// @ts-check

const version = "v1";

self.addEventListener("install", (_event) => {
  const event = /** @type {any} */ (_event);

  event.waitUntil(
    caches.open(version).then((cache) => {
      return cache.addAll([
        "/",
        "/index.html",
        "/script.js",
        "/packages/solid-signals/2024-04-17/script.js",
        "/packages/ufuzzy/v1.0.14/script.js",
        "/packages/lean-qr/v2.3.4/script.js",
        "/packages/lightweight-charts/v4.2.0/script.js",
        "/assets/fonts/satoshi/2024-09/font.var.woff2",
      ]);
    })
  );

  // @ts-ignore
  self.skipWaiting();
});

/**
 * @param {Response | undefined} cachedResponse
 * @param {Response | undefined} badResponse
 */
function pickCorrectResponse(cachedResponse, badResponse) {
  if (cachedResponse) {
    return cachedResponse;
  } else {
    return caches
      .match("/")
      .then((response) => {
        return response ?? badResponse;
      })
      .catch(() => {
        return badResponse;
      });
  }
}

self.addEventListener("fetch", (_event) => {
  const event = /** @type {any} */ (_event);

  /** @type {Request} */
  const request = event.request;
  const { url, method } = request;

  console.log(`service-worker: fetching: ${url}`);

  event.respondWith(
    caches.match(request).then((cachedResponse) => {
      return fetch(request)
        .then((response) => {
          const { status } = response;

          // @ts-ignore
          if (method !== "GET" || url.includes("/api/")) {
            return response;
          }

          return caches.open(version).then((cache) => {
            if (status === 200 || status === 304) {
              if (status === 200) {
                cache.put(request, response.clone());
              }
              return response;
            } else {
              return pickCorrectResponse(cachedResponse, response);
            }
          });
        })
        .catch(() => {
          return pickCorrectResponse(cachedResponse, undefined);
        });
    })
  );
});
