/**
 * Fichier  : assets/js/push-notifications.js
 * Auteur   : KREMER Régis
 * Version  : 2.2.0
 * Date     : 2026-02-21
 * Description : JS — Gestion des notifications Web Push 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
 */
// ================================================================
// push-notifications.js — Gestion des notifications push
// ================================================================

const PushManager = {
    swRegistration: null,
    isSubscribed: false,
    
    /**
     * Initialise le système de notifications push
     */
    async init() {
        // Vérifier le support
        if (!('serviceWorker' in navigator)) {
            console.log('[Push] Service Workers non supportés');
            return false;
        }
        
        if (!('PushManager' in window)) {
            console.log('[Push] Push API non supportée');
            return false;
        }
        
        if (!('Notification' in window)) {
            console.log('[Push] Notifications non supportées');
            return false;
        }
        
        try {
            // Enregistrer le Service Worker
            this.swRegistration = await navigator.serviceWorker.register('/sm/sw.js');
            console.log('[Push] Service Worker enregistré:', this.swRegistration);
            
            // Attendre que le SW soit prêt
            await navigator.serviceWorker.ready;
            
            // Vérifier l'état actuel
            const subscription = await this.swRegistration.pushManager.getSubscription();
            this.isSubscribed = subscription !== null;
            
            console.log('[Push] Abonné:', this.isSubscribed);
            
            // Mettre à jour l'UI
            this.updateUI();
            
            return true;
        } catch (error) {
            console.error('[Push] Erreur initialisation:', error);
            return false;
        }
    },
    
    /**
     * Demande la permission et s'abonne aux notifications
     */
    async subscribe() {
        try {
            // Demander la permission
            const permission = await Notification.requestPermission();
            
            if (permission !== 'granted') {
                console.log('[Push] Permission refusée');
                toast('Permission de notification refusée', 'warning');
                return false;
            }
            
            // Obtenir la clé publique VAPID
            const response = await fetch('/sm/api/push.php');
            const data = await response.json();
            const vapidPublicKey = data.publicKey;
            
            if (!vapidPublicKey) {
                console.error('[Push] Clé VAPID manquante');
                toast('Configuration des notifications incomplète', 'error');
                return false;
            }
            
            // Convertir la clé VAPID
            const applicationServerKey = this.urlBase64ToUint8Array(vapidPublicKey);
            
            // S'abonner
            const subscription = await this.swRegistration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: applicationServerKey
            });
            
            console.log('[Push] Subscription:', subscription);
            
            // Envoyer la subscription au serveur
            const saveResponse = await fetch('/sm/api/push.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': window.CSRF_TOKEN || ''
                },
                body: JSON.stringify({
                    action: 'subscribe',
                    subscription: subscription.toJSON()
                })
            });
            
            const saveData = await saveResponse.json();
            
            if (saveData.success) {
                this.isSubscribed = true;
                this.updateUI();
                toast('Notifications activées !', 'success');
                return true;
            } else {
                throw new Error(saveData.error || 'Erreur serveur');
            }
            
        } catch (error) {
            console.error('[Push] Erreur subscription:', error);
            toast('Erreur lors de l\'activation des notifications', 'error');
            return false;
        }
    },
    
    /**
     * Se désabonne des notifications
     */
    async unsubscribe() {
        try {
            const subscription = await this.swRegistration.pushManager.getSubscription();
            
            if (subscription) {
                // Supprimer côté serveur
                await fetch('/sm/api/push.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRF-TOKEN': window.CSRF_TOKEN || ''
                    },
                    body: JSON.stringify({
                        action: 'unsubscribe',
                        endpoint: subscription.endpoint
                    })
                });
                
                // Désabonner côté client
                await subscription.unsubscribe();
            }
            
            this.isSubscribed = false;
            this.updateUI();
            toast('Notifications désactivées', 'info');
            return true;
            
        } catch (error) {
            console.error('[Push] Erreur unsubscribe:', error);
            toast('Erreur lors de la désactivation', 'error');
            return false;
        }
    },
    
    /**
     * Bascule l'état des notifications
     */
    async toggle() {
        if (this.isSubscribed) {
            return await this.unsubscribe();
        } else {
            return await this.subscribe();
        }
    },
    
    /**
     * Envoie une notification de test
     */
    async sendTest() {
        try {
            const response = await fetch('/sm/api/push.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': window.CSRF_TOKEN || ''
                },
                body: JSON.stringify({ action: 'test' })
            });

            const data = await response.json();
            console.log('[Push] Test result:', data);

            if (data.sent > 0) {
                toast(`Notification de test envoyée (${data.sent}/${data.total} appareil(s))`, 'success');
            } else if (data.total === 0) {
                toast('Aucun appareil abonné — cliquez "Activer" d\'abord sur cet appareil', 'warning');
            } else {
                // Afficher le debug
                const errs = (data.errors || []).map(e => e.debug || e).join(' | ');
                toast(`Envoi échoué (${data.total} sub) — ${errs}`, 'error');
                console.error('[Push] Errors:', data.errors);
            }

        } catch (error) {
            console.error('[Push] Erreur test:', error);
            toast('Erreur lors du test', 'error');
        }
    },
    
    /**
     * Met à jour l'interface utilisateur
     */
    updateUI() {
        const btn    = document.getElementById('pushToggleBtn');
        const status = document.getElementById('pushStatus');

        if (btn) {
            btn.innerHTML = this.isSubscribed
                ? `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
                     <path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9"/>
                     <path d="M13.73 21a2 2 0 01-3.46 0"/>
                     <line x1="1" y1="1" x2="23" y2="23"/>
                   </svg> Désactiver les notifications`
                : `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2">
                     <path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9"/>
                     <path d="M13.73 21a2 2 0 01-3.46 0"/>
                   </svg> Activer sur cet appareil`;
            btn.className = this.isSubscribed
                ? 'btn btn-secondary'
                : 'btn btn-success';
        }

        if (status) {
            status.innerHTML = this.isSubscribed
                ? '<span class="badge badge-green">Activées</span>'
                : '<span class="badge badge-gray">Désactivées</span>';
        }

        // Mettre à jour l'info appareil dans SetPage si disponible
        if (typeof SetPage !== 'undefined' && SetPage._refreshPushDeviceInfo) {
            SetPage._refreshPushDeviceInfo();
        }
    },
    
    /**
     * Convertit une clé base64url en Uint8Array
     */
    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;
    },
    
    /**
     * Vérifie si les notifications sont supportées
     */
    isSupported() {
        return 'serviceWorker' in navigator && 
               'PushManager' in window && 
               'Notification' in window;
    },
    
    /**
     * Obtient l'état de la permission
     */
    getPermissionState() {
        if (!('Notification' in window)) {
            return 'unsupported';
        }
        return Notification.permission; // 'default', 'granted', 'denied'
    }
};

// Auto-init si l'utilisateur est admin
document.addEventListener('DOMContentLoaded', () => {
    // Vérifier si l'utilisateur est admin (via variable globale ou data attribute)
    const isAdmin = document.body.dataset.userRole === 'admin' || window.USER_ROLE === 'admin';
    
    if (isAdmin && PushManager.isSupported()) {
        PushManager.init().then(success => {
            if (success) {
                console.log('[Push] Système initialisé avec succès');
            }
        });
    }
});

// Exposer globalement (PushManager = notre objet, SMPush = alias pour éviter conflit avec l'API native)
window.SMPush = PushManager;
window.PushManager = PushManager; // garde compat
