import './app.scss'
import * as Turbo from "@hotwired/turbo"
import '@grafikart/drop-files-element'
import {PaymentForm} from './PaymentForm'
import * as Sentry from "@sentry/browser";

// --- CLÉS DE STOCKAGE ET VAPID ---
const VAPID_PUBLIC_KEY = "BKz0kdcsG6kk9KxciPpkfP8kEDAd408inZecij5kBDbQ1ZGZSNwS4KZ8FerC28LFXvgSqpDXtor3ePo0zBCdNqo";
const COOKIE_STORAGE_KEY = 'cookies_accepted'; // Clé pour le consentement des cookies


// --- MESSAGES ET TRADUCTIONS (fr et en) ---
const MESSAGES = {
    fr: {
        // Notifications
        notificationTitle: "🔔 Activer les notifications",
        notificationText: "Recevez les nouvelles, les promotions et les événements de l'association.",
        notificationButton: "Activer",
        notificationClose: "Fermer la notification",

        // Cookies
        cookieText: 'Ce site utilise uniquement des cookies de <strong>fonctionnement</strong> et de <strong>sécurité</strong> (e.g. Cloudflare) essentiels pour son bon fonctionnement. Aucune donnée personnelle n\'est collectée.',
        cookieLink: "Politique de cookies",
        cookieButton: "Accepter",
    },
    en: {
        // Notifications
        notificationTitle: "🔔 Enable Notifications",
        notificationText: "Receive news, promotions, and association events.",
        notificationButton: "Enable",
        notificationClose: "Close notification",

        // Cookies
        cookieText: 'This website only uses <strong>functional</strong> and <strong>security</strong> cookies (e.g. Cloudflare) essential for its proper operation. No personal data is collected.',
        cookieLink: "Cookie Policy",
        cookieButton: "Accept",
    }
};

/**
 * Détermine la langue à utiliser, en privilégiant l'attribut 'lang' du document HTML,
 * puis la langue du navigateur. Retourne l'ensemble de messages correspondant.
 * @returns {object} L'objet de messages pour la langue sélectionnée.
 */
function getLanguageMessages() {
    let langCode = 'fr'; // Français par défaut

    // 1. Tente de lire la langue depuis l'attribut 'lang' du tag <html>
    const htmlLang = document.documentElement.lang;
    if (htmlLang) {
        // On prend les deux premiers caractères (ex: 'en-US' devient 'en')
        const normalizedHtmlLang = htmlLang.toLowerCase().substring(0, 2);
        if (normalizedHtmlLang === 'en') {
            langCode = 'en';
        }
    } else {
        // 2. Si l'attribut 'lang' est manquant, utilise la langue du navigateur
        const userLang = navigator.language || navigator.userLanguage;
        if (userLang && userLang.toLowerCase().startsWith('en')) {
            langCode = 'en';
        }
    }

    return MESSAGES[langCode];
}
// --- FIN MESSAGES ET TRADUCTIONS ---


/**
 * Convertit une chaîne Base64 URL Safe en Uint8Array.
 * Nécessaire pour passer la clé VAPID publique à pushManager.subscribe().
 * @param {string} base64String
 * @returns {Uint8Array}
 */
function urlBase64ToUint8Array(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
        .replace(/\-/g, '+')
        .replace(/_/g, '/');

    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
}


/**
 * Fonction générique pour basculer la visibilité d'un menu déroulant.
 * @param {HTMLElement} button - Le bouton qui déclenche l'action.
 * @param {HTMLElement} menu - Le menu à afficher/masquer.
 */
function toggleMenu(button, menu) {
    if (!button || !menu) return;
    const isExpanded = button.getAttribute('aria-expanded') === 'true' || false;
    button.setAttribute('aria-expanded', !isExpanded);
    menu.classList.toggle('hidden');
}

/**
 * Fonction d'initialisation pour les composants qui DOIVENT être réinitialisés
 * après un chargement Turbo (comme les compteurs d'articles, les états initiaux).
 * Le menu mobile et le panier sont gérés par délégation d'événements.
 */
