const CACHE_PREFIX = "who-need-help-static-"
const CACHE = `${CACHE_PREFIX}v4`
const OFFLINE_URL = "/offline.html"
const SHELL = [
  OFFLINE_URL,
  "/manifest.webmanifest",
  "/assets/css/app.css",
  "/assets/js/app.js",
  "/images/logo.svg",
  "/images/pwa-192.png",
  "/images/pwa-512.png",
  "/images/pwa-maskable-512.png"
]

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

self.addEventListener("activate", event => {
  event.waitUntil(
    caches
      .keys()
      .then(keys =>
        Promise.all(
          keys
            .filter(key => key.startsWith(CACHE_PREFIX) && key !== CACHE)
            .map(key => caches.delete(key))
        )
      )
      .then(() => self.clients.claim())
  )
})

self.addEventListener("fetch", event => {
  const url = new URL(event.request.url)
  const sameOrigin = url.origin === self.location.origin
  const isStatic =
    sameOrigin &&
    (url.pathname.startsWith("/assets/") || url.pathname.startsWith("/images/"))

  if (event.request.method !== "GET" || !sameOrigin) return

  if (event.request.mode === "navigate") {
    event.respondWith(
      fetch(event.request).catch(async () => {
        const fallback = await caches.match(OFFLINE_URL)
        return fallback || Response.error()
      })
    )
    return
  }

  if (isStatic) {
    event.respondWith(cacheFirst(event))
  }
})

async function cacheFirst(event) {
  const cached = await caches.match(event.request)
  if (cached) return cached

  const response = await fetch(event.request)

  if (response.ok) {
    const copy = response.clone()
    event.waitUntil(caches.open(CACHE).then(cache => cache.put(event.request, copy)))
  }

  return response
}
