/**
 * mySupport - Service Worker
 * PWA pour agents avec notifications push et cache offline
 */

const CACHE_NAME = 'mysupport-agent-v1';
const STATIC_CACHE = 'mysupport-static-v1';
const DYNAMIC_CACHE = 'mysupport-dynamic-v1';

// Ressources à mettre en cache pour le mode offline
const STATIC_ASSETS = [
    '/',
    '/agent',
    '/manifest.json',
    '/assets/css/app.css',
    '/assets/icons/icon-192x192.png',
    '/assets/icons/icon-512x512.png',
    'https://cdn.tailwindcss.com',
    'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css',
    'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'
];

// Pages à mettre en cache dynamiquement
const CACHE_PAGES = [
    '/agent',
    '/agent/conversations',
    '/agent/tickets'
];

// Installation du Service Worker
self.addEventListener('install', (event) => {
    console.log('[SW] Installation...');
    event.waitUntil(
        caches.open(STATIC_CACHE)
            .then((cache) => {
                console.log('[SW] Mise en cache des ressources statiques');
                return cache.addAll(STATIC_ASSETS).catch(err => {
                    console.log('[SW] Erreur cache statique:', err);
                });
            })
            .then(() => self.skipWaiting())
    );
});

// Activation et nettoyage des anciens caches
self.addEventListener('activate', (event) => {
    console.log('[SW] Activation...');
    event.waitUntil(
        caches.keys().then((cacheNames) => {
            return Promise.all(
                cacheNames
                    .filter((name) => name !== STATIC_CACHE && name !== DYNAMIC_CACHE)
                    .map((name) => {
                        console.log('[SW] Suppression ancien cache:', name);
                        return caches.delete(name);
                    })
            );
        }).then(() => self.clients.claim())
    );
});

// Stratégie de cache: Network First avec fallback sur cache
self.addEventListener('fetch', (event) => {
    const { request } = event;
    const url = new URL(request.url);

    // Ignorer les requêtes non-GET
    if (request.method !== 'GET') return;

    // Ignorer les requêtes API (toujours réseau)
    if (url.pathname.startsWith('/api/')) return;

    // Stratégie Network First pour les pages
    if (request.mode === 'navigate' || request.headers.get('accept').includes('text/html')) {
        event.respondWith(
            fetch(request)
                .then((response) => {
                    // Mettre en cache la réponse
                    const responseClone = response.clone();
                    caches.open(DYNAMIC_CACHE).then((cache) => {
                        cache.put(request, responseClone);
                    });
                    return response;
                })
                .catch(() => {
                    // Fallback sur le cache
                    return caches.match(request).then((cachedResponse) => {
                        if (cachedResponse) return cachedResponse;
                        // Page offline par défaut
                        return caches.match('/offline.html');
                    });
                })
        );
        return;
    }

    // Cache First pour les ressources statiques
    event.respondWith(
        caches.match(request).then((cachedResponse) => {
            if (cachedResponse) return cachedResponse;
            
            return fetch(request).then((response) => {
                // Mettre en cache les ressources statiques
                if (response.status === 200) {
                    const responseClone = response.clone();
                    caches.open(DYNAMIC_CACHE).then((cache) => {
                        cache.put(request, responseClone);
                    });
                }
                return response;
            });
        })
    );
});

// Gestion des notifications push
self.addEventListener('push', (event) => {
    console.log('[SW] Push reçu:', event);
    
    let data = {
        title: 'mySupport',
        body: 'Nouvelle notification',
        icon: '/assets/icons/icon-192x192.png',
        badge: '/assets/icons/badge-72x72.png',
        tag: 'default',
        data: {}
    };

    if (event.data) {
        try {
            data = { ...data, ...event.data.json() };
        } catch (e) {
            data.body = event.data.text();
        }
    }

    const options = {
        body: data.body,
        icon: data.icon || '/assets/icons/icon-192x192.png',
        badge: data.badge || '/assets/icons/badge-72x72.png',
        tag: data.tag || 'mysupport-notification',
        renotify: true,
        requireInteraction: data.requireInteraction || false,
        vibrate: [200, 100, 200],
        data: data.data || {},
        actions: data.actions || [
            { action: 'open', title: 'Ouvrir' },
            { action: 'dismiss', title: 'Ignorer' }
        ]
    };

    event.waitUntil(
        self.registration.showNotification(data.title, options)
    );
});

// Clic sur notification
self.addEventListener('notificationclick', (event) => {
    console.log('[SW] Clic notification:', event.action);
    
    event.notification.close();

    if (event.action === 'dismiss') return;

    const urlToOpen = event.notification.data?.url || '/agent';

    event.waitUntil(
        clients.matchAll({ type: 'window', includeUncontrolled: true })
            .then((clientList) => {
                // Si une fenêtre est déjà ouverte, la focus
                for (const client of clientList) {
                    if (client.url.includes('/agent') && 'focus' in client) {
                        client.navigate(urlToOpen);
                        return client.focus();
                    }
                }
                // Sinon, ouvrir une nouvelle fenêtre
                if (clients.openWindow) {
                    return clients.openWindow(urlToOpen);
                }
            })
    );
});

// Fermeture notification
self.addEventListener('notificationclose', (event) => {
    console.log('[SW] Notification fermée');
});

// Message depuis l'application
self.addEventListener('message', (event) => {
    console.log('[SW] Message reçu:', event.data);

    if (event.data.type === 'SKIP_WAITING') {
        self.skipWaiting();
    }

    if (event.data.type === 'CACHE_URLS') {
        const urls = event.data.urls || [];
        caches.open(DYNAMIC_CACHE).then((cache) => {
            cache.addAll(urls);
        });
    }
});

// Sync en arrière-plan (pour envoyer des messages en attente quand online)
self.addEventListener('sync', (event) => {
    console.log('[SW] Sync:', event.tag);

    if (event.tag === 'send-pending-messages') {
        event.waitUntil(sendPendingMessages());
    }
});

async function sendPendingMessages() {
    // Récupérer les messages en attente depuis IndexedDB
    // et les envoyer quand la connexion est rétablie
    console.log('[SW] Envoi des messages en attente...');
}