function initializeUI() {
    // Réinitialisation des états des menus cachés après un chargement Turbo
    document.querySelectorAll('#mobile-menu, #userMenuDesktop, #userMenuMobile').forEach(menu => {
        if (!menu.classList.contains('hidden')) {
            menu.classList.add('hidden');
        }
    });
    document.querySelectorAll('#mobileMenuButton, #userMenuButtonDesktop, #userMenuButtonMobile').forEach(button => {
        button.setAttribute('aria-expanded', 'false');
    });


    // --- 2. Gestion du Panier Latéral (Off-Canvas) ---
    const cartSidebar = document.getElementById('cartSidebar');
    const cartBackdrop = document.getElementById('cartBackdrop');
    const closeCartButton = document.getElementById('closeCartButton');

    // Mettez les fonctions ici pour qu'elles soient toujours définies si les éléments existent
    if (cartSidebar && cartBackdrop && closeCartButton) {
        function openCart() {
            document.body.style.overflow = 'hidden';
            cartBackdrop.classList.remove('hidden');
            cartSidebar.classList.remove('translate-x-full');
            cartSidebar.classList.add('translate-x-0');
        }

        function closeCart() {
            document.body.style.overflow = '';
            cartSidebar.classList.remove('translate-x-0');
            cartSidebar.classList.add('translate-x-full');
            setTimeout(() => {
                cartBackdrop.classList.add('hidden');
            }, 300);
        }

        // Stocker les fonctions dans une variable globale accessible par l'écouteur du document
        window.openCart = openCart;
        window.closeCart = closeCart;
    } else {
        // Sécurité si les éléments du panier n'existent pas
        window.openCart = null;
        window.closeCart = null;
    }


    // --- 3. Logique Panier Mock (Affichage du compteur) ---
    function updateCartDisplay(count) {
        const desktopCounter = document.getElementById('cartCountDesktop');
        const mobileCounter = document.getElementById('cartCountMobile');

        if (desktopCounter) desktopCounter.textContent = count;
        if (mobileCounter) mobileCounter.textContent = count;
    }

    // Simuler un panier non-vide au chargement (Mettre 0 pour un panier vide réel)
    updateCartDisplay(0);

    // --- 4. Vérification de l'abonnement push au chargement ---
    if ('Notification' in window && Notification.permission === 'granted') {
        subscribeAndSave();
    }
}

/**
 * Tente d'abonner l'utilisateur aux notifications push via le Service Worker
 * et envoie l'objet d'abonnement au backend (/notificationSub).
 */
async function subscribeAndSave() {
    if (!('Notification' in window) || Notification.permission !== 'granted') {
        console.log("Les notifications ne sont pas supportées ou la permission n'est pas accordée.");
        return;
    }

    if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
        console.error("Le Service Worker ou PushManager n'est pas disponible pour l'abonnement.");
        return;
    }

    try {
        const registration = await navigator.serviceWorker.ready;
        let subscription = await registration.pushManager.getSubscription();

        // 1. Si aucun abonnement n'existe, on essaie d'en créer un.
        if (!subscription) {
            console.log("Aucun abonnement existant trouvé. Tentative de nouvel abonnement...");

            const applicationServerKey = urlBase64ToUint8Array(VAPID_PUBLIC_KEY);

            subscription = await registration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: applicationServerKey
            });

            if (!subscription) {
                console.error("Échec de la création de l'abonnement. Le Service Worker est-il correctement enregistré et la clé VAPID valide ?");
                return;
            }
        } else {
            console.log("Abonnement push existant trouvé. Vérification/Mise à jour auprès du serveur.");
        }

        // 2. Envoi (ou mise à jour) de l'abonnement au backend
        const payload = { subscription: subscription.toJSON() };

        const response = await fetch('/notificationSub', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(payload)
        });

        if (response.ok) {
            console.log("-> Abonnement aux notifications sauvegardé (ou vérifié) avec succès sur le serveur. <-");
        } else {
            console.error("-> Erreur lors de la sauvegarde de l'abonnement:", response.status, response.statusText);
        }

    } catch (error) {
        console.error("Erreur lors de l'obtention de l'abonnement ou de l'enregistrement:", error);
    }
}

/**
 * Tente de demander la permission si nécessaire et d'appeler l'abonnement.
 * (Utilisée par le clic du bandeau)
 */
async function promptForPermissionAndSubscribe() {
    if (!('Notification' in window)) {
        console.error("Les Notifications ne sont pas supportées par ce navigateur.");
        return;
    }

    // Demander la permission
    try {
        const permission = await Notification.requestPermission();

        if (permission === 'granted') {
            console.log("-> Permission de notification accordée. Lancement de l'abonnement. <-");
            await subscribeAndSave();
        } else {
            console.log(`-> Permission de notification refusée ou ignorée (${permission}). <-`);
        }
    } catch (error) {
        console.error("Erreur lors de la demande de permission:", error);
    }
}

// ====================================================================
// --- NOUVELLE FONCTION DE DÉTECTION POUR PAGESPEED/LIGHTHOUSE ---
// ====================================================================

