<script lang="ts">
	import '../app.css';
	import { onMount } from 'svelte';
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { dev } from '$app/environment';
	import { authState, checkAuth, consumeKeyParam } from '$lib/auth.svelte';
	import { precacheAll } from '$lib/precache.svelte';

	let { children } = $props();
	let booted = $state(false);

	onMount(async () => {
		if ('serviceWorker' in navigator) {
			if (dev) {
				const regs = await navigator.serviceWorker.getRegistrations();
				await Promise.all(regs.map((r) => r.unregister()));
				const keys = await caches.keys();
				await Promise.all(keys.map((k) => caches.delete(k)));
			} else {
				navigator.serviceWorker
					.register('/service-worker.js', { type: 'module' })
					.catch((err) => console.warn('sw register failed:', err));
			}
		}

		const keyResult = await consumeKeyParam();
		if (keyResult !== 'success') await checkAuth();

		const path = $page.url.pathname;
		if (authState() === 'signed-out' && path !== '/login') {
			const params = new URLSearchParams({ next: path });
			if (keyResult === 'failed') params.set('error', 'qr');
			await goto('/login?' + params.toString(), { replaceState: true });
		}

		// Production-only: kick off audio/image bulk precache once authenticated.
		// SW does the work; failures non-fatal.
		if (!dev && authState() === 'signed-in') {
			precacheAll().catch(() => undefined);
		}

		booted = true;
	});
</script>

{#if booted}
	{@render children()}
{:else}
	<div class="splash">
		<div class="ring" aria-hidden="true"></div>
	</div>
{/if}

<style>
	.splash {
		flex: 1;
		display: grid;
		place-items: center;
	}
	.ring {
		width: 32px;
		height: 32px;
		border-radius: 50%;
		border: 2px solid var(--rule);
		border-top-color: var(--accent);
		animation: spin 0.8s linear infinite;
	}
	@keyframes spin {
		to { transform: rotate(360deg); }
	}
</style>
