/**
 * Fichier  : assets/js/validator.js
 * Auteur   : KREMER Régis
 * Version  : 2.2.0
 * Date     : 2026-02-21
 * Description : JS — Module de validation de formulaires côté client
 *
 * Changelog :
 *   v2.1.0 (2026-02-21) — Version initiale auditée et sécurisée
 *   v2.1.1 (2026-02-21) — Corrections sécurité, utils.js centralisé
 *   v2.2.0 (2026-02-21) — Permissions magasins, bons de commande, rapport d'écart,
 *                      import CSV, historique prix, bon de livraison multi-lignes
 */
// ================================================================
// validator.js — MageStock V2.1
// Client-side form validation
// ================================================================

const Validator = {
    
    /**
     * Check if value is not empty
     */
    required(val, fieldName) {
        const v = String(val || '').trim();
        if (!v) {
            throw new Error(`${fieldName} est requis`);
        }
        return true;
    },
    
    /**
     * Check minimum value
     */
    min(val, min, fieldName) {
        const v = parseFloat(val);
        if (isNaN(v) || v < min) {
            throw new Error(`${fieldName} doit être ≥ ${min}`);
        }
        return true;
    },
    
    /**
     * Check maximum value
     */
    max(val, max, fieldName) {
        const v = parseFloat(val);
        if (isNaN(v) || v > max) {
            throw new Error(`${fieldName} doit être ≤ ${max}`);
        }
        return true;
    },
    
    /**
     * Check email format
     */
    email(val, fieldName) {
        const v = String(val || '').trim();
        if (!v) return true; // Skip if empty (use required separately)
        const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!re.test(v)) {
            throw new Error(`${fieldName} invalide`);
        }
        return true;
    },
    
    /**
     * Check min length
     */
    minLength(val, min, fieldName) {
        const v = String(val || '').trim();
        if (v.length < min) {
            throw new Error(`${fieldName} doit contenir au moins ${min} caractères`);
        }
        return true;
    },
    
    /**
     * Check max length
     */
    maxLength(val, max, fieldName) {
        const v = String(val || '');
        if (v.length > max) {
            throw new Error(`${fieldName} doit contenir maximum ${max} caractères`);
        }
        return true;
    },
    
    /**
     * Check if value matches pattern
     */
    pattern(val, regex, fieldName, message) {
        const v = String(val || '').trim();
        if (v && !regex.test(v)) {
            throw new Error(message || `${fieldName} format invalide`);
        }
        return true;
    },
    
    /**
     * Check hex color
     */
    hexColor(val, fieldName) {
        const v = String(val || '').trim();
        if (v && !/^#[0-9A-Fa-f]{6}$/.test(v)) {
            throw new Error(`${fieldName} doit être une couleur hexadécimale (#RRGGBB)`);
        }
        return true;
    },
    
    /**
     * Validate entire form
     * @param {string} formId - Form ID or selector
     * @param {object} rules - Validation rules { fieldName: [validator1, validator2, ...] }
     * @returns {boolean} True if valid
     * 
     * Example:
     * Validator.validateForm('myForm', {
     *   name: [(v) => Validator.required(v, 'Nom')],
     *   email: [
     *     (v) => Validator.required(v, 'Email'),
     *     (v) => Validator.email(v, 'Email')
     *   ],
     *   age: [(v) => Validator.min(v, 18, 'Âge')]
     * })
     */
    validateForm(formId, rules) {
        const form = document.getElementById(formId) || document.querySelector(formId);
        if (!form) {
            console.error(`Form not found: ${formId}`);
            return false;
        }
        
        try {
            for (const [fieldName, validators] of Object.entries(rules)) {
                const input = form.querySelector(`[name="${fieldName}"]`);
                if (!input) {
                    console.warn(`Field not found: ${fieldName}`);
                    continue;
                }
                
                const val = input.type === 'checkbox' ? input.checked : input.value;
                
                for (const validator of validators) {
                    validator(val, fieldName);
                }
            }
            return true;
        } catch (err) {
            toast(err.message, 'error');
            return false;
        }
    },
    
    /**
     * Validate single field
     */
    validateField(fieldElement, validators) {
        try {
            const val = fieldElement.type === 'checkbox' ? fieldElement.checked : fieldElement.value;
            const fieldName = fieldElement.getAttribute('data-label') || fieldElement.name || 'Champ';
            
            for (const validator of validators) {
                validator(val, fieldName);
            }
            
            // Remove error state
            fieldElement.classList.remove('inp-error');
            const errorSpan = fieldElement.nextElementSibling;
            if (errorSpan && errorSpan.classList.contains('field-error')) {
                errorSpan.remove();
            }
            
            return true;
        } catch (err) {
            // Add error state
            fieldElement.classList.add('inp-error');
            
            // Show error message
            let errorSpan = fieldElement.nextElementSibling;
            if (!errorSpan || !errorSpan.classList.contains('field-error')) {
                errorSpan = document.createElement('span');
                errorSpan.className = 'field-error';
                fieldElement.parentNode.insertBefore(errorSpan, fieldElement.nextSibling);
            }
            errorSpan.textContent = err.message;
            
            return false;
        }
    },
    
    /**
     * Setup real-time validation on form
     */
    setupRealtimeValidation(formId, rules) {
        const form = document.getElementById(formId) || document.querySelector(formId);
        if (!form) return;
        
        for (const [fieldName, validators] of Object.entries(rules)) {
            const input = form.querySelector(`[name="${fieldName}"]`);
            if (!input) continue;
            
            input.addEventListener('blur', () => {
                this.validateField(input, validators);
            });
            
            input.addEventListener('input', () => {
                // Clear error on input
                input.classList.remove('inp-error');
                const errorSpan = input.nextElementSibling;
                if (errorSpan && errorSpan.classList.contains('field-error')) {
                    errorSpan.remove();
                }
            });
        }
    }
};