/**
 * Vérifie si le script est exécuté par un User Agent de test (e.g., Lighthouse/PageSpeed)
 * @returns {boolean} True si c'est un User Agent de test.
 */
function isPerformanceTestAgent() {
    const ua = navigator.userAgent;
    // Vérifie les User Agents connus des outils de performance
    return ua.includes('Lighthouse') || ua.includes('Chrome-Lighthouse') || ua.includes('PageSpeed') || ua.includes('moto g power') || ua.includes('Intel Mac OS X 10_15_7');
}


/**
 * Affiche une petite carte de notification push temporaire en bas à gauche.
 * N'affiche QUE si la permission n'est PAS accordée.
 */
function handleNotificationBanner() {
    // 0. MASQUAGE POUR PAGESPEED
    if (isPerformanceTestAgent()) {
        console.log("Notification Banner skipped for performance test agent.");
        return;
    }
    // --- FIN MASQUAGE ---

    const BANNER_ID = 'notification-prompt-banner';
    const DURATION_MS = 15000; // 15 secondes d'affichage
    const M = getLanguageMessages(); // Récupère les messages traduits

    // 1. NE PAS AFFICHER si la permission est déjà accordée
    if ('Notification' in window && Notification.permission === 'granted') {
        return;
    }

    // 2. Si le bandeau existe déjà, on quitte.
    if (document.getElementById(BANNER_ID)) {
        return;
    }

    // 3. Créer le conteneur du message
    const banner = document.createElement('div');
    banner.id = BANNER_ID;
    banner.className = `fixed bottom-4 left-4 z-50 p-4 max-w-xs
                        bg-indigo-600 text-white rounded-xl shadow-2xl
                        transition-all duration-500 transform
                        opacity-0 translate-y-full
                        md:left-8 md:bottom-8`; // Style initial (masqué)

    banner.innerHTML = `
        <div class="flex items-start justify-between">
            <p class="font-semibold text-sm leading-snug">
                ${M.notificationTitle}
            </p>
            <button id="closeNotificationBanner"
                    aria-label="${M.notificationClose}"
                    class="ml-3 -mt-1 p-1 rounded-full text-indigo-200 hover:text-white hover:bg-indigo-700 transition">
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x"><path d="M18 6L6 18"/><path d="M6 6l12 12"/></svg>
            </button>
        </div>
        <p class="mt-1 text-xs text-indigo-200">
            ${M.notificationText}
        </p>
        <button id="activateNotifications"
                class="mt-3 w-full text-center py-2 bg-white text-indigo-600 font-bold text-sm rounded-lg
                       shadow hover:bg-gray-100 transition transform hover:scale-[1.02]">
            ${M.notificationButton}
        </button>
    `;

    document.body.appendChild(banner);

    // 4. Fonctions d'animation et de gestion
    const hideBanner = () => {
        // Déclenche l'animation de disparition
        banner.classList.remove('opacity-100', 'translate-y-0');
        banner.classList.add('opacity-0', 'translate-y-full');
        // Supprime après l'animation pour nettoyer le DOM
        setTimeout(() => {
            if (document.body.contains(banner)) {
                document.body.removeChild(banner);
            }
        }, 600);
    };

    // Clic sur le bouton de fermeture
    document.getElementById('closeNotificationBanner').addEventListener('click', () => {
        hideBanner();
    });

    // Clic sur le bouton d'activation -> Logique Push
    document.getElementById('activateNotifications').addEventListener('click', async () => {
        await promptForPermissionAndSubscribe();
        // Fermer le bandeau après l'interaction (que ce soit accordé ou refusé)
        hideBanner();
    });

    // 5. Affichage et Timer

    // Montre le bandeau (déclencher l'animation)
    setTimeout(() => {
        banner.classList.remove('opacity-0', 'translate-y-full');
        banner.classList.add('opacity-100', 'translate-y-0');
    }, 100);

    // Cache le bandeau automatiquement après la durée définie
    setTimeout(hideBanner, DURATION_MS);
}


/**
 * Affiche le bandeau de consentement aux cookies en bas à droite s'il n'a jamais été accepté.
 */
