"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelectionDynamicFieldCrudManager = void 0;
const class_validator_1 = require("class-validator");
const create_field_metadata_dto_1 = require("../../dtos/create-field-metadata.dto");
class SelectionDynamicFieldCrudManager {
    constructor(options) {
        this.options = options;
    }
    async validate(dto) {
        const fieldValue = dto[this.options.fieldName];
        const isMultiSelect = this.options?.isMultiSelect;
        if (isMultiSelect && fieldValue) {
            const arrayCheck = this.parseAndValidateArray(fieldValue);
            if (!arrayCheck.isValid) {
                return [
                    {
                        field: this.options.fieldName,
                        error: `Field: ${this.options.fieldName} must be a valid array`,
                    },
                ];
            }
            const values = arrayCheck.values;
            if (this.isApplyRequiredValidation() && values.length === 0) {
                return [
                    {
                        field: this.options.fieldName,
                        error: `Field: ${this.options.fieldName} is required`,
                    },
                ];
            }
            const allErrors = await Promise.all(values.map((val) => this.applyValidations(val)));
            return allErrors.flat();
        }
        else {
            return this.applyValidations(fieldValue);
        }
    }
    parseAndValidateArray(fieldValue) {
        if (Array.isArray(fieldValue)) {
            return { isValid: true, values: fieldValue };
        }
        try {
            const parsed = typeof fieldValue === 'string' ? JSON.parse(fieldValue) : null;
            if (Array.isArray(parsed)) {
                return { isValid: true, values: parsed };
            }
        }
        catch {
        }
        return { isValid: false, values: [] };
    }
    async applyValidations(fieldValue) {
        const errors = [];
        this.isApplyRequiredValidation() && (0, class_validator_1.isEmpty)(fieldValue) ? errors.push({ field: this.options.fieldName, error: `Field: ${this.options.fieldName} is required` }) : "no errors";
        if ((0, class_validator_1.isNotEmpty)(fieldValue)) {
            const formatErrors = await this.applyFormatValidations(fieldValue);
            errors.push(...formatErrors);
        }
        return errors;
    }
    async applyFormatValidations(fieldValue) {
        const errors = [];
        !this.isValidSelectionValueType(fieldValue, this.options.selectionValueType) ? errors.push({ field: this.options.fieldName, error: 'Field value type is invalid' }) : "no errors";
        const ctxt = this.options.selectionDynamicProviderCtxt;
        if (ctxt.validateOnSave !== false) {
            const _isValidSelectionValue = await this.isValidSelectionValue(fieldValue, this.options.selectionDynamicProvider, ctxt);
            !_isValidSelectionValue ? errors.push({ field: this.options.fieldName, error: 'Field value is invalid' }) : "no errors";
        }
        return errors;
    }
    transformForCreate(dto) {
        return dto;
    }
    isValidSelectionValueType(fieldValue, selectionValueType) {
        switch (selectionValueType) {
            case create_field_metadata_dto_1.SelectionValueType.string:
                return (0, class_validator_1.isString)(fieldValue);
            case create_field_metadata_dto_1.SelectionValueType.int:
                return (0, class_validator_1.isInt)(fieldValue);
            default:
                throw new Error(`Validation for selection value type ${selectionValueType} is not implemented`);
        }
    }
    async isValidSelectionValue(fieldValue, selectionDynamicProvider, ctxt) {
        const providerInstance = this.providerInstance(selectionDynamicProvider);
        try {
            const valueOption = await providerInstance.value(fieldValue, ctxt);
            if (valueOption && valueOption.value === fieldValue) {
                return true;
            }
            return false;
        }
        catch (error) {
            const values = await providerInstance.values('', ctxt);
            const isValid = values.some(v => v.value === fieldValue);
            return isValid;
        }
    }
    providerInstance(selectionDynamicProvider) {
        const providers = this.options.discoveryService.getProviders();
        const byToken = providers.find((p) => p.name === selectionDynamicProvider);
        if (byToken) {
            return byToken.instance;
        }
        const byName = providers.find((p) => {
            try {
                return typeof p.instance?.name === 'function' && p.instance.name() === selectionDynamicProvider;
            }
            catch {
                return false;
            }
        });
        if (!byName) {
            throw new Error(`Provider for ${selectionDynamicProvider} not found`);
        }
        return byName.instance;
    }
    isApplyRequiredValidation() {
        return this.options.required;
    }
}
exports.SelectionDynamicFieldCrudManager = SelectionDynamicFieldCrudManager;
//# sourceMappingURL=SelectionDynamicFieldCrudManager.js.map