/**
 * FORM VALIDATORS - Sistema de Validación de Formularios
 * 
 * Este archivo contiene todas las funciones de validación para formularios
 * del sistema GGEE, incluyendo validación de RUT chileno, email y teléfono.
 * 
 * CARACTERÍSTICAS:
 * - Validación en tiempo real
 * - Feedback visual (verde/rojo)
 * - Formateo automático
 * - Mensajes de error en español
 * 
 * EXPLICACIÓN PARA JUNIOR:
 * Las validaciones aseguran que los datos ingresados sean correctos
 * antes de enviarlos al servidor. Esto mejora la experiencia del usuario
 * y reduce errores en la base de datos.
 */

// ============================================
// VALIDACIÓN DE RUT CHILENO
// ============================================

/**
 * Valida un RUT chileno completo (formato y dígito verificador)
 * 
 * @param {string} rut - RUT a validar (puede incluir puntos y guión)
 * @returns {Object} - { valid: boolean, message: string, formatted: string }
 * 
 * EXPLICACIÓN:
 * El RUT chileno tiene un dígito verificador calculado con el algoritmo módulo 11.
 * Este dígito ayuda a detectar errores de digitación.
 */
function validateRUT(rut) {
    // 1. Limpiar RUT (quitar puntos, guiones, espacios)
    const cleanRut = cleanRUTString(rut);

    // 2. Validar que no esté vacío
    if (!cleanRut) {
        return { valid: false, message: 'RUT es requerido', formatted: '' };
    }

    // 3. Validar longitud (mínimo 8, máximo 9 caracteres)
    if (cleanRut.length < 8 || cleanRut.length > 9) {
        return { valid: false, message: 'RUT debe tener entre 8 y 9 dígitos', formatted: '' };
    }

    // 4. Separar número y dígito verificador
    const rutNumber = cleanRut.slice(0, -1);
    const verifier = cleanRut.slice(-1).toUpperCase();

    // 5. Calcular dígito verificador esperado
    const expectedVerifier = calculateRUTVerifier(rutNumber);

    // 6. Comparar
    if (verifier !== expectedVerifier) {
        return {
            valid: false,
            message: 'RUT inválido (dígito verificador incorrecto)',
            formatted: ''
        };
    }

    // 7. RUT válido - retornar formateado
    return {
        valid: true,
        message: 'RUT válido',
        formatted: formatRUT(cleanRut)
    };
}

/**
 * Calcula el dígito verificador de un RUT usando el algoritmo módulo 11
 * 
 * @param {string} rutNumber - Número del RUT sin el dígito verificador
 * @returns {string} - Dígito verificador calculado ('0'-'9' o 'K')
 * 
 * EXPLICACIÓN DEL ALGORITMO:
 * 1. Se multiplica cada dígito por un factor (2,3,4,5,6,7,2,3,4...)
 * 2. Se suman todos los productos
 * 3. Se calcula el módulo 11 de la suma
 * 4. El verificador es 11 - módulo
 * 5. Si es 11 → '0', si es 10 → 'K', sino → el número
 */
function calculateRUTVerifier(rutNumber) {
    let sum = 0;
    let multiplier = 2;

    // Recorrer el RUT de derecha a izquierda
    for (let i = rutNumber.length - 1; i >= 0; i--) {
        sum += parseInt(rutNumber[i]) * multiplier;
        multiplier = multiplier === 7 ? 2 : multiplier + 1;
    }

    const remainder = sum % 11;
    const verifier = 11 - remainder;

    if (verifier === 11) return '0';
    if (verifier === 10) return 'K';
    return verifier.toString();
}

/**
 * Formatea un RUT al formato estándar chileno: XX.XXX.XXX-X
 * 
 * @param {string} rut - RUT limpio (solo números y K)
 * @returns {string} - RUT formateado
 */
function formatRUT(rut) {
    const clean = cleanRUTString(rut);
    if (!clean) return '';

    const number = clean.slice(0, -1);
    const verifier = clean.slice(-1);

    // Agregar puntos cada 3 dígitos de derecha a izquierda
    const formatted = number.replace(/\B(?=(\d{3})+(?!\d))/g, '.');

    return `${formatted}-${verifier}`;
}

/**
 * Limpia un RUT dejando solo números y K
 * 
 * @param {string} rut - RUT a limpiar
 * @returns {string} - RUT limpio
 */
function cleanRUTString(rut) {
    if (!rut) return '';
    return rut.toString().replace(/[^0-9kK]/g, '').toUpperCase();
}

// ============================================
// VALIDACIÓN DE EMAIL
// ============================================

/**
 * Valida un email según el estándar RFC 5322 (simplificado)
 * 
 * @param {string} email - Email a validar
 * @returns {Object} - { valid: boolean, message: string, normalized: string }
 */
function validateEmail(email) {
    // Regex RFC 5322 simplificado pero robusto
    const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;

    const trimmed = email ? email.trim() : '';

    // Validar que no esté vacío
    if (!trimmed) {
        return { valid: false, message: 'Email es requerido', normalized: '' };
    }

    // Validar formato
    if (!emailRegex.test(trimmed)) {
        return { valid: false, message: 'Formato de email inválido', normalized: '' };
    }

    // Validar longitud máxima (estándar RFC 5321)
    if (trimmed.length > 254) {
        return { valid: false, message: 'Email demasiado largo (máximo 254 caracteres)', normalized: '' };
    }

    // Email válido - normalizar a minúsculas
    return {
        valid: true,
        message: 'Email válido',
        normalized: trimmed.toLowerCase()
    };
}

/**
 * Normaliza un email (trim + lowercase)
 * 
 * @param {string} email - Email a normalizar
 * @returns {string} - Email normalizado
 */
function normalizeEmail(email) {
    if (!email) return '';
    return email.trim().toLowerCase();
}

// ============================================
// VALIDACIÓN DE TELÉFONO CHILENO
// ============================================

/**
 * Valida un teléfono chileno (móvil o fijo)
 * 
 * Formatos válidos:
 * - Móvil: 9 XXXX XXXX (9 dígitos empezando con 9)
 * - Fijo: 2 XXXX XXXX (9 dígitos empezando con 2)
 * 
 * @param {string} phone - Teléfono a validar
 * @returns {Object} - { valid: boolean, message: string, formatted: string, type: string }
 */
function validatePhone(phone) {
    // Limpiar teléfono (solo números)
    const cleanPhone = cleanPhoneString(phone);

    // Validar que no esté vacío
    if (!cleanPhone) {
        return { valid: false, message: 'Teléfono es requerido', formatted: '', type: '' };
    }

    // Validar longitud (debe ser 9 dígitos)
    if (cleanPhone.length !== 9) {
        return {
            valid: false,
            message: 'Teléfono debe tener 9 dígitos',
            formatted: '',
            type: ''
        };
    }

    // Validar primer dígito (9 para móvil, 2 para fijo)
    const firstDigit = cleanPhone[0];
    if (firstDigit !== '9' && firstDigit !== '2') {
        return {
            valid: false,
            message: 'Teléfono debe comenzar con 9 (móvil) o 2 (fijo)',
            formatted: '',
            type: ''
        };
    }

    // Teléfono válido
    const type = firstDigit === '9' ? 'móvil' : 'fijo';
    return {
        valid: true,
        message: `Teléfono ${type} válido`,
        formatted: formatPhone(cleanPhone),
        type: type
    };
}

/**
 * Formatea un teléfono chileno al formato: +56 9 XXXX XXXX
 * 
 * @param {string} phone - Teléfono limpio (9 dígitos)
 * @returns {string} - Teléfono formateado
 */
function formatPhone(phone) {
    const clean = cleanPhoneString(phone);
    if (clean.length !== 9) return phone;

    // Formato: +56 9 XXXX XXXX
    return `+56 ${clean[0]} ${clean.slice(1, 5)} ${clean.slice(5)}`;
}

/**
 * Limpia un teléfono dejando solo números
 * 
 * @param {string} phone - Teléfono a limpiar
 * @returns {string} - Teléfono limpio
 */
function cleanPhoneString(phone) {
    if (!phone) return '';
    // Quitar +56 si existe, luego quitar todo excepto números
    return phone.toString().replace(/^\+?56\s*/, '').replace(/[^0-9]/g, '');
}

// ============================================
// FEEDBACK VISUAL EN CAMPOS
// ============================================

/**
 * Muestra un error en un campo del formulario
 * 
 * @param {HTMLElement} field - Campo del formulario
 * @param {string} message - Mensaje de error
 * 
 * EXPLICACIÓN:
 * Agrega clases CSS para mostrar el campo en rojo y muestra
 * el mensaje de error debajo del campo.
 */
function showFieldError(field, message) {
    if (!field) return;

    // Quitar clases de éxito
    field.classList.remove('is-valid', 'field-valid');

    // Agregar clases de error
    field.classList.add('is-invalid', 'field-invalid');

    // Buscar o crear elemento de feedback
    let feedbackEl = field.parentElement.querySelector('.field-feedback');
    if (!feedbackEl) {
        feedbackEl = document.createElement('div');
        feedbackEl.className = 'field-feedback invalid-feedback';
        field.parentElement.appendChild(feedbackEl);
    }

    feedbackEl.textContent = message;
    feedbackEl.classList.remove('valid-feedback');
    feedbackEl.classList.add('invalid-feedback');
    feedbackEl.style.display = 'block';
}

/**
 * Muestra éxito en un campo del formulario
 * 
 * @param {HTMLElement} field - Campo del formulario
 * @param {string} message - Mensaje de éxito (opcional)
 */
function showFieldSuccess(field, message = '') {
    if (!field) return;

    // Quitar clases de error
    field.classList.remove('is-invalid', 'field-invalid');

    // Agregar clases de éxito
    field.classList.add('is-valid', 'field-valid');

    // Buscar o crear elemento de feedback
    let feedbackEl = field.parentElement.querySelector('.field-feedback');
    if (!feedbackEl) {
        feedbackEl = document.createElement('div');
        feedbackEl.className = 'field-feedback valid-feedback';
        field.parentElement.appendChild(feedbackEl);
    }

    if (message) {
        feedbackEl.textContent = message;
        feedbackEl.classList.remove('invalid-feedback');
        feedbackEl.classList.add('valid-feedback');
        feedbackEl.style.display = 'block';
    } else {
        feedbackEl.style.display = 'none';
    }
}

/**
 * Limpia el feedback de un campo
 * 
 * @param {HTMLElement} field - Campo del formulario
 */
function clearFieldFeedback(field) {
    if (!field) return;

    field.classList.remove('is-valid', 'is-invalid', 'field-valid', 'field-invalid');

    const feedbackEl = field.parentElement.querySelector('.field-feedback');
    if (feedbackEl) {
        feedbackEl.style.display = 'none';
        feedbackEl.textContent = '';
    }
}

// ============================================
// AUTO-VALIDACIÓN EN CAMPOS
// ============================================

/**
 * Configura validación automática en un campo RUT
 * 
 * @param {string|HTMLElement} fieldId - ID del campo o elemento del campo
 * @param {boolean} autoFormat - Si debe formatear automáticamente
 */
function setupRUTValidation(fieldId, autoFormat = true) {
    const field = typeof fieldId === 'string' ? document.getElementById(fieldId) : fieldId;
    if (!field) return;

    field.addEventListener('input', function (e) {
        const result = validateRUT(e.target.value);

        if (result.valid) {
            showFieldSuccess(e.target);
            if (autoFormat) {
                e.target.value = result.formatted;
            }
        } else if (e.target.value.trim()) {
            showFieldError(e.target, result.message);
        } else {
            clearFieldFeedback(e.target);
        }
    });
}

/**
 * Configura validación automática en un campo email
 * 
 * @param {string|HTMLElement} fieldId - ID del campo o elemento del campo
 */
function setupEmailValidation(fieldId) {
    const field = typeof fieldId === 'string' ? document.getElementById(fieldId) : fieldId;
    if (!field) return;

    field.addEventListener('blur', function (e) {
        const result = validateEmail(e.target.value);

        if (result.valid) {
            showFieldSuccess(e.target);
            e.target.value = result.normalized;
        } else if (e.target.value.trim()) {
            showFieldError(e.target, result.message);
        } else {
            clearFieldFeedback(e.target);
        }
    });
}

/**
 * Configura validación automática en un campo teléfono
 * 
 * @param {string|HTMLElement} fieldId - ID del campo o elemento del campo
 * @param {boolean} autoFormat - Si debe formatear automáticamente
 */
function setupPhoneValidation(fieldId, autoFormat = true) {
    const field = typeof fieldId === 'string' ? document.getElementById(fieldId) : fieldId;
    if (!field) return;

    field.addEventListener('input', function (e) {
        const result = validatePhone(e.target.value);

        if (result.valid) {
            showFieldSuccess(e.target, result.message);
            if (autoFormat) {
                e.target.value = result.formatted;
            }
        } else if (e.target.value.trim()) {
            showFieldError(e.target, result.message);
        } else {
            clearFieldFeedback(e.target);
        }
    });
}

// ============================================
// INICIALIZACIÓN AUTOMÁTICA
// ============================================

/**
 * Inicializa validaciones automáticas en campos con atributos data-validate
 * 
 * USO:
 * <input type="text" data-validate="rut" id="rut">
 * <input type="email" data-validate="email" id="email">
 * <input type="tel" data-validate="phone" id="telefono">
 */
document.addEventListener('DOMContentLoaded', function () {
    // Buscar todos los campos con data-validate
    const fieldsToValidate = document.querySelectorAll('[data-validate]');

    fieldsToValidate.forEach(field => {
        const validateType = field.getAttribute('data-validate');

        switch (validateType) {
            case 'rut':
                setupRUTValidation(field);
                break;
            case 'email':
                setupEmailValidation(field);
                break;
            case 'phone':
            case 'telefono':
                setupPhoneValidation(field);
                break;
        }
    });
});
