// IMP-56: Service Worker — オフラインフォールバック + 静的ファイルキャッシュ
// IMP-67: キャッシュキーを v3 に更新 (IMP-63 ダークモードCSS, IMP-70 スピナーCSS対応)
const CACHE_NAME = "municipal-app-v4";
const STATIC_ASSETS = ["/", "/index.html", "/app.js", "/styles.css", "/manifest.json"];

self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => cache.addAll(STATIC_ASSETS)).then(() => self.skipWaiting())
  );
});

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

self.addEventListener("fetch", (event) => {
  const { request } = event;
  const url = new URL(request.url);

  // APIリクエストはネットワーク優先 (キャッシュしない)
  if (url.pathname.startsWith("/api/")) {
    event.respondWith(fetch(request).catch(() => new Response(JSON.stringify({ error: "オフライン中です" }), { status: 503, headers: { "content-type": "application/json" } })));
    return;
  }

  // 静的ファイル: キャッシュ優先 (Cache First)
  event.respondWith(
    caches.match(request).then((cached) => {
      if (cached) return cached;
      return fetch(request).then((res) => {
        if (res.ok && request.method === "GET") {
          caches.open(CACHE_NAME).then((cache) => cache.put(request, res.clone()));
        }
        return res;
      }).catch(() => caches.match("/index.html"));
    })
  );
});
