import FormFieldSchemaType from "./Types/FormFieldSchemaType";
import Hostname from "../../../Types/API/Hostname";
import Route from "../../../Types/API/Route";
import URL from "../../../Types/API/URL";
import Color from "../../../Types/Color";
import OneUptimeDate from "../../../Types/Date";
import Domain from "../../../Types/Domain";
import Email from "../../../Types/Email";
import BadDataException from "../../../Types/Exception/BadDataException";
import Exception from "../../../Types/Exception/Exception";
import Phone from "../../../Types/Phone";
import { Logger } from "../../Utils/Logger";
import Port from "../../../Types/Port";
import Typeof from "../../../Types/Typeof";
export default class Validation {
    static validateLength(content, field) {
        var _a, _b;
        if (content && field.validation) {
            if (field.validation.minLength) {
                if (content.trim().length < ((_a = field.validation) === null || _a === void 0 ? void 0 : _a.minLength)) {
                    return `${field.title || name} cannot be less than ${field.validation.minLength} characters.`;
                }
            }
            if (field.validation.maxLength) {
                if (content.trim().length > ((_b = field.validation) === null || _b === void 0 ? void 0 : _b.maxLength)) {
                    return `${field.title || name} cannot be more than ${field.validation.maxLength} characters.`;
                }
            }
            if (field.validation.noSpaces) {
                if (content.trim().includes(" ")) {
                    return `${field.title || name} should not have spaces.`;
                }
            }
            if (field.validation.noSpecialCharacters) {
                if (!content.match(/^[A-Za-z0-9_-]*$/)) {
                    return `${field.title || name} can only contain letters, numbers, hyphens (-), and underscores (_).`;
                }
            }
            if (field.validation.noNumbers) {
                if (!content.match(/^[A-Za-z]*$/)) {
                    return `${field.title || name} should not have numbers.`;
                }
            }
        }
        return null;
    }
    static validateDate(content, field) {
        if (content && field.validation) {
            if (field.validation.dateShouldBeInTheFuture) {
                if (OneUptimeDate.isInThePast(content.trim())) {
                    return `${field.title || name} should be a future date.`;
                }
            }
        }
        return null;
    }
    static validateMaxValueAndMinValue(content, field) {
        var _a, _b, _c, _d;
        if (content && field.validation) {
            if (typeof content === "string") {
                try {
                    content = parseInt(content);
                }
                catch (e) {
                    Logger.error(e);
                    return `${field.title || name} should be a number.`;
                }
            }
            if (field.validation.maxValue) {
                if (content > ((_a = field.validation) === null || _a === void 0 ? void 0 : _a.maxValue)) {
                    return `${field.title || name} should not be more than ${(_b = field.validation) === null || _b === void 0 ? void 0 : _b.maxValue}.`;
                }
            }
            if (field.validation.minValue) {
                if (content < ((_c = field.validation) === null || _c === void 0 ? void 0 : _c.minValue)) {
                    return `${field.title || name} should not be less than ${(_d = field.validation) === null || _d === void 0 ? void 0 : _d.minValue}.`;
                }
            }
        }
        return null;
    }
    static validateRequired(currentValues, content, field) {
        let required = false;
        if (field.required && typeof field.required === Typeof.Boolean) {
            required = true;
        }
        else if (field.required &&
            typeof field.required === "function" &&
            field.required(currentValues)) {
            required = true;
        }
        if (required && (!content || content.length === 0)) {
            return `${field.title} is required.`;
        }
        return null;
    }
    static validateMatchField(content, field, entity) {
        var _a, _b, _c, _d;
        if (content &&
            ((_a = field.validation) === null || _a === void 0 ? void 0 : _a.toMatchField) &&
            entity[(_b = field.validation) === null || _b === void 0 ? void 0 : _b.toMatchField] &&
            entity[(_c = field.validation) === null || _c === void 0 ? void 0 : _c.toMatchField].toString().trim() !==
                content.trim()) {
            return `${field.title} should match ${(_d = field.validation) === null || _d === void 0 ? void 0 : _d.toMatchField}`;
        }
        return null;
    }
    static validateData(content, field) {
        if (content && field.fieldType === FormFieldSchemaType.Email) {
            if (!Email.isValid(content)) {
                return "Email is not valid.";
            }
        }
        if (content && field.fieldType === FormFieldSchemaType.Port) {
            try {
                new Port(content);
            }
            catch (e) {
                if (e instanceof Exception) {
                    return e.getMessage();
                }
            }
        }
        if (content && field.fieldType === FormFieldSchemaType.URL) {
            try {
                URL.fromString(content);
            }
            catch (e) {
                if (e instanceof Exception) {
                    return e.getMessage();
                }
            }
        }
        if (content && field.fieldType === FormFieldSchemaType.Hostname) {
            try {
                new Hostname(content.toString());
            }
            catch (e) {
                if (e instanceof Exception) {
                    return e.getMessage();
                }
            }
        }
        if (content && field.fieldType === FormFieldSchemaType.Route) {
            try {
                new Route(content.toString());
            }
            catch (e) {
                if (e instanceof Exception) {
                    return e.getMessage();
                }
            }
        }
        if (content && field.fieldType === FormFieldSchemaType.Phone) {
            try {
                new Phone(content.toString());
            }
            catch (e) {
                if (e instanceof Exception) {
                    return e.getMessage();
                }
            }
        }
        if (content && field.fieldType === FormFieldSchemaType.Color) {
            try {
                new Color(content.toString());
            }
            catch (e) {
                if (e instanceof Exception) {
                    return e.getMessage();
                }
            }
        }
        if (content && field.fieldType === FormFieldSchemaType.Domain) {
            try {
                new Domain(content.toString());
            }
            catch (e) {
                if (e instanceof Exception) {
                    return e.getMessage();
                }
            }
        }
        return null;
    }
    static validate(args) {
        var _a;
        const errors = {};
        const entries = Object.assign({}, args.values);
        for (const field of args.formFields) {
            if (args.currentFormStepId && field.stepId !== args.currentFormStepId) {
                continue;
            }
            if (!field.name) {
                throw new BadDataException("Field name is required.");
            }
            const name = field.name;
            // is this field visible? If not visible, skip validation.
            if (field.showIf) {
                const isVisible = field === null || field === void 0 ? void 0 : field.showIf(args.values);
                if (!isVisible) {
                    continue;
                }
            }
            if (name in entries) {
                const content = (_a = entries[name]) === null || _a === void 0 ? void 0 : _a.toString();
                // Check Required fields.
                const resultRequired = this.validateRequired(args.values, content, field);
                if (resultRequired) {
                    errors[name] = resultRequired;
                }
                // Check for valid email data.
                const resultValidateData = this.validateData(content, field);
                if (resultValidateData) {
                    errors[name] = resultValidateData;
                }
                const resultMatch = this.validateMatchField(content, field, entries);
                if (resultMatch) {
                    errors[name] = resultMatch;
                }
                // check for length of content
                const result = this.validateLength(content, field);
                if (result) {
                    errors[name] = result;
                }
                // check for date
                const resultDate = this.validateDate(content, field);
                if (resultDate) {
                    errors[name] = resultDate;
                }
                // check for length of content
                const resultMaxMinValue = this.validateMaxValueAndMinValue(content, field);
                if (resultMaxMinValue) {
                    errors[name] = resultMaxMinValue;
                }
                if (field.customValidation) {
                    // check for length of content
                    const resultCustomValidation = field.customValidation(Object.assign({}, args.values));
                    if (resultCustomValidation) {
                        errors[name] = resultCustomValidation;
                    }
                }
            }
            else if (field.required) {
                errors[name] = `${field.title || name} is required.`;
            }
        }
        let customValidateResult = {};
        if (args.onValidate) {
            customValidateResult = args.onValidate(args.values);
        }
        const totalValidationErrors = Object.assign(Object.assign({}, errors), customValidateResult);
        return totalValidationErrors;
    }
}
//# sourceMappingURL=Validation.js.map