/* ENPEX Almacén CRM - Service Worker (v6) */
const VERSION = 'v6-20250820';
const SCOPE   = '/almacencrm/';         // Asegura que coincide con BASE_URL
const RUNTIME = 'enpex-rt-' + VERSION;

// (Opcional) recursos estáticos a precachear
const PRECACHE = [
  // `${SCOPE}assets/adminlte/dist/css/adminlte.min.css`,
  // `${SCOPE}assets/adminlte/dist/js/adminlte.min.js`,
  // `${SCOPE}offline.html`,
];

self.addEventListener('install', (e) => {
  e.waitUntil(caches.open(RUNTIME).then(c => c.addAll(PRECACHE)).catch(()=>{}));
  self.skipWaiting();
});

self.addEventListener('activate', (e) => {
  e.waitUntil((async () => {
    const keys = await caches.keys();
    await Promise.all(keys.map(k => (k !== RUNTIME ? caches.delete(k) : null)));
    await self.clients.claim();
  })());
});

/* utilidades */
const neverCache = (url) =>
  url.pathname.startsWith(`${SCOPE}ajax/`) ||
  url.pathname.startsWith(`${SCOPE}controllers/`) ||
  url.pathname.endsWith('.php');

const isInsideScope = (url) => url.pathname.startsWith(SCOPE);
const isCdn = (url) =>
  /cdn\.jsdelivr\.net|cdn\.datatables\.net|cdnjs\.cloudflare\.com|fonts\.googleapis\.com|fonts\.gstatic\.com/i
    .test(url.hostname);

/* Estrategia:
   - /ajax/, /controllers/, *.php -> network-only (no cache)
   - CDNs -> stale-while-revalidate
   - Resto dentro del scope -> network-first
*/
self.addEventListener('fetch', (event) => {
  const req = event.request;
  if (req.method !== 'GET') return;

  const url = new URL(req.url);

  // Sólo manejamos peticiones dentro del CRM
  if (!isInsideScope(url)) return;

  // Dinámicos: jamás cachear
  if (neverCache(url)) {
    event.respondWith(fetch(req, { cache: 'no-store' }));
    return;
  }

  // CDNs: SWR
  if (isCdn(url)) {
    event.respondWith((async () => {
      const cache = await caches.open(RUNTIME);
      const cached = await cache.match(req);
      const networkPromise = fetch(req).then((res) => {
        if (res && res.status === 200) cache.put(req, res.clone());
        return res;
      }).catch(() => null);
      return cached || networkPromise || new Response('', { status: 504 });
    })());
    return;
  }

  // Resto del CRM: NETWORK FIRST
  event.respondWith((async () => {
    try {
      const fresh = await fetch(req, { cache: 'no-store' });
      if (req.method === 'GET' && fresh && fresh.status === 200) {
        const cache = await caches.open(RUNTIME);
        cache.put(req, fresh.clone());
      }
      return fresh;
    } catch (err) {
      const cached = await caches.match(req);
      if (cached) return cached;
      // opcional: return await caches.match(`${SCOPE}offline.html`);
      return new Response('Offline', { status: 503, statusText: 'Offline' });
    }
  })());
});
