import { useI18n } from 'vue-i18n';
import validator from 'validator';
import { useValidationsStore } from 'src/stores/useValidationsStore';

export function useValidator() {
    const models = useValidationsStore().validations;

    function validate(propertyRule) {
        const modelInfo = models;
        if (!modelInfo || !propertyRule) return;

        const rule = propertyRule.split('.');
        const model = rule[0];
        const property = rule[1];
        const modelName = model.charAt(0).toUpperCase() + model.slice(1);

        if (!modelInfo[modelName]) return;

        const modelValidations = modelInfo[modelName].validations;

        if (!modelValidations[property]) return;

        const rules = modelValidations[property].map((validation) => {
            return validations(validation)[validation.validation];
        });

        return rules;
    }

    const { t } = useI18n();
    const validations = function (validation = {}) {
        return {
            format: (value) => {
                const { allowNull, with: format, allowBlank } = validation;
                const message = t(validation.message) || validation.message;
                if (!allowBlank && value === '') return message;
                if (!allowNull && value === null) return message;

                const isValid = new RegExp(format).test(value);
                if (!isValid) return message;
            },
            presence: (value) => {
                let message = t(`globals.valueCantBeEmpty`);
                if (validation.message)
                    message = t(validation.message) || validation.message;

                return !validator.isEmpty(value ? String(value) : '') || message;
            },
            required: (required, value) => {
                return required ? !!value || t('globals.fieldRequired') : null;
            },
            length: (value) => {
                const options = {
                    min: validation.min || validation.is,
                    max: validation.max || validation.is,
                };

                value = String(value);

                if (!value) value = '';

                let message = `Value should have at most ${options.max} characters`;
                if (validation.is)
                    message = `Value should be ${validation.is} characters long`;
                if (validation.min)
                    message = `Value should have at least ${validation.min} characters`;
                if (validation.min && validation.max)
                    message = `Value should have a length between ${validation.min} and ${validation.max}`;

                return validator.isLength(value, options) || message;
            },
            numericality: (value) => {
                if (validation.int)
                    return validator.isInt(value) || 'Value should be integer';
                return validator.isNumeric(value) || 'Value should be a number';
            },
            min: (value, min) => {
                if (min >= 0)
                    if (Math.floor(value) < min) return t('inputMin', { value: min });
            },
            custom: (value) => validation.bindedFunction(value) || 'Invalid value',
        };
    };

    return {
        validate,
        validations,
        models,
    };
}
