// Service worker for WakeUpYourSoul.
//
// Strategy:
//   - On install: precache the core shell (HTML, CSS, JS, lang, icons).
//   - On fetch:   cache-first for precached items, network-first for everything
//                 else (so new music tracks load when online, fallback to cache
//                 when offline).
//   - On activate: delete any cache whose name doesn't match CACHE_VERSION.
//
// To force every client to refresh after a deploy, bump CACHE_VERSION below.
// The activate step will purge old caches and the page will start using new
// content within one reload (or two on iOS, where SW updates lag).

const CACHE_VERSION = "wuys-v249";
const CORE_ASSETS = [
  "./",
  "./index.html",
  "./styles.css?v=123",
  "./i18n.js?v=6",
  "./galaxy.js",
  "./emotions.js",
  "./app.js?v=10",
  "./music.js?v=2",
  "./music-list.js",
  "./library.js?v=25",
  "./stumble.js?v=1",
  "./onboarding.js?v=3",
  "./words/en.js?v=2",
  "./words/da.js?v=2",
  "./words/fr.js?v=2",
  "./words/es.js?v=2",
  "./words/ru.js?v=2",
  "./words/usages-en.js?v=2",
  "./words/usages-da.js?v=2",
  "./words/usages-fr.js?v=2",
  "./words/usages-es.js?v=2",
  "./words/usages-ru.js?v=2",
  "./wordwall.js?v=10",
  "./dictwall.js?v=1",
  "./words/dictwall-en.js?v=1",
  "./words/dictwall-da.js?v=1",
  "./words/dictwall-fr.js?v=1",
  "./words/dictwall-es.js?v=1",
  "./words/dictwall-ru.js?v=1",
  "./breath.js?v=1",
  "./moonwheels.js?v=1",
  "./heartfield.js?v=1",
  "./freqviz.js?v=1",
  "./starfield.js?v=1",
  "./inversion.js?v=1",
  "./silence.js?v=1",
  "./nowclock.js?v=1",
  "./sunrise.js?v=1",
  "./magic.js?v=1",
  "./discernment.js?v=10",
  "./geo.js?v=7",
  "./flags/us.svg",
  "./flags/gb.svg",
  "./flags/de.svg",
  "./flags/cn.svg",
  "./flags/sa.svg",
  "./flags/il.svg",
  "./flags/dk.svg",
  "./flags/ru.svg",
  "./flags/fr.svg",
  "./flags/it.svg",
  "./flags/es.svg",
  "./flags/be.svg",
  "./flags/ch.svg",
  "./flags/br.svg",
  "./flags/mx.svg",
  "./flags/in.svg",
  "./flags/jp.svg",
  "./flags/za.svg",
  "./flags/ua.svg",
  "./flags/by.svg",
  "./flags/ge.svg",
  "./flags/md.svg",
  "./flags/rs.svg",
  "./flags/hu.svg",
  "./flags/ir.svg",
  "./flags/sy.svg",
  "./flags/ve.svg",
  "./flags/kp.svg",
  "./flags/ml.svg",
  "./flags/iq.svg",
  "./flags/af.svg",
  "./flags/ye.svg",
  "./flags/ly.svg",
  "./flags/lb.svg",
  "./flags/tr.svg",
  "./flags/eg.svg",
  "./flags/kr.svg",
  "./flags/ph.svg",
  "./flags/ng.svg",
  "./flags/ar.svg",
  "./flags/co.svg",
  "./flags/ca.svg",
  "./flags/cu.svg",
  "./flags/cl.svg",
  "./flags/pl.svg",
  "./flags/gr.svg",
  "./flags/cz.svg",
  "./flags/sk.svg",
  "./flags/bg.svg",
  "./flags/cy.svg",
  "./flags/ie.svg",
  "./flags/nl.svg",
  "./flags/at.svg",
  "./flags/se.svg",
  "./flags/pk.svg",
  "./flags/id.svg",
  "./flags/th.svg",
  "./flags/my.svg",
  "./flags/sg.svg",
  "./flags/mm.svg",
  "./flags/lk.svg",
  "./flags/kh.svg",
  "./flags/cd.svg",
  "./flags/ke.svg",
  "./flags/sd.svg",
  "./flags/zw.svg",
  "./flags/ma.svg",
  "./flags/et.svg",
  "./flags/rw.svg",
  "./flags/au.svg",
  "./flags/nz.svg",
  "./world-map.svg?v=4",
  "./world-map-data.js?v=4",
  "./world-topo-data.js?v=1",
  "./flags-data.js?v=5",
  "./audio/quiz-with-teacups.mp3",
  "./witness.js?v=1",
  "./doorway.js?v=4",
  "./power-pyramid.js?v=1",
  "./media-pyramid.js?v=5",
  "./moneyclock.js?v=1",
  "./timeline.js?v=6",
  "./food-pyramid.js?v=1",
  "./pharma-pyramid.js?v=1",
  "./brainwaves.js?v=1",
  "./biofield.js?v=2",
  "./radar.js?v=4",
  "./lifeweeks.js?v=1",
  "./onion.js?v=1",
  "./emotionwheel.js?v=1",
  "./tactics.js?v=1",
  "./shadowmirror.js?v=1",
  "./warclock.js?v=1",
  "./plants.js?v=1",
  "./modalities.js?v=1",
  "./karpman.js?v=1",
  "./religiontree.js?v=1",
  "./ancestors.js?v=1",
  "./truthfilters.js?v=1",
  "./boundarymap.js?v=1",
  "./places.js?v=8",
  "./lang/en.js?v=62",
  "./lang/da.js?v=65",
  "./lang/fr.js?v=75",
  "./lang/es.js?v=44",
  "./lang/ru.js?v=47",
  "./icons/icon-192.png",
  "./icons/icon-512.png",
  "./icons/apple-touch-icon.png",
  "./icons/favicon-32.png",
  "./manifest.json"
];

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

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

self.addEventListener("fetch", (event) => {
  const req = event.request;
  if (req.method !== "GET") return;
  // Only handle same-origin requests so we don't break analytics/CDN calls.
  const url = new URL(req.url);
  if (url.origin !== self.location.origin) return;

  // Network-first for music files so users get fresh streams when online,
  // cache-first for everything else (the shell + lang + icons).
  const isMusic = url.pathname.includes("/music/");
  if (isMusic) {
    event.respondWith(
      fetch(req)
        .then((res) => {
          const copy = res.clone();
          caches.open(CACHE_VERSION).then((c) => c.put(req, copy));
          return res;
        })
        .catch(() => caches.match(req))
    );
    return;
  }

  event.respondWith(
    caches.match(req).then((cached) => {
      if (cached) return cached;
      return fetch(req).then((res) => {
        // Cache successful same-origin responses so subsequent visits work offline.
        if (res && res.ok) {
          const copy = res.clone();
          caches.open(CACHE_VERSION).then((c) => c.put(req, copy));
        }
        return res;
      }).catch(() => cached);
    })
  );
});
