<!-- [DEF:ProtectedRoute:Component] -->
<!--
@TIER: STANDARD
@SEMANTICS: auth, guard, route, protection, permission
@PURPOSE:   Wraps content to ensure only authenticated and authorized users can access it.
@LAYER:     Component
@RELATION:  USES -> authStore
@RELATION:  CALLS -> goto
@RELATION:  DEPENDS_ON -> frontend.src.lib.auth.permissions.hasPermission

@INVARIANT: Redirects to /login if user is not authenticated and to fallback route when permission is denied.
@UX_STATE: Loading -> Shows spinner while session/permission check is in progress.
@UX_STATE: Authorized -> Renders protected slot content.
@UX_RECOVERY: Invalid token triggers logout and redirect to /login.
-->

<script lang="ts">
    import { onMount } from "svelte";
    import { auth } from "../../lib/auth/store";
    import { api } from "../../lib/api";
    import { goto } from "$app/navigation";
    import { hasPermission } from "$lib/auth/permissions.js";

    export let requiredPermission: string | null = null;
    export let fallbackPath: string = "/profile";

    let hasRouteAccess = false;
    let isCheckingAccess = true;

    // [DEF:verifySessionAndAccess:Function]
    /**
     * @purpose Validates active session and optional route permission before rendering protected slot.
     * @pre Auth store is initialized.
     * @post hasRouteAccess is true only when session and permission checks pass.
     * @side_effect May update auth store, perform redirect, and fetch current user.
     */
    async function verifySessionAndAccess(): Promise<void> {
        isCheckingAccess = true;
        try {
            if (!$auth.token) {
                auth.setLoading(false);
                await goto("/login");
                return;
            }

            let currentUser = $auth.user;
            if (!currentUser) {
                auth.setLoading(true);
                try {
                    const user = await api.fetchApi("/auth/me");
                    auth.setUser(user);
                    currentUser = user;
                } catch (error) {
                    console.error("[ProtectedRoute][COHERENCE:FAILED] Failed to verify session:", error);
                    auth.logout();
                    await goto("/login");
                    return;
                } finally {
                    auth.setLoading(false);
                }
            }

            if (!currentUser) {
                auth.logout();
                await goto("/login");
                return;
            }

            if (requiredPermission && !hasPermission(currentUser, requiredPermission, "READ")) {
                console.warn(
                    `[ProtectedRoute][REFLECT] Permission denied for ${requiredPermission}, redirecting to ${fallbackPath}`,
                );
                hasRouteAccess = false;
                await goto(fallbackPath);
                return;
            }

            hasRouteAccess = true;
        } finally {
            isCheckingAccess = false;
        }
    }
    // [/DEF:verifySessionAndAccess:Function]

    onMount(() => {
        void verifySessionAndAccess();
    });
</script>

{#if $auth.loading || isCheckingAccess}
    <div class="flex items-center justify-center min-h-screen">
        <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
    </div>
{:else if $auth.isAuthenticated && hasRouteAccess}
    <slot />
{/if}

<!-- [/DEF:ProtectedRoute:Component] -->