function handleCookieBanner() {
    // 0. MASQUAGE POUR PAGESPEED
    if (isPerformanceTestAgent()) {
        console.log("Cookie Banner skipped for performance test agent.");
        return;
    }
    // --- FIN MASQUAGE ---

    const BANNER_ID = 'cookie-banner';
    const M = getLanguageMessages(); // Récupère les messages traduits

    // 1. NE PAS AFFICHER si le consentement est déjà enregistré
    if (localStorage.getItem(COOKIE_STORAGE_KEY) === 'true') {
        return;
    }

    // 2. Si le bandeau existe déjà, on quitte.
    if (document.getElementById(BANNER_ID)) {
        return;
    }

    // 3. Créer le conteneur du message (position bottom-right)
    const banner = document.createElement('div');
    banner.id = BANNER_ID;
    banner.className = `fixed bottom-4 right-4 z-50 p-4 max-w-sm
                        bg-white text-gray-800 rounded-xl shadow-2xl
                        transition-all duration-500 transform
                        opacity-0 translate-y-full
                        border border-gray-100
                        md:right-8 md:bottom-8`; // Style initial (masqué)

    // Utilisation de M.cookieText, M.cookieLink et M.cookieButton
    // MODIFICATION APPORTÉE ICI : Ajout de py-2 (padding vertical) au lien "En savoir plus"
    banner.innerHTML = `
        <p class="text-sm leading-relaxed">
            ${M.cookieText}
        </p>
        <div class="mt-4 flex justify-end items-center">
            <a href="/cookies" class="py-2 font-medium text-indigo-600 hover:text-indigo-800 transition mr-4">
                ${M.cookieLink}
            </a>
            <button id="acceptCookies"
                    class="py-2 px-4 bg-indigo-600 text-white font-bold text-sm rounded-lg
                           shadow-md hover:bg-indigo-700 transition transform hover:scale-[1.02]">
                ${M.cookieButton}
            </button>
        </div>
    `;

    document.body.appendChild(banner);

    // 4. Fonctions d'animation et de gestion
    const hideBanner = () => {
        // Déclenche l'animation de disparition
        banner.classList.remove('opacity-100', 'translate-y-0');
        banner.classList.add('opacity-0', 'translate-y-full');
        // Supprime après l'animation
        setTimeout(() => {
            if (document.body.contains(banner)) {
                document.body.removeChild(banner);
            }
        }, 600);
    };

    // Clic sur le bouton d'acceptation
    document.getElementById('acceptCookies').addEventListener('click', () => {
        localStorage.setItem(COOKIE_STORAGE_KEY, 'true');
        hideBanner();
    });

    // 5. Affichage
    // Montre le bandeau (déclencher l'animation)
    setTimeout(() => {
        banner.classList.remove('opacity-0', 'translate-y-full');
        banner.classList.add('opacity-100', 'translate-y-0');
    }, 100);
}


// --- INITIALISATION DES COMPOSANTS APRÈS TURBO/CHARGEMENT ---
document.addEventListener('DOMContentLoaded', ()=>{
    customElements.define('payment-don',PaymentForm,{extends:'form'})

    // initializeUI appelle subscribeAndSave si la permission est accordée
    initializeUI()
    if (!isPerformanceTestAgent()) {
        // Gère le bandeau de notification (bottom-left)
        handleNotificationBanner()

        // Gère le bandeau de cookies (bottom-right)
        handleCookieBanner()
    }
    if (!isPerformanceTestAgent()) {
        var BASE_URL_WOOT = "https://chat.esy-web.dev";
        let script = document.createElement('script');
        script.setAttribute('src', BASE_URL_WOOT + "/packs/js/sdk.js")
        script.setAttribute('sync', true)
        document.head.append(script)
        script.onload = function () {
            window.chatwootSDK.run({
                websiteToken: '6uFX3g3qybyvSt3PAQUMgkm4',
                baseUrl: BASE_URL_WOOT
            })
        }
    }
    const env = document.querySelector('meta[name="env"]')
    if(env.getAttribute('content') == "prod") {
        if (typeof navigator.serviceWorker !== 'undefined') {
            // Assurez-vous que le Service Worker est bien enregistré en mode prod
            navigator.serviceWorker.register('sw.js')
        }
    }
});
document.addEventListener('turbo:load', () => {
    initializeUI();
    handleNotificationBanner();
    handleCookieBanner(); // Doit être appelé à chaque chargement Turbo

});


// ====================================================================
// --- DÉLÉGATION D'ÉVÉNEMENTS (Gestion des clics une seule fois) ---
// ====================================================================

