<template>
    <div v-if="validator?.$error" class="text-danger fs-10">
        <template v-for="(rule, name) in validator" :key="name">
            <small class="bold" v-if="typeof rule === 'object' && rule.$invalid">
                <span class="btn-block">{{ getErrorMessage({ ...rule, $validator: name as unknown as string }) }}</span>
            </small>
        </template>
    </div>
</template>

<script setup lang="ts">
interface Props {
    validator: any;
}

const props = defineProps<Props>();

interface ValidationErrorItem {
    $validator: string;
    $invalid: boolean;
    $params?: Record<string, any>;
}

const errorMessages: Record<string, string> = {
    required: 'this field is required',
    email: 'enter a valid email address',
    maxLength: 'this field must have at most characters',
    minLength: 'this field must have at least characters',
    sameAs: 'this field must match',
    maxValue: 'this value must not exceed',
    alphaNum: 'this value must be alphanumeric',
    fiveDigits: 'this value must be exactly 5 digits',
    allowZeroOrFiveDigits: 'this value must be exactly 5 digits or 0',
    numeric: 'this field must be numeric'
};

const getErrorMessage = (error: ValidationErrorItem): string => {
    if (!error) return 'invalid value';

    const validatorName = error.$validator;
    const params = error.$params || {};

    if (validatorName === 'minLength') return `${errorMessages.minLength} ${params.min} characters`;
    if (validatorName === 'maxLength') return `${errorMessages.maxLength} ${params.max} characters`;
    if (validatorName === 'sameAs' || validatorName === 'sameAsPassword') {
        let fieldName = params.otherName || params.eq || 'password';
        if (fieldName === 'password') fieldName = 'password';
        return `${errorMessages.sameAs} ${fieldName} field`;
    }
    if (validatorName === 'minValue') return `${errorMessages.minValue} ${params.min}`;
    if (validatorName === 'maxValue') return `${errorMessages.maxValue} ${params.max}`;

    return errorMessages[validatorName] || 'invalid value';
};
</script>

