/**
 * Validation du formulaire de contact
 * JavaScript vanilla - pas de dépendances
 */

/**
 * Service reCAPTCHA v3
 * Gestion du token avec dégradation gracieuse
 */
const RecaptchaService = {
    siteKey: null,

    init() {
        this.siteKey = window.RECAPTCHA_SITE_KEY || null;
    },

    isAvailable() {
        return this.siteKey && typeof grecaptcha !== 'undefined';
    },

    /**
     * Obtient un token reCAPTCHA
     * @param {string} action - Action à valider (ex: 'contact')
     * @returns {Promise<string>} - Token ou chaîne vide si indisponible
     */
    async getToken(action = 'contact') {
        // Dégradation gracieuse si reCAPTCHA non disponible
        if (!this.isAvailable()) {
            console.warn('reCAPTCHA non disponible, envoi sans protection');
            return '';
        }

        return new Promise((resolve) => {
            grecaptcha.ready(() => {
                grecaptcha.execute(this.siteKey, { action })
                    .then(token => resolve(token))
                    .catch(error => {
                        console.error('Erreur reCAPTCHA:', error);
                        resolve(''); // Permettre l'envoi quand même
                    });
            });
        });
    }
};

class FormValidator {
    constructor(formId) {
        this.form = document.getElementById(formId);
        if (!this.form) return;

        this.submitBtn = document.getElementById('submit-btn');
        this.submitText = document.getElementById('submit-text');
        this.submitLoading = document.getElementById('submit-loading');
        this.fields = {};
        this.errors = {};

        this.init();
    }

    init() {
        // Définir les règles de validation
        this.rules = {
            nom: {
                required: true,
                minLength: 2,
                maxLength: 100,
                message: 'Veuillez entrer votre nom (2 caractères minimum)'
            },
            prenom: {
                required: true,
                minLength: 2,
                maxLength: 100,
                message: 'Veuillez entrer votre prénom (2 caractères minimum)'
            },
            email: {
                required: true,
                email: true,
                message: 'Veuillez entrer une adresse email valide'
            },
            categorie: {
                required: true,
                message: 'Veuillez sélectionner une catégorie'
            },
            objet: {
                required: true,
                minLength: 5,
                maxLength: 200,
                message: 'Veuillez entrer un objet (5 caractères minimum)'
            },
            message: {
                required: true,
                minLength: 20,
                maxLength: 5000,
                message: 'Veuillez entrer votre message (20 caractères minimum)'
            }
        };

        // Récupérer les champs
        Object.keys(this.rules).forEach(fieldName => {
            this.fields[fieldName] = this.form.querySelector(`[name="${fieldName}"]`);
        });

        this.bindEvents();
    }

    bindEvents() {
        // Validation au blur
        Object.keys(this.fields).forEach(fieldName => {
            const field = this.fields[fieldName];
            if (field) {
                field.addEventListener('blur', () => this.validateField(fieldName));
                field.addEventListener('input', () => {
                    // Effacer l'erreur pendant la saisie
                    if (this.errors[fieldName]) {
                        this.clearError(fieldName);
                    }
                });
            }
        });

        // Validation à la soumission
        this.form.addEventListener('submit', (e) => this.handleSubmit(e));

        // Compteur de caractères pour le message
        const messageField = this.fields.message;
        if (messageField) {
            messageField.addEventListener('input', () => this.updateCharCount());
        }

        // Bouton reset
        this.form.addEventListener('reset', () => {
            setTimeout(() => {
                this.clearAllErrors();
                this.updateCharCount();
            }, 10);
        });
    }

    validateField(fieldName) {
        const field = this.fields[fieldName];
        const rule = this.rules[fieldName];

        if (!field || !rule) return true;

        const value = field.value.trim();
        let isValid = true;
        let errorMessage = '';

        // Required
        if (rule.required && !value) {
            isValid = false;
            errorMessage = rule.message;
        }

        // Min length
        if (isValid && rule.minLength && value.length < rule.minLength) {
            isValid = false;
            errorMessage = rule.message;
        }

        // Max length
        if (isValid && rule.maxLength && value.length > rule.maxLength) {
            isValid = false;
            errorMessage = `Maximum ${rule.maxLength} caractères`;
        }

        // Email format
        if (isValid && rule.email && value) {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (!emailRegex.test(value)) {
                isValid = false;
                errorMessage = rule.message;
            }
        }

        // Afficher ou masquer l'erreur
        if (isValid) {
            this.clearError(fieldName);
        } else {
            this.showError(fieldName, errorMessage);
        }

        this.errors[fieldName] = !isValid;
        this.updateSubmitButton();

        return isValid;
    }

    validateAll() {
        let allValid = true;

        Object.keys(this.rules).forEach(fieldName => {
            if (!this.validateField(fieldName)) {
                allValid = false;
            }
        });

        return allValid;
    }

