const CACHE = "tym-v1.1.0-914619f3";
const ASSETS = [
  "/",
  "/index.html",
  "/assets/api.89363e2a.js",
  "/assets/app.58f3e95c.js",
  "/assets/auth.a6c28cdb.js",
  "/assets/badge.30848c28.js",
  "/assets/offlineQueue.0a9bbfdd.js",
  "/assets/pwa.b6a6d909.js",
  "/assets/styles.993b74f1.css",
  "/assets/ui.47fc1625.js",
  "/assets/updates.57073981.js",
  "/manifest.json",
  "/icon.png",
  "/icon-72x72.png",
  "/icon-192x192.png",
  "/icon-512x512.png",
  "/version.json"
];

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

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

self.addEventListener("message", (event) => {
  if (event.data?.type === "SKIP_WAITING") self.skipWaiting();
});

function isHashedAsset(pathname) {
  return pathname.startsWith("/assets/");
}

async function networkOnly(request) {
  return fetch(request);
}

async function networkFirst(request, fallbackPath) {
  try {
    const response = await fetch(request);
    if (response.ok) return response;
  } catch {
    /* offline */
  }
  const cached = await caches.match(request);
  if (cached) return cached;
  if (fallbackPath) {
    const fallback = await caches.match(fallbackPath);
    if (fallback) return fallback;
  }
  return new Response("Offline", { status: 503, statusText: "Offline" });
}

async function cacheFirst(request) {
  const cached = await caches.match(request);
  if (cached) return cached;
  const response = await fetch(request);
  if (response.ok) {
    const cache = await caches.open(CACHE);
    await cache.put(request, response.clone());
  }
  return response;
}

self.addEventListener("fetch", (event) => {
  const { request } = event;
  if (request.method !== "GET") return;
  const url = new URL(request.url);
  if (url.origin !== self.location.origin) return;

  // sw.js: never intercept — browser must revalidate with server
  if (url.pathname === "/sw.js") return;

  if (url.pathname.startsWith("/api/")) {
    event.respondWith(
      fetch(request).catch(() => new Response(JSON.stringify({ offline: true }), {
        status: 503,
        headers: { "Content-Type": "application/json" },
      }))
    );
    return;
  }

  if (url.pathname === "/version.json") {
    event.respondWith(networkOnly(request));
    return;
  }

  if (request.mode === "navigate") {
    event.respondWith(networkFirst(request, "/index.html"));
    return;
  }

  if (isHashedAsset(url.pathname)) {
    event.respondWith(cacheFirst(request));
    return;
  }

  if (url.pathname === "/index.html" || url.pathname === "/manifest.json") {
    event.respondWith(networkFirst(request));
    return;
  }

  // Icons and other static root files
  event.respondWith(networkFirst(request));
});

self.addEventListener("push", (event) => {
  if (!event.data) return;
  let data = {};
  try { data = event.data.json(); } catch { data = { body: event.data.text() }; }

  const options = {
    body: data.body || "Med-Time!",
    icon: "/icon-192x192.png",
    badge: "/icon-72x72.png",
    silent: data.silent !== false,
    tag: data.tag || "med-reminder",
    renotify: true,
    data: { slot_id: data.slot_id },
    actions: [
      { action: "take", title: "Genommen ✓" },
      { action: "snooze15", title: "+15 Min" },
      { action: "snooze30", title: "+30 Min" },
    ],
  };

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

self.addEventListener("notificationclick", (event) => {
  event.notification.close();
  const slotId = event.notification.data?.slot_id;
  const action = event.action;

  if (action === "take" && slotId) {
    event.waitUntil(self.clients.openWindow(`/?action=take&slot=${slotId}`));
    return;
  }

  if ((action === "snooze15" || action === "snooze30") && slotId) {
    const minutes = action === "snooze15" ? 15 : 30;
    event.waitUntil(self.clients.openWindow(`/?action=snooze&slot=${slotId}&minutes=${minutes}`));
    return;
  }

  event.waitUntil(self.clients.openWindow("/"));
});

self.addEventListener("sync", (event) => {
  if (event.tag === "sync-logs") {
    event.waitUntil(
      self.clients.matchAll().then((list) => {
        list.forEach((c) => c.postMessage({ type: "SYNC_QUEUE" }));
      })
    );
  }
});
