"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultTransformer = void 0;
exports.getFieldDecoder = getFieldDecoder;
exports.getFieldElements = getFieldElements;
const utils_1 = require("@postxl/utils");
function getFieldDecoder(params) {
    const { rawDecoder, modifiers, transformer } = getFieldElements(params);
    let fieldDecoder = `${params.field.name}: ${rawDecoder}`;
    if (modifiers && modifiers.size > 0) {
        fieldDecoder += `.${[...modifiers.values()].join('.')}`;
    }
    if (transformer) {
        fieldDecoder += `.transform((v) => ${transformer('v')})`;
    }
    return fieldDecoder;
}
const defaultTransformer = (name) => `${name}`;
exports.defaultTransformer = defaultTransformer;
function getFieldElements(params) {
    switch (params.field.kind) {
        case 'id':
            return getFieldElementsForId(params);
        case 'scalar':
            return getFieldElementsForScalar(params);
        case 'relation':
            return getFieldElementsForRelation(params);
        case 'enum':
            return getFieldElementsForEnum(params);
        case 'discriminatedUnion':
            return getFieldElementsForDiscriminatedUnion(params);
        default:
            throw new utils_1.ExhaustiveSwitchCheck(params.field);
    }
}
function getFieldElementsForId({ model, imports }) {
    imports.add(model.types.id.toBranded);
    return {
        rawDecoder: `z.string()`,
        modifiers: new Set(),
        transformer: (name) => `${model.types.id.toBranded.name}(${name})`,
    };
}
function getFieldElementsForScalar(params) {
    const elements = getFieldElementsForScalar_Base(params);
    if (!params.field.isRequired) {
        elements.modifiers.add('nullable()');
    }
    return elements;
}
function getFieldElementsForScalar_Base(params) {
    switch (params.field.type) {
        case 'number':
            return getFieldElementsForScalarNumber(params);
        case 'string':
            return getFieldElementsForScalarString(params);
        case 'boolean':
            return { rawDecoder: `z.boolean()`, modifiers: new Set() };
        case 'Date':
            return { rawDecoder: `z.date()`, modifiers: new Set() };
        default:
            throw new utils_1.ExhaustiveSwitchCheck(params.field);
    }
}
function getFieldElementsForScalarNumber({ field }) {
    const modifiers = new Set();
    if (field.validations.type === 'int' || field.databaseType === 'Int' || field.databaseType === 'BigInt') {
        modifiers.add('int()');
    }
    if (field.validations.min !== undefined) {
        modifiers.add(`min(${field.validations.min})`);
    }
    if (field.validations.max !== undefined) {
        modifiers.add(`max(${field.validations.max})`);
    }
    return { rawDecoder: `z.number()`, modifiers };
}
function getFieldElementsForScalarString({ field }) {
    const modifiers = new Set();
    if (field.validations.maxLength) {
        modifiers.add(`max(${field.validations.maxLength})`);
    }
    return { rawDecoder: `z.string()`, modifiers };
}
function getFieldElementsForRelation({ field, context, imports, }) {
    const modifiers = new Set(field.isRequired ? [] : ['nullable()']);
    const referencedModel = context.models.get(field.referencedModelName);
    imports.add(referencedModel.types.id.toBranded);
    const transformer = field.isRequired
        ? (name) => `${referencedModel.types.id.toBranded.name}(${name})`
        : (name) => `${name} === null ? null : ${referencedModel.types.id.toBranded.name}(${name})`;
    return { rawDecoder: `z.string()`, modifiers, transformer };
}
function getFieldElementsForEnum({ field, context, imports }) {
    const modifiers = new Set(field.isRequired ? [] : ['nullable()']);
    const enum_ = context.enums.get(field.enumName);
    imports.add(enum_.decoder.decoder.rawInputValidation).add(enum_.decoder.decoder.transformer);
    const transformer = field.isRequired
        ? (name) => `${enum_.decoder.decoder.transformer.name}(${name})`
        : (name) => `${name} === null ? null : ${enum_.decoder.decoder.transformer.name}(${name})`;
    return {
        rawDecoder: `${enum_.decoder.decoder.rawInputValidation.name}`,
        modifiers,
        transformer,
    };
}
function getFieldElementsForDiscriminatedUnion({ field, model, imports, }) {
    const modifiers = new Set(field.isRequired ? [] : ['nullable()']);
    const du = model.decoder.discriminatedUnions.get(field.name);
    imports.add(du.decoder.zodDecoder);
    return { rawDecoder: `${du.decoder.zodDecoder.name}`, modifiers };
}
//# sourceMappingURL=field-decoder.helper.js.map