    showError(fieldName, message) {
        const field = this.fields[fieldName];
        const errorEl = this.form.querySelector(`[data-error="${fieldName}"]`);

        if (field) {
            field.classList.add('border-red-500', 'focus:ring-red-500/50', 'focus:border-red-500');
            field.classList.remove('border-border', 'focus:ring-primary/50', 'focus:border-primary');
            field.setAttribute('aria-invalid', 'true');
        }

        if (errorEl) {
            errorEl.textContent = message;
            errorEl.classList.remove('hidden');
        }
    }

    clearError(fieldName) {
        const field = this.fields[fieldName];
        const errorEl = this.form.querySelector(`[data-error="${fieldName}"]`);

        if (field) {
            field.classList.remove('border-red-500', 'focus:ring-red-500/50', 'focus:border-red-500');
            field.classList.add('border-border', 'focus:ring-primary/50', 'focus:border-primary');
            field.removeAttribute('aria-invalid');
        }

        if (errorEl) {
            errorEl.textContent = '';
            errorEl.classList.add('hidden');
        }

        this.errors[fieldName] = false;
        this.updateSubmitButton();
    }

    clearAllErrors() {
        Object.keys(this.rules).forEach(fieldName => {
            this.clearError(fieldName);
        });
    }

    updateSubmitButton() {
        const hasErrors = Object.values(this.errors).some(err => err);

        if (this.submitBtn) {
            this.submitBtn.disabled = hasErrors;
        }
    }

    updateCharCount() {
        const messageField = this.fields.message;
        const countEl = document.getElementById('message-count');

        if (messageField && countEl) {
            countEl.textContent = messageField.value.length;
        }
    }

    setLoading(isLoading) {
        if (this.submitBtn) {
            this.submitBtn.disabled = isLoading;
        }
        if (this.submitText) {
            this.submitText.classList.toggle('hidden', isLoading);
        }
        if (this.submitLoading) {
            this.submitLoading.classList.toggle('hidden', !isLoading);
            if (isLoading) {
                this.submitLoading.classList.add('flex');
            } else {
                this.submitLoading.classList.remove('flex');
            }
        }
    }

    handleSubmit(e) {
        e.preventDefault();

        if (!this.validateAll()) {
            // Focus sur le premier champ en erreur
            const firstError = Object.keys(this.errors).find(key => this.errors[key]);
            if (firstError && this.fields[firstError]) {
                this.fields[firstError].focus();
            }
            return;
        }

        // Si valide, déclencher l'envoi
        this.form.dispatchEvent(new CustomEvent('validSubmit', {
            detail: this.getFormData()
        }));
    }

    getFormData() {
        const formData = {};
        Object.keys(this.fields).forEach(fieldName => {
            if (this.fields[fieldName]) {
                formData[fieldName] = this.fields[fieldName].value.trim();
            }
        });
        // Ajouter le champ entreprise (optionnel)
        const entreprise = this.form.querySelector('[name="entreprise"]');
        if (entreprise) {
            formData.entreprise = entreprise.value.trim();
        }
        // Ajouter le token CSRF
        const csrfToken = this.form.querySelector('[name="csrf_token"]');
        if (csrfToken) {
            formData.csrf_token = csrfToken.value;
        }
        return formData;
    }
}

/**
 * Gestionnaire de persistance du formulaire
 * Sauvegarde/restaure les données via localStorage
 */
class ContactFormPersistence {
    constructor(formId) {
        this.form = document.getElementById(formId);
        if (!this.form) return;

        this.debounceTimer = null;
        this.init();
    }

    init() {
        this.loadSavedData();
        this.bindEvents();
    }

    bindEvents() {
        // Sauvegarder à chaque modification (avec debounce de 500ms)
        this.form.addEventListener('input', () => {
            clearTimeout(this.debounceTimer);
            this.debounceTimer = setTimeout(() => this.saveData(), 500);
        });

        // Bouton effacer
        const clearBtn = document.getElementById('clear-form-btn');
        if (clearBtn) {
            clearBtn.addEventListener('click', (e) => {
                e.preventDefault();
                this.clearForm();
            });
        }

        // Écouter l'envoi réussi (dispatché par le handler AJAX)
        this.form.addEventListener('formSuccess', () => {
            AppState.clearFormData();
        });
    }

    saveData() {
        const formData = new FormData(this.form);
        const data = {};

        formData.forEach((value, key) => {
            data[key] = value;
        });

        AppState.saveFormData(data);
    }

    loadSavedData() {
        const savedData = AppState.getFormData();
        if (!savedData) return;

        Object.keys(savedData).forEach(key => {
            const field = this.form.querySelector(`[name="${key}"]`);
            if (field && savedData[key]) {
                field.value = savedData[key];
            }
        });

        // Mettre à jour le compteur de caractères
        const messageField = this.form.querySelector('[name="message"]');
        const countEl = document.getElementById('message-count');
        if (messageField && countEl) {
            countEl.textContent = messageField.value.length;
        }
    }

