/**
 * Enregistrement du Service Worker et gestion des mises à jour.
 *
 * Quand une nouvelle version du site est déployée (sw.js modifié, suffixe de
 * version des caches bumpé), le nouveau Service Worker s'installe en arrière-
 * plan et reste en attente. Un modal propose alors la mise à jour :
 *   - « Mettre à jour » : le SW en attente prend le contrôle (SKIP_WAITING),
 *     les anciens caches sont purgés à l'activation, puis la page se recharge
 *     sur la nouvelle version (controllerchange).
 *   - « Plus tard » : le modal se ferme ; la mise à jour sera reproposée au
 *     prochain chargement de page.
 *
 * Aucune purge manuelle du cache navigateur n'est nécessaire.
 */
(function () {
    'use strict';

    if (!('serviceWorker' in navigator)) {
        return;
    }

    let modalShown = false;
    let refreshing = false;

    // Recharge la page quand le nouveau Service Worker prend le contrôle
    navigator.serviceWorker.addEventListener('controllerchange', function () {
        if (refreshing) {
            return;
        }
        refreshing = true;
        window.location.reload();
    });

    /**
     * Construit et affiche le modal de mise à jour (une seule fois).
     * @param {ServiceWorker} waitingWorker Le SW en attente d'activation
     */
    function showUpdateModal(waitingWorker) {
        if (modalShown || !waitingWorker) {
            return;
        }
        modalShown = true;

        const overlay = document.createElement('div');
        overlay.className = 'pwa-update-overlay';
        overlay.setAttribute('role', 'dialog');
        overlay.setAttribute('aria-modal', 'true');
        overlay.setAttribute('aria-labelledby', 'pwa-update-title');
        overlay.innerHTML =
            '<div class="pwa-update-modal">' +
                '<img class="pwa-update-logo" src="img/logo.png" alt="" aria-hidden="true">' +
                '<h2 class="pwa-update-title" id="pwa-update-title">Nouvelle version disponible</h2>' +
                '<p class="pwa-update-text">' +
                    'Une mise à jour du site est prête à être installée. ' +
                    'Elle est rapide et ne supprime aucune de vos données.' +
                '</p>' +
                '<div class="pwa-update-actions">' +
                    '<button type="button" class="pwa-update-btn pwa-update-btn-primary">' +
                        'Mettre à jour' +
                    '</button>' +
                    '<button type="button" class="pwa-update-btn pwa-update-btn-secondary">' +
                        'Plus tard' +
                    '</button>' +
                '</div>' +
            '</div>';

        document.body.appendChild(overlay);

        // Force le reflow pour que la transition CSS d'entrée joue
        void overlay.offsetWidth;
        overlay.classList.add('pwa-update-visible');

        const primaryBtn = overlay.querySelector('.pwa-update-btn-primary');
        const secondaryBtn = overlay.querySelector('.pwa-update-btn-secondary');

        function closeModal() {
            overlay.classList.remove('pwa-update-visible');
            overlay.addEventListener('transitionend', function () {
                overlay.remove();
            }, { once: true });
        }

        primaryBtn.addEventListener('click', function () {
            primaryBtn.disabled = true;
            secondaryBtn.disabled = true;
            primaryBtn.textContent = 'Mise à jour…';
            // Le rechargement est déclenché par l'event controllerchange
            waitingWorker.postMessage({ type: 'SKIP_WAITING' });
        });

        secondaryBtn.addEventListener('click', closeModal);

        document.addEventListener('keydown', function onEscape(event) {
            if (event.key === 'Escape' && document.body.contains(overlay)) {
                closeModal();
                document.removeEventListener('keydown', onEscape);
            }
        });

        // Accessibilité : focus sur l'action principale
        primaryBtn.focus();
    }

    /**
     * Surveille l'installation d'un nouveau Service Worker.
     * @param {ServiceWorkerRegistration} registration
     */
    function trackInstalling(registration) {
        registration.addEventListener('updatefound', function () {
            const newWorker = registration.installing;
            if (!newWorker) {
                return;
            }
            newWorker.addEventListener('statechange', function () {
                // installed + un contrôleur actif = mise à jour en attente
                // (sans contrôleur, c'est la toute première installation)
                if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
                    showUpdateModal(registration.waiting);
                }
            });
        });
    }

    window.addEventListener('load', function () {
        navigator.serviceWorker.register('/sw.js')
            .then(function (registration) {
                // Cas où une mise à jour est déjà en attente (installée lors
                // d'une visite précédente, jamais activée)
                if (registration.waiting && navigator.serviceWorker.controller) {
                    showUpdateModal(registration.waiting);
                }
                trackInstalling(registration);
            })
            .catch(function (err) {
                console.log('Échec de l\'enregistrement du Service Worker:', err);
            });
    });
})();
