<script lang="ts">
	import { onMount } from "svelte";
	import { goto } from "$app/navigation";
	import { page } from "$app/state";
	import { i18n } from "$lib/i18n/index.svelte";
	import { session } from "$lib/session-store.svelte";
	import { eventStream } from "../api/events.svelte";
	import { loadCore } from "../platform/core/index";
	import { GATEWAY_RESPONSE_PUBLIC_KEY } from "$lib/env";
	import ToastHost from "$lib/toast-host.svelte";

	let { children } = $props();

	// `streamSessionId` records the device session id the event stream
	// is currently bound to. The `$effect` below uses it to detect a
	// re-login (different session id while still authenticated) and
	// restart the stream against the fresh credentials.
	let streamSessionId: string | null = null;

	onMount(() => {
		void session.init();
		return () => {
			eventStream.stop();
			streamSessionId = null;
		};
	});

	$effect(() => {
		if (
			session.status === "authenticated" &&
			session.keypair !== null &&
			session.deviceSessionId !== null &&
			GATEWAY_RESPONSE_PUBLIC_KEY.length > 0
		) {
			const keypair = session.keypair;
			const deviceSessionId = session.deviceSessionId;
			if (streamSessionId !== deviceSessionId) {
				if (streamSessionId !== null) {
					eventStream.stop();
				}
				streamSessionId = deviceSessionId;
				void (async (): Promise<void> => {
					try {
						const core = await loadCore();
						// Bail out if the session flipped away from this id
						// while we were loading core (logout, re-login).
						if (
							session.deviceSessionId !== deviceSessionId ||
							session.status !== "authenticated"
						) {
							return;
						}
						eventStream.start({
							core,
							keypair,
							deviceSessionId,
							gatewayResponsePublicKey: GATEWAY_RESPONSE_PUBLIC_KEY,
						});
					} catch (err) {
						console.info("layout: failed to start event stream", err);
					}
				})();
			}
		} else if (streamSessionId !== null) {
			eventStream.stop();
			streamSessionId = null;
		}

		const pathname = page.url.pathname;
		// Debug-only routes under /__debug/* run their own bootstrap
		// path against the storage primitives and must bypass the
		// auth guard so Phase 6's Playwright spec can drive the
		// keystore directly.
		if (pathname.startsWith("/__debug/")) {
			return;
		}
		if (session.status === "anonymous" && pathname !== "/login") {
			void goto("/login", { replaceState: true });
		} else if (session.status === "authenticated" && pathname === "/login") {
			void goto("/lobby", { replaceState: true });
		}
	});
</script>

{#if session.status === "loading"}
	<main class="status">
		<p>{i18n.t("common.loading")}</p>
	</main>
{:else if session.status === "unsupported"}
	<main class="status">
		<h1>{i18n.t("common.browser_not_supported_title")}</h1>
		<p>{i18n.t("common.browser_not_supported_body")}</p>
	</main>
{:else}
	{@render children()}
{/if}

<ToastHost />

<style>
	.status {
		padding: 2rem;
		font-family: system-ui, sans-serif;
	}
</style>