    clearForm() {
        // Confirmation
        if (!confirm('Êtes-vous sûr de vouloir effacer le formulaire ?')) {
            return;
        }

        // Vider le localStorage
        AppState.clearFormData();

        // Réinitialiser le formulaire
        this.form.reset();

        // Réinitialiser le compteur
        const countEl = document.getElementById('message-count');
        if (countEl) {
            countEl.textContent = '0';
        }

        // Effacer les erreurs visuelles
        this.form.querySelectorAll('.border-red-500').forEach(el => {
            el.classList.remove('border-red-500', 'focus:ring-red-500/50', 'focus:border-red-500');
            el.classList.add('border-border', 'focus:ring-primary/50', 'focus:border-primary');
            el.removeAttribute('aria-invalid');
        });
        this.form.querySelectorAll('[data-error]').forEach(el => {
            el.classList.add('hidden');
            el.textContent = '';
        });

        // Réactiver le bouton submit
        const submitBtn = document.getElementById('submit-btn');
        if (submitBtn) {
            submitBtn.disabled = false;
        }
    }
}

/**
 * Gestionnaire d'envoi AJAX du formulaire
 * Gère le loading, succès et erreurs
 */
class ContactFormSubmit {
    constructor(formId) {
        this.form = document.getElementById(formId);
        if (!this.form) return;

        this.submitBtn = document.getElementById('submit-btn');
        this.submitText = document.getElementById('submit-text');
        this.submitLoading = document.getElementById('submit-loading');
        this.successMessage = document.getElementById('success-message');
        this.errorMessage = document.getElementById('error-message');
        this.errorText = document.getElementById('error-text');

        this.isSubmitting = false;

        this.init();
    }

    init() {
        // Écouter l'événement de validation réussie
        this.form.addEventListener('validSubmit', (e) => this.handleSubmit(e.detail));
    }

    async handleSubmit(formData) {
        if (this.isSubmitting) return;

        this.setLoadingState(true);
        this.hideMessages();

        try {
            // Ajouter le token CSRF
            const csrfInput = this.form.querySelector('[name="csrf_token"]');
            if (csrfInput) {
                formData.csrf_token = csrfInput.value;
            }

            // Obtenir le token reCAPTCHA
            formData.recaptcha_token = await RecaptchaService.getToken('contact');

            // Envoyer la requête
            const response = await fetch('/api/contact.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'application/json'
                },
                body: JSON.stringify(formData)
            });

            const result = await response.json();

            if (result.success) {
                this.handleSuccess(result.message);
            } else {
                this.handleError(result.error || 'Une erreur est survenue');
            }

        } catch (error) {
            console.error('Erreur envoi formulaire:', error);
            this.handleError('Impossible de contacter le serveur. Vérifiez votre connexion.');
        } finally {
            this.setLoadingState(false);
        }
    }

    setLoadingState(loading) {
        this.isSubmitting = loading;

        if (this.submitBtn) {
            this.submitBtn.disabled = loading;
        }

        if (this.submitText && this.submitLoading) {
            if (loading) {
                this.submitText.classList.add('hidden');
                this.submitLoading.classList.remove('hidden');
                this.submitLoading.classList.add('flex');
            } else {
                this.submitText.classList.remove('hidden');
                this.submitLoading.classList.add('hidden');
                this.submitLoading.classList.remove('flex');
            }
        }
    }

    handleSuccess(message) {
        // Masquer le formulaire
        this.form.classList.add('hidden');

        // Afficher le message de succès
        if (this.successMessage) {
            this.successMessage.classList.remove('hidden');

            // Scroll vers le message
            this.successMessage.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }

        // Vider le localStorage
        AppState.clearFormData();

        // Réinitialiser le formulaire (pour un éventuel nouvel envoi)
        this.form.reset();

        // Déclencher l'événement de succès
        this.form.dispatchEvent(new CustomEvent('formSuccess'));
    }

    handleError(message) {
        // Afficher le message d'erreur
        if (this.errorMessage && this.errorText) {
            this.errorText.textContent = message;
            this.errorMessage.classList.remove('hidden');

            // Scroll vers le message
            this.errorMessage.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }

        // Les données sont conservées dans le formulaire pour réessayer
    }

    hideMessages() {
        if (this.successMessage) {
            this.successMessage.classList.add('hidden');
        }
        if (this.errorMessage) {
            this.errorMessage.classList.add('hidden');
        }
    }
}

// Initialisation
document.addEventListener('DOMContentLoaded', () => {
    RecaptchaService.init();
    window.contactFormValidator = new FormValidator('contact-form');
    window.contactFormPersistence = new ContactFormPersistence('contact-form');
    window.contactFormSubmit = new ContactFormSubmit('contact-form');
});
