/// <reference types="@sveltejs/kit" />
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />

import { build, files, version } from '$service-worker';

const sw = self as unknown as ServiceWorkerGlobalScope;

const APP_SHELL = `jwe-shell-${version}`; // immuable, recréé à chaque build
const PHOTOS = 'jwe-photos'; // stale-while-revalidate

const ASSETS = [...build, ...files];

sw.addEventListener('install', (event) => {
	event.waitUntil(caches.open(APP_SHELL).then((cache) => cache.addAll(ASSETS)));
});

sw.addEventListener('activate', (event) => {
	event.waitUntil(
		caches.keys().then((keys) =>
			Promise.all(
				keys
					.filter((key) => key !== APP_SHELL && key !== PHOTOS)
					.map((key) => caches.delete(key))
			)
		)
	);
});

function isPhoto(url: URL): boolean {
	return (
		url.hostname === 'upload.wikimedia.org' ||
		(url.hostname === 'commons.wikimedia.org' && url.pathname.startsWith('/wiki/Special:FilePath'))
	);
}

sw.addEventListener('fetch', (event) => {
	const url = new URL(event.request.url);
	if (event.request.method !== 'GET') return;

	// App shell : cache d'abord
	if (ASSETS.includes(url.pathname)) {
		event.respondWith(caches.match(event.request).then((r) => r ?? fetch(event.request)));
		return;
	}

	// Photos Wikimedia : stale-while-revalidate
	if (isPhoto(url)) {
		event.respondWith(
			caches.open(PHOTOS).then(async (cache) => {
				const cached = await cache.match(event.request);
				const frais = fetch(event.request)
					.then((res) => {
						if (res.ok) void cache.put(event.request, res.clone());
						return res;
					})
					.catch(() => cached as Response);
				return cached ?? frais;
			})
		);
		return;
	}
});
