/*
  sw.js — Save Pet Service Worker
  ---------------------------------------------------------------
  Precaches the entire app shell on install so the game is fully
  playable offline after the first successful load. Cache-first
  for static assets (fast + offline-safe), network-first with a
  cache fallback for navigations, and an offline.html fallback if
  absolutely nothing is cached yet.

  TO SHIP AN UPDATE: bump CACHE_VERSION below. Clients already
  running the game will detect the new service worker, and main.js
  will show a "New version available" banner (see pwa.js) instead
  of silently swapping files under an active player.
*/
const CACHE_VERSION = "savepet-v1.0.1";
const RUNTIME_CACHE = "savepet-runtime";

const PRECACHE_URLS = [
  "./",
  "./index.html",
  "./offline.html",
  "./css/style.min.css",
  "./js/config.js",
  "./js/utils.js",
  "./js/levels.js",
  "./js/entities.js",
  "./js/particles.js",
  "./js/audio.js",
  "./js/achievements.js",
  "./js/game.js",
  "./js/ads.js",
  "./js/analytics.js",
  "./js/ui.js",
  "./js/pwa.js",
  "./js/main.js",
  "./manifest.json",
  "./assets/icons/icon-72.png",
  "./assets/icons/icon-96.png",
  "./assets/icons/icon-128.png",
  "./assets/icons/icon-144.png",
  "./assets/icons/icon-152.png",
  "./assets/icons/icon-192.png",
  "./assets/icons/icon-384.png",
  "./assets/icons/icon-512.png",
  "./assets/icons/icon-maskable-512.png",
  "./assets/icons/apple-touch-icon.png",
  "./assets/icons/favicon-32.png",
  "./assets/icons/favicon-16.png",
  "./favicon.ico",
  "./assets/audio/sfx_click.wav",
  "./assets/audio/sfx_pop.wav",
  "./assets/audio/sfx_pop_tank.wav",
  "./assets/audio/sfx_hit.wav",
  "./assets/audio/sfx_coin.wav",
  "./assets/audio/sfx_star.wav",
  "./assets/audio/sfx_win.wav",
  "./assets/audio/sfx_lose.wav",
  "./assets/audio/sfx_whoosh.wav",
  "./assets/audio/sfx_achievement.wav",
  "./assets/audio/sfx_tick.wav",
  "./assets/audio/sfx_unlock.wav",
  "./assets/audio/sfx_error.wav",
  "./assets/audio/music_menu.mp3",
  "./assets/audio/music_menu.ogg",
  "./assets/audio/music_game.mp3",
  "./assets/audio/music_game.ogg"
];

self.addEventListener("install", function (event) {
  event.waitUntil(
    caches.open(CACHE_VERSION)
      .then(function (cache) { return cache.addAll(PRECACHE_URLS); })
      .then(function () { return self.skipWaiting(); })
      .catch(function (err) { console.warn("[SavePet SW] precache failed", err); })
  );
});

self.addEventListener("activate", function (event) {
  event.waitUntil(
    caches.keys().then(function (keys) {
      return Promise.all(keys.filter(function (k) { return k !== CACHE_VERSION && k !== RUNTIME_CACHE; })
        .map(function (k) { return caches.delete(k); }));
    }).then(function () { return self.clients.claim(); })
  );
});

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

self.addEventListener("fetch", function (event) {
  const req = event.request;
  if (req.method !== "GET") return;

  let url;
  try { url = new URL(req.url); } catch (e) { return; }
  if (url.origin !== self.location.origin) return; // never intercept ad/analytics/cross-origin calls

  if (req.mode === "navigate") {
    event.respondWith(
      fetch(req).then(function (res) {
        const copy = res.clone();
        caches.open(RUNTIME_CACHE).then(function (cache) { cache.put(req, copy); });
        return res;
      }).catch(function () {
        return caches.match(req).then(function (cached) { return cached || caches.match("./offline.html"); });
      })
    );
    return;
  }

  event.respondWith(
    caches.match(req).then(function (cached) {
      if (cached) return cached;
      return fetch(req).then(function (res) {
        if (res && res.status === 200) {
          const copy = res.clone();
          caches.open(RUNTIME_CACHE).then(function (cache) { cache.put(req, copy); });
        }
        return res;
      }).catch(function () {
        return new Response("", { status: 408, statusText: "Offline and not cached" });
      });
    })
  );
});
