<script lang="ts">
    import { goto } from "$app/navigation";
    import {
        checkLinkValidityFresh,
        mapLinkErrorToSessionEndReason,
    } from "$lib/domains/link/client";
    import { endLinkSessionSC } from "$lib/domains/link/link.remote";
    import { onMount } from "svelte";

    const POLL_INTERVAL_MS = 2000;
    const MAX_CONSECUTIVE_POLL_ERRORS = 3;

    let state: "loading" | "ready" = "loading";
    let token = "";
    let streamUrl: string | null = null;
    let statusText = "Connecting to your active session...";

    onMount(() => {
        let disposed = false;
        let hasEnded = false;
        let timer: ReturnType<typeof setInterval> | null = null;
        let inFlight = false;
        let consecutivePollErrors = 0;

        const endSession = async (reason: string) => {
            if (disposed || hasEnded) return;
            hasEnded = true;

            if (timer) clearInterval(timer);
            streamUrl = null;

            if (token) {
                try {
                    await endLinkSessionSC({ token });
                } catch {
                    // Best-effort cleanup; user ejection should proceed regardless.
                }
            }

            await goto(`/session-ended?reason=${encodeURIComponent(reason)}`, {
                replaceState: true,
            });
        };

        const pollValidity = async () => {
            if (disposed || inFlight || !token) return;
            inFlight = true;

            try {
                const result = await checkLinkValidityFresh(token);

                if (disposed) return;

                if (result?.error || !result?.data) {
                    await endSession(
                        mapLinkErrorToSessionEndReason(result?.error),
                    );
                    return;
                }

                consecutivePollErrors = 0;

                if (result.data.link.status !== "active") {
                    await endSession("expired");
                    return;
                }

                const nextStreamUrl = result.data.device?.streamUrl;
                if (typeof nextStreamUrl === "string" && nextStreamUrl.length > 0) {
                    streamUrl = nextStreamUrl;
                }
            } catch {
                consecutivePollErrors += 1;
                if (consecutivePollErrors >= MAX_CONSECUTIVE_POLL_ERRORS) {
                    await endSession("network");
                }
            } finally {
                inFlight = false;
            }
        };

        const start = async () => {
            token =
                new URLSearchParams(window.location.search)
                    .get("token")
                    ?.trim() || "";

            if (!token) {
                await goto("/unauthorized?reason=missing_token", {
                    replaceState: true,
                });
                return;
            }

            const initial = await checkLinkValidityFresh(token);
            if (initial?.error || !initial?.data) {
                await endSession(mapLinkErrorToSessionEndReason(initial?.error));
                return;
            }

            streamUrl = initial.data.device?.streamUrl ?? null;
            state = "ready";
            statusText = "Session active";

            await pollValidity();
            timer = setInterval(() => {
                void pollValidity();
            }, POLL_INTERVAL_MS);
        };

        void start();

        return () => {
            disposed = true;
            if (timer) clearInterval(timer);
            if (!hasEnded && token) {
                void endLinkSessionSC({ token });
            }
        };
    });
</script>

<main class="bg-background text-foreground min-h-dvh">
    {#if state === "loading"}
        <section class="flex min-h-dvh items-center justify-center px-6">
            <div
                class="w-full max-w-sm rounded-xl border border-border bg-card p-6 text-center"
            >
                <h1 class="text-xl font-semibold">Loading session</h1>
                <p class="mt-3 text-sm text-muted-foreground">
                    {statusText}
                </p>
            </div>
        </section>
    {:else}
        <section class="bg-black relative h-dvh min-h-dvh overflow-hidden">
            <div
                class="pointer-events-none absolute inset-x-0 top-0 z-10 flex justify-center px-3 pt-2"
            >
                <div class="rounded-full bg-black/55 px-3 py-1 text-xs text-white/90">
                    {statusText}
                </div>
            </div>
            <div class="h-full w-full">
                {#if streamUrl}
                    <iframe
                        src={streamUrl}
                        title="Android session"
                        class="block h-full w-full border-0 bg-black"
                        allow="autoplay; fullscreen"
                        referrerpolicy="no-referrer"
                    ></iframe>
                {:else}
                    <div class="flex h-full items-center justify-center">
                        <p class="text-sm text-white/70">Waiting for stream...</p>
                    </div>
                {/if}
            </div>
        </section>
    {/if}
</main>