document.addEventListener('click', (event) => {
    const target = event.target;

    // --- 1. GESTION DU MENU MOBILE (Burger) ---
    const mobileMenuButton = document.getElementById('mobileMenuButton');
    const mobileMenu = document.getElementById('mobile-menu');

    // On vérifie si la cible cliquée est le bouton ou un de ses enfants
    if (mobileMenuButton && mobileMenu && (target === mobileMenuButton || mobileMenuButton.contains(target))) {
        event.preventDefault();
        toggleMenu(mobileMenuButton, mobileMenu);
        return;
    }

    // --- 2. GESTION DU MENU UTILISATEUR (Dropdown) ---
    const userMenuButtonDesktop = document.getElementById('userMenuButtonDesktop');
    const userMenuDesktop = document.getElementById('userMenuDesktop');
    const userMenuButtonMobile = document.getElementById('userMenuButtonMobile');
    const userMenuMobile = document.getElementById('userMenuMobile');

    // Ouverture/Fermeture du menu utilisateur Desktop
    if (userMenuButtonDesktop && userMenuDesktop && (target === userMenuButtonDesktop || userMenuButtonDesktop.contains(target))) {
        event.preventDefault();
        // S'assurer que les autres menus sont fermés
        userMenuMobile.classList.add('hidden');
        toggleMenu(userMenuButtonDesktop, userMenuDesktop);
        return;
    }

    // Ouverture/Fermeture du menu utilisateur Mobile
    if (userMenuButtonMobile && userMenuMobile && (target === userMenuButtonMobile || userMenuButtonMobile.contains(target))) {
        event.preventDefault();
        // S'assurer que les autres menus sont fermés
        userMenuDesktop.classList.add('hidden');
        toggleMenu(userMenuButtonMobile, userMenuMobile);
        return;
    }

    // Fermeture des menus s'il y a un clic en dehors
    const isClickInsideDesktopMenu = userMenuDesktop && (userMenuDesktop.contains(target) || userMenuButtonDesktop.contains(target));
    const isClickInsideMobileMenu = userMenuMobile && (userMenuMobile.contains(target) || userMenuButtonMobile.contains(target));

    if (userMenuDesktop && userMenuButtonDesktop && !isClickInsideDesktopMenu) {
        userMenuDesktop.classList.add('hidden');
        userMenuButtonDesktop.setAttribute('aria-expanded', 'false');
    }
    if (userMenuMobile && userMenuButtonMobile && !isClickInsideMobileMenu) {
        userMenuMobile.classList.add('hidden');
        userMenuButtonMobile.setAttribute('aria-expanded', 'false');
    }

    // --- 3. GESTION DE L'OUVERTURE ET FERMETURE DU PANIER ---
    const openCartDesktop = document.getElementById('openCartDesktop');
    const openCartMobile = document.getElementById('openCartMobile');
    const closeCartButton = document.getElementById('closeCartButton');
    const cartBackdrop = document.getElementById('cartBackdrop');

    // Ouverture (Desktop ou Mobile)
    if (window.openCart && (
        (openCartDesktop && (target === openCartDesktop || openCartDesktop.contains(target))) ||
        (openCartMobile && (target === openCartMobile || openCartMobile.contains(target)))
    )) {
        event.preventDefault();
        window.openCart();
        return;
    }

    // Fermeture (Bouton interne)
    if (window.closeCart && closeCartButton && (target === closeCartButton || closeCartButton.contains(target))) {
        event.preventDefault();
        window.closeCart();
        return;
    }

    // Fermeture (Cliquer sur le fond/backdrop)
    if (window.closeCart && target === cartBackdrop) {
        window.closeCart();
        return;
    }

});

// --- GESTION GLOBALE DE LA TOUCHE ESC (Une seule fois) ---
document.addEventListener('keydown', (event) => {
    const cartSidebar = document.getElementById('cartSidebar');
    // Fermer le panier
    if (cartSidebar && window.closeCart && event.key === 'Escape' && !cartSidebar.classList.contains('translate-x-full')) {
        window.closeCart();
        return;
    }

    // Fermer les menus utilisateur
    const userMenuDesktop = document.getElementById('userMenuDesktop');
    const userMenuButtonDesktop = document.getElementById('userMenuButtonDesktop');
    const userMenuMobile = document.getElementById('userMenuMobile');
    const userMenuButtonMobile = document.getElementById('userMenuButtonMobile');

    if (event.key === 'Escape') {
        if (userMenuDesktop && !userMenuDesktop.classList.contains('hidden')) {
            toggleMenu(userMenuButtonDesktop, userMenuDesktop);
            return;
        }
        if (userMenuMobile && !userMenuMobile.classList.contains('hidden')) {
            toggleMenu(userMenuButtonMobile, userMenuMobile);
            return;
        }
    }
});
