/**
 * EdumacFlo Progressive Web App (PWA) Service Worker
 * Version: 3.1.0
 * Strategy: Stale-While-Revalidate for Static Assets | Network-First for Pages | Offline Fallback
 */

const CACHE_NAME = 'edumacflo-cache-v3';
const OFFLINE_URL = 'offline.html';

const PRECACHE_ASSETS = [
  'offline.html',
  'assets/css/main.css',
  'assets/css/custom-theme.css',
  'assets/css/table.css',
  'assets/vendor/font-awesome/css/all.min.css',
  'assets/vendor/simple-line-icons/css/simple-line-icons.css',
  'assets/js/main.js',
  'assets/js/theme-toggle.js',
  'assets/vendor/jquery/jquery-3.2.1.min.js'
];

// 1. Install Event: Pre-cache core shell & offline fallback
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => {
      console.log('[EdumacFlo SW] Pre-caching offline page and shell assets...');
      return cache.addAll(PRECACHE_ASSETS.map(url => new Request(url, { cache: 'reload' }))).catch((err) => {
        console.warn('[EdumacFlo SW] Some pre-cache assets could not be cached immediately:', err);
      });
    }).then(() => self.skipWaiting())
  );
});

// 2. Activate Event: Clean up legacy caches and claim clients immediately
self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames.map((cache) => {
          if (cache !== CACHE_NAME) {
            console.log('[EdumacFlo SW] Purging old cache:', cache);
            return caches.delete(cache);
          }
        })
      );
    }).then(() => self.clients.claim())
  );
});

// 3. Fetch Event: Smart routing & caching
self.addEventListener('fetch', (event) => {
  // Only intercept GET requests
  if (event.request.method !== 'GET') {
    return;
  }

  const url = new URL(event.request.url);

  // Bypass service worker for file downloads or external APIs if needed
  if (url.searchParams.has('download_snapshot') || url.searchParams.has('export_excel') || url.pathname.includes('export_broadsheet')) {
    return;
  }

  // Strategy A: HTML Navigation & Dynamic PHP Pages (Network-First with Offline Fallback)
  if (event.request.mode === 'navigate' || url.pathname.endsWith('.php') || url.pathname.endsWith('/') || !url.pathname.includes('.')) {
    event.respondWith(
      fetch(event.request)
        .then((networkResponse) => {
          // If valid response, clone into cache for offline viewing
          if (networkResponse && networkResponse.status === 200) {
            const responseClone = networkResponse.clone();
            caches.open(CACHE_NAME).then((cache) => {
              cache.put(event.request, responseClone);
            });
          }
          return networkResponse;
        })
        .catch(() => {
          // Network failed (device is offline)
          return caches.match(event.request).then((cachedResponse) => {
            if (cachedResponse) {
              return cachedResponse;
            }
            // If page is not in cache, deliver the rich offline fallback page
            return caches.match(OFFLINE_URL);
          });
        })
    );
    return;
  }

  // Strategy B: Static Assets (CSS, JS, WebFonts, Images) -> Stale-While-Revalidate
  event.respondWith(
    caches.match(event.request).then((cachedResponse) => {
      const fetchPromise = fetch(event.request)
        .then((networkResponse) => {
          if (networkResponse && networkResponse.status === 200) {
            const responseClone = networkResponse.clone();
            caches.open(CACHE_NAME).then((cache) => {
              cache.put(event.request, responseClone);
            });
          }
          return networkResponse;
        })
        .catch(() => {
          // Ignore network errors for background cache updates
        });

      return cachedResponse || fetchPromise;
    })
  );
});

// 4. Message Event: Support for manual skipWaiting or cache purging from app UI
self.addEventListener('message', (event) => {
  if (event.data && event.data.action === 'skipWaiting') {
    self.skipWaiting();
  }
});
