<script lang="ts">
    import { untrack } from "svelte"
    import { metricCall } from "./config"
    import { location, mobileMenuOpen, currentContentEntry } from "./lib/store"
    import { _, locale } from "./lib/i18n/index"
    import LoadingBar from "./widgets/LoadingBar.svelte"
    import ToastContainer from "./widgets/ToastContainer.svelte"
    import DebugFooterInfo from "./widgets/DebugFooterInfo.svelte"
    import BlockRenderer from "./blocks/BlockRenderer.svelte"
    import NotFound from "./routes/NotFound.svelte"
    import { initScrollRestoration } from "./lib/navigation"
    import { getCachedEntries } from "./lib/api"
    import {
        SUPPORTED_LANGUAGES,
        LANGUAGE_LABELS,
        currentLanguage,
        localizedPath,
        getLanguageSwitchUrl,
        getBrowserLanguage,
        extractLanguageFromPath,
        DEFAULT_LANGUAGE,
        stripLanguageFromPath,
    } from "./lib/i18n"

    const CONTENT_MEDIA_LOOKUP = ["blocks.heroImage.image:medialib", "blocks.image:medialib"].join(",")
    const NAVIGATION_CONTENT_LOOKUP = "elements.page:content"
    const CONTENT_COMMENT_AGGREGATE = {
        collection: "comment",
        foreignField: "contentId",
        op: "count",
        filter: { active: true },
        as: "commentCount",
    }

    let { url = "" }: { url?: string } = $props()

    initScrollRestoration()

    // SSR: capture initial URL once (not reactive — url is only set server-side)
    untrack(() => {
        if (url) {
            let l = url.split("?")
            $location = {
                path: l[0],
                search: l.length > 1 ? l[1] : "",
                hash: "",
                push: false,
                pop: false,
            }
            const lang = extractLanguageFromPath(l[0]) || DEFAULT_LANGUAGE
            $locale = lang
        }
    })

    // Redirect root "/" to default language
    $effect(() => {
        if (typeof window !== "undefined" && $location.path === "/") {
            const lang = getBrowserLanguage()
            history.replaceState(null, "", `/${lang}/`)
        }
    })

    function focusMainContent(updateHash = false) {
        if (typeof window === "undefined") {
            return
        }

        const mainContent = document.getElementById("main-content")
        if (!(mainContent instanceof HTMLElement)) {
            return
        }

        if (updateHash) {
            window.history.pushState(window.history.state, "", "#main-content")
        }

        window.requestAnimationFrame(() => {
            mainContent.scrollIntoView({ block: "start" })
            mainContent.focus()
        })
    }

    function handleSkipToMainContent() {
        focusMainContent(true)
    }

    $effect(() => {
        if (typeof window === "undefined") {
            return
        }

        const handleHashChange = () => {
            if (window.location.hash === "#main-content") {
                focusMainContent()
            }
        }

        window.addEventListener("hashchange", handleHashChange)

        return () => {
            window.removeEventListener("hashchange", handleHashChange)
        }
    })

    // metrics
    let oldPath = $state("")
    $effect(() => {
        if (metricCall && typeof window !== "undefined" && oldPath !== $location.path) {
            const ref = oldPath
                ? document.location.protocol + "//" + document.location.host + oldPath
                : document.referrer
            oldPath = $location.path
            const fetchPath = oldPath + (oldPath.includes("?") ? "&" : "?") + "metrics"
            fetch(fetchPath, {
                headers: {
                    "x-ssr-skip": "204",
                    "x-ssr-ref": ref,
                    "x-ssr-res": `${window.innerWidth}x${window.innerHeight}`,
                    "cache-control": "no-cache, no-store, must-revalidate",
                },
            })
        }
    })

    // ── Content loading ──────────────────────────────────────────
    let contentEntry = $state<ContentEntry | null>(null)
    let headerNav = $state<NavigationEntry | null>(null)
    let footerNav = $state<NavigationEntry | null>(null)

    function resolveNavigationHref(item: NavigationElement): string {
        const resolvedPagePath = item._lookup?.page?.path || (item.page?.startsWith("/") ? item.page : "/")
        const localized = localizedPath(resolvedPagePath || "/")

        if (!item.hash) return localized

        const normalizedHash = item.hash.startsWith("#") ? item.hash : `#${item.hash}`
        return `${localized}${normalizedHash}`
    }
    let loading = $state(true)
    let notFound = $state(false)
    let commentList = $state<any[]>([])

    // Header scroll detection
    let scrolled = $state(false)
    if (typeof window !== "undefined") {
        window.addEventListener(
            "scroll",
            () => {
                scrolled = window.scrollY > 20
            },
            { passive: true }
        )
    }

    // Close mobile menu on navigation
    $effect(() => {
        $location.path // subscribe
        $mobileMenuOpen = false
    })

    async function loadContent(lang: string, routePath: string) {
        loading = true
        notFound = false
        contentEntry = null

        try {
            // Load navigation
            const [headerEntries, footerEntries] = await Promise.all([
                getCachedEntries<"navigation">("navigation", {
                    filter: { type: "header", language: lang },
                    sort: "sort",
                    limit: 1,
                    lookup: NAVIGATION_CONTENT_LOOKUP,
                }),
                getCachedEntries<"navigation">("navigation", {
                    filter: { type: "footer", language: lang },
                    sort: "sort",
                    limit: 1,
                    lookup: NAVIGATION_CONTENT_LOOKUP,
                }),
            ])
            headerNav = headerEntries[0] || null
            footerNav = footerEntries[0] || null

            // Load content for current path. Limit 1 so SSR tracks content:<id> instead of content:*.
            const contentEntries = await getCachedEntries<"content">("content", {
                filter: { lang, path: routePath, active: true },
                sort: "sort",
                limit: 1,
                aggregate: CONTENT_COMMENT_AGGREGATE,
                lookup: CONTENT_MEDIA_LOOKUP,
            })

            if (contentEntries.length > 0) {
                contentEntry = contentEntries[0]
                $currentContentEntry = {
                    translationKey: contentEntry.translationKey,
                    lang: contentEntry.lang,
                    path: contentEntry.path,
                }

                try {
                    commentList = await getCachedEntries("comment", {
                        filter: { active: true, contentId: contentEntry.id as string },
                        sort: "sort",
                    })
                } catch (e) {
                    console.error("Failed to load comment", e)
                    commentList = []
                }
            } else {
                notFound = true
            }
        } catch (err) {
            console.error("[App] Failed to load content:", err)
            notFound = true
        }

        loading = false
    }

    if (typeof window === "undefined") {
        ;(() => {
            const initialPath = url.split("?")[0] || "/"
            const initialLang = extractLanguageFromPath(initialPath) || DEFAULT_LANGUAGE
            const initialRoutePath = stripLanguageFromPath(initialPath) || "/"
            loadContent(initialLang, initialRoutePath)
        })()
    }

    // Re-load content when path or language changes
    $effect(() => {
        if (typeof window === "undefined") {
            return
        }

        const lang = $currentLanguage
        const routePath = stripLanguageFromPath($location.path)
        loadContent(lang, routePath || "/")
    })

    // Dynamic page title
    const SITE_NAME = "Tibi Starter"
    let pageTitle = $derived(
        contentEntry?.meta?.title
            ? `${contentEntry.meta.title} — ${SITE_NAME}`
            : contentEntry?.name
              ? `${contentEntry.name} — ${SITE_NAME}`
              : SITE_NAME
    )
</script>

<svelte:head>
    <title>{pageTitle}</title>
    {#if contentEntry?.meta?.description}
        <meta name="description" content={contentEntry.meta.description} />
    {/if}
    {#if contentEntry?.meta?.keywords?.length}
        <meta name="keywords" content={contentEntry.meta.keywords.join(", ")} />
    {/if}
</svelte:head>

<LoadingBar />
<ToastContainer />

<!-- ── Sticky Header with glassmorphism ──────────────────────── -->
<header
    class="fixed top-0 left-0 right-0 z-50 transition-all duration-300 {scrolled
        ? 'bg-white/80 backdrop-blur-lg shadow-sm'
        : 'bg-transparent'}"
>
    <button
        type="button"
        aria-controls="main-content"
        onclick={handleSkipToMainContent}
        class="sr-only absolute left-4 top-4 z-50 rounded bg-brand-600 px-4 py-2 text-sm font-semibold text-white focus:not-sr-only"
    >
        {$_("skipToMainContent")}
    </button>

    <div class="max-w-6xl mx-auto px-6 py-4 flex items-center justify-between">
        <!-- Logo -->
        <a
            href={localizedPath("/")}
            class="text-xl font-display font-bold transition-colors duration-300 {scrolled
                ? 'text-gray-900'
                : 'text-white'}"
        >
            {#if scrolled}<span class="text-gradient">Tibi</span>{:else}Tibi{/if} Starter
        </a>

        <!-- Desktop Nav -->
        <nav class="hidden md:flex items-center gap-8">
            {#if headerNav?.elements}
                {#each headerNav.elements as item}
                    <a
                        href={resolveNavigationHref(item)}
                        class="text-sm font-medium transition-colors duration-300 hover:text-brand-500 {scrolled
                            ? 'text-gray-700'
                            : 'text-white/90'}"
                    >
                        {item.name}
                    </a>
                {/each}
            {/if}

            <!-- Language Switcher -->
            <div
                class="flex items-center gap-1 border-l pl-6 transition-colors duration-300 {scrolled
                    ? 'border-gray-200'
                    : 'border-white/20'}"
            >
                {#each SUPPORTED_LANGUAGES as lang}
                    {#if $currentLanguage === lang}
                        <a
                            href={getLanguageSwitchUrl(lang)}
                            class="text-xs font-semibold uppercase px-2 py-1 rounded transition-all duration-300 bg-brand-600 text-white"
                        >
                            {lang}
                        </a>
                    {:else}
                        <a
                            href={getLanguageSwitchUrl(lang)}
                            class="text-xs font-semibold uppercase px-2 py-1 rounded transition-all duration-300 hover:text-brand-500 {scrolled
                                ? 'text-gray-500'
                                : 'text-white/50'}"
                        >
                            {lang}
                        </a>
                    {/if}
                {/each}
            </div>
        </nav>

        <!-- Mobile Hamburger -->
        <button
            class="md:hidden p-2 rounded-lg transition-colors {scrolled ? 'text-gray-900' : 'text-white'}"
            onclick={() => ($mobileMenuOpen = !$mobileMenuOpen)}
            aria-label="Menu"
            aria-expanded={$mobileMenuOpen}
        >
            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                {#if $mobileMenuOpen}
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"
                    ></path>
                {:else}
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"
                    ></path>
                {/if}
            </svg>
        </button>
    </div>

    <!-- Mobile Menu Overlay -->
    {#if $mobileMenuOpen}
        <div class="md:hidden bg-white border-t border-gray-100 shadow-lg">
            <nav class="max-w-6xl mx-auto px-6 py-4 space-y-3">
                {#if headerNav?.elements}
                    {#each headerNav.elements as item}
                        <a
                            href={resolveNavigationHref(item)}
                            class="block text-gray-700 text-lg font-medium hover:text-brand-600 py-2"
                        >
                            {item.name}
                        </a>
                    {/each}
                {/if}
                <div class="flex gap-2 pt-3 border-t border-gray-100">
                    {#each SUPPORTED_LANGUAGES as lang}
                        <a
                            href={getLanguageSwitchUrl(lang)}
                            class="text-xs font-semibold uppercase px-3 py-1.5 rounded {$currentLanguage === lang
                                ? 'bg-brand-600 text-white'
                                : 'text-gray-500 bg-gray-100'}"
                        >
                            {LANGUAGE_LABELS[lang]}
                        </a>
                    {/each}
                </div>
            </nav>
        </div>
    {/if}
</header>

<!-- ── Main Content ──────────────────────────────────────────── -->
<main id="main-content" tabindex="-1">
    {#if loading}
        <div class="min-h-screen flex items-center justify-center">
            <div class="w-8 h-8 border-4 border-brand-200 border-t-brand-600 rounded-full animate-spin"></div>
        </div>
    {:else if notFound}
        <div class="pt-16">
            <NotFound />
        </div>
    {:else if contentEntry?.blocks}
        <div class="page-enter">
            <BlockRenderer blocks={contentEntry.blocks} />

            {#if (contentEntry as any)?._aggregate?.commentCount !== undefined}
                <div class="max-w-6xl mx-auto px-6 py-8 border-t border-gray-100 my-12">
                    <h3 class="text-xl font-bold mb-6">
                        Kommentare ({(contentEntry as any)._aggregate.commentCount})
                    </h3>
                    {#if commentList && commentList.length > 0}
                        <div class="space-y-6">
                            {#each commentList as comment}
                                <div class="bg-gray-50 p-6 rounded-lg">
                                    <div class="font-bold text-gray-900 mb-2">{comment.author}</div>
                                    <p class="text-gray-700 whitespace-pre-wrap">{comment.message}</p>
                                </div>
                            {/each}
                        </div>
                    {:else}
                        <p class="text-gray-500 italic">Noch keine Kommentare vorhanden.</p>
                    {/if}
                </div>
            {/if}
        </div>
    {/if}
</main>

<!-- ── Footer ────────────────────────────────────────────────── -->
<footer class="bg-gray-900 text-gray-400">
    <div class="max-w-6xl mx-auto px-6 py-12">
        <div class="grid md:grid-cols-3 gap-8 mb-8">
            <!-- Brand -->
            <div>
                <h3 class="text-white font-display font-bold text-lg mb-3">Tibi Starter</h3>
                <p class="text-sm leading-relaxed">
                    {$_("footer.madeWith")}
                </p>
            </div>

            <!-- Footer Nav -->
            {#if footerNav?.elements}
                <div>
                    <h4 class="text-white font-semibold text-sm uppercase tracking-wider mb-3">Navigation</h4>
                    <ul class="space-y-2">
                        {#each footerNav.elements as item}
                            <li>
                                {#if item.external}
                                    <a
                                        href={item.externalUrl || "#"}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                        class="text-sm hover:text-white transition-colors"
                                    >
                                        {item.name} &nearr;
                                    </a>
                                {:else}
                                    <a
                                        href={resolveNavigationHref(item)}
                                        class="text-sm hover:text-white transition-colors"
                                    >
                                        {item.name}
                                    </a>
                                {/if}
                            </li>
                        {/each}
                    </ul>
                </div>
            {/if}

            <!-- Language -->
            <div>
                <h4 class="text-white font-semibold text-sm uppercase tracking-wider mb-3">{$_("language")}</h4>
                <div class="flex gap-2">
                    {#each SUPPORTED_LANGUAGES as lang}
                        <a
                            href={getLanguageSwitchUrl(lang)}
                            class="text-sm px-3 py-1.5 rounded transition-all {$currentLanguage === lang
                                ? 'bg-brand-600 text-white'
                                : 'hover:text-white'}"
                        >
                            {LANGUAGE_LABELS[lang]}
                        </a>
                    {/each}
                </div>
            </div>
        </div>

        <!-- Bottom bar -->
        <div class="border-t border-gray-800 pt-6 flex flex-col sm:flex-row justify-between items-center gap-4 text-sm">
            <p>&copy; {new Date().getFullYear()} Tibi Svelte Starter. {$_("footer.rights")}</p>
            <DebugFooterInfo />
        </div>
    </div>
</footer>
