// Service worker — coquille hors-ligne.
//
// PÉRIMÈTRE ASSUMÉ : ce worker rend l'application *installable* et affiche une page
// « hors connexion » lisible quand le réseau tombe (fréquent en salle DC). Il ne fait
// PAS de synchronisation d'écriture hors-ligne : mettre en file des mutations puis les
// rejouer soulève des conflits (deux techniciens sur la même intervention, numérotation,
// transitions de statut) qui exigent une stratégie de résolution explicite.
//
// Règles :
//  - Navigations : réseau d'abord, repli sur la page hors-ligne en cache.
//  - Ressources statiques (/_next/static, images) : cache d'abord (immuables, hashées).
//  - API / tRPC : JAMAIS de cache — on ne veut pas servir de données métier périmées.

const CACHE = "cyceo-v1";
const HORS_LIGNE = "/hors-ligne.html";
const PRECHARGE = [HORS_LIGNE, "/logo.png", "/manifest.webmanifest"];

self.addEventListener("install", (e) => {
  e.waitUntil(caches.open(CACHE).then((c) => c.addAll(PRECHARGE)).then(() => self.skipWaiting()));
});

self.addEventListener("activate", (e) => {
  e.waitUntil(
    caches
      .keys()
      .then((cles) => Promise.all(cles.filter((k) => k !== CACHE).map((k) => caches.delete(k))))
      .then(() => self.clients.claim()),
  );
});

self.addEventListener("fetch", (e) => {
  const req = e.request;
  if (req.method !== "GET") return; // les mutations passent toujours par le réseau

  const url = new URL(req.url);
  if (url.origin !== self.location.origin) return;
  // Données métier et authentification : jamais servies depuis le cache.
  if (url.pathname.startsWith("/api/")) return;

  // Navigation : réseau d'abord, sinon page hors-ligne.
  if (req.mode === "navigate") {
    e.respondWith(fetch(req).catch(() => caches.match(HORS_LIGNE)));
    return;
  }

  // Statiques hashés : cache d'abord, puis mise en cache à la volée.
  if (url.pathname.startsWith("/_next/static") || /\.(png|jpg|jpeg|svg|webp|ico|woff2?)$/.test(url.pathname)) {
    e.respondWith(
      caches.match(req).then(
        (hit) =>
          hit ??
          fetch(req).then((rep) => {
            if (rep.ok) {
              const clone = rep.clone();
              caches.open(CACHE).then((c) => c.put(req, clone));
            }
            return rep;
          }),
      ),
    );
  }
});
