// A server-rendered public page.
//
// The SPA under /js/* is client-only: the browser gets an empty #app and Solid fills
// it. That is fine for a docs section behind a click, and wrong for anything a search
// engine or a slow phone has to read.
//
// This page takes the other route. The bundler renders it at BUILD time — the real
// component, executed in goja against a DOM shim — and bakes the resulting HTML into
// a Go registry (internal/handlers/public_pages.gen.go). The server ships that HTML
// directly, so the page is complete before any JavaScript loads. The client bundle
// then re-renders the same component over the top and it becomes interactive.
//
// serverData() is what makes it more than a static file: the handler can inject data
// for a request, and the SAME component renders it — on the server at request time,
// and again in the browser after takeover, from the same inlined JSON. No refetch, no
// flash of a skeleton.

import { serverData } from "@kjol/ssr/serverData.ts";

interface BuildInfo {
    renderedAt: string;
    stage: string;
}

export function Ssr() {
    // Read inside the reactive body, never captured at module load — the value has to
    // be observed at render time, and there are three different render times.
    const info = () => serverData<BuildInfo>();

    return (
        <div class="page-ssr mx-auto max-w-2xl px-4 py-14">
            <p class="text-ss font-semibold uppercase tracking-widest text-primary">Kjøl JS Web</p>
            <h1 class="mt-2 text-3xl font-semibold tracking-tight text-ink">
                This page was rendered by Go
            </h1>

            <p class="mt-4 leading-relaxed text-ink-soft">
                Not by a Node renderer, and not in your browser. A Go program executed this Solid component
                in an embedded JavaScript engine, serialized the DOM it produced, and compiled the result
                into the server binary. View source: the markup arrived complete.
            </p>

            {/* No data → the skeleton. This is exactly what the build-time bake sees, because
                the bake injects nothing; it is also what a crawler sees. With data injected at
                request time, the same three lines render the real values instead. */}
            {!info() ? (
                <div class="mt-8 animate-pulse rounded-default border border-line p-5">
                    <div class="h-3 w-40 rounded bg-surface-strong" />
                    <div class="mt-3 h-3 w-64 rounded bg-surface-raised" />
                </div>
            ) : (
                <dl class="mt-8 rounded-default border border-line p-5">
                    <div class="flex justify-between text-sm">
                        <dt class="text-ink-muted">rendered at</dt>
                        <dd class="font-mono text-ink">{info()!.renderedAt}</dd>
                    </div>
                    <div class="mt-2 flex justify-between text-sm">
                        <dt class="text-ink-muted">stage</dt>
                        <dd class="font-mono text-ink">{info()!.stage}</dd>
                    </div>
                </dl>
            )}

            <p class="mt-8 leading-relaxed text-ink-soft">
                The skeleton above is the honest default. The bake runs with no data, so a component that
                cannot render without data cannot be baked — which is a useful constraint to discover at build
                time rather than in production.
            </p>

            <p class="mt-8 text-sm text-ink-muted">
                <a href="/js" class="text-primary underline underline-offset-4">
                    Back to Kjøl JS Web
                </a>
            </p>
        </div>
    );
}
