// /js — what the JS layer is, and how it is built.

import { For } from "solid-js";
import { useNavigate } from "@solidjs/router";
import { Card, CardHeader } from "@ui/Cards";
import { AlertBlue } from "@ui/Alerts";
import { CodeBox } from "@ui/General";
import { Icon } from "@ui/Icons";
import { COMPONENT_GROUPS } from "../componentGroups.ts";

export function Overview() {
    const navigate = useNavigate();

    return (
        <div>
            <p class="text-xs font-semibold uppercase tracking-widest text-primary">Kjøl JS Web</p>
            <h1 class="mt-2 text-3xl font-semibold tracking-tight text-ink">
                A Solid kit, built by a Go toolchain
            </h1>

            <p class="mt-4 leading-relaxed text-ink-soft">
                This layer is the original one: a Solid.js component kit — forms, tables, modals, menus,
                tooltips, charts — that the applications shared before any of it was rewritten in Go. It is
                still what those applications run.
            </p>
            <p class="mt-3 leading-relaxed text-ink-soft">
                What is unusual is the build. There is no Node, no Vite, no Babel, and no{" "}
                <code class="rounded bg-surface-raised px-1 py-0.5 font-mono text-[13px]">node_modules</code>.
                The TSX is compiled to Solid's runtime calls by a Go program, the CSS by a Go implementation
                of Tailwind v4, and the whole thing is bundled by esbuild's Go API. The toolchain is a Go
                package you import.
            </p>

            <h2 class="mt-10 text-lg font-semibold text-ink">The pipeline</h2>
            <p class="mt-2 leading-relaxed text-ink-soft">
                One command builds this section. Every stage of it is Go:
            </p>

            <div class="mt-4 space-y-3">
                <Stage
                    n="1"
                    title="TSX → Solid"
                    body="kjol/jsbundler compiles each .tsx into dom-expressions calls — the same output Babel's Solid preset produces. It is checked against Babel by a render-equivalence test: both are compiled, both are rendered, and the HTML must match."
                />
                <Stage
                    n="2"
                    title="Solid → bundle"
                    body="esbuild's Go API bundles it. Vendored packages resolve out of a pinned manifest rather than their own exports maps, because solid-js's bare entry mis-resolves to its SSR build — where every effect is a silent no-op."
                />
                <Stage
                    n="3"
                    title="Tailwind"
                    body="kjol/tw scans the sources for candidate class names and compiles the stylesheet. It is a Go implementation, so it can just as happily scan .go files — which is exactly what the Wasm Web layer needs it to do."
                />
            </div>

            <CodeBox class="mt-5" code={"$ go run ./server -build\nGenerating FA icon subset...\n  FA icons: 94 defs for 47 names\nGenerating public routes...\n  /js/ssr              Ssr (rendered, 2498 bytes)\nBundling JS + CSS...\n\nBundle                       Files      Size       Time\n-------------------------------------------------------\nbundle.min.js                    1    1.4 MB      198ms\nbundle.min.css                2500   74.6 KB       30ms"} />

            <AlertBlue header="One reactive instance, always" class="mt-8">
                The single hardest invariant in this build is that there is exactly one copy of solid-js. Two
                copies do not error — they render fine and then silently stop flushing effects, so onMount
                never fires and nothing updates. kjol's vendor manifest is searched before the app's for
                precisely this reason.
            </AlertBlue>

            <h2 class="mt-10 text-lg font-semibold text-ink">The kit</h2>
            <p class="mt-2 leading-relaxed text-ink-soft">
                All of it is on one page. It used to be three — Components, Forms, AutoTable — which is a
                split along the lines of the source files rather than along anything a reader wants: a person
                looking for a date picker does not know, and should not have to guess, whether it was filed
                under forms or under overlays.
            </p>

            <div class="mt-5 grid gap-3 sm:grid-cols-3">
                <For each={COMPONENT_GROUPS}>
                    {(g) => (
                        <a
                            href={"/js/components#" + g.id}
                            class="group flex items-center gap-2 rounded-default border border-line bg-surface px-3 py-2.5 no-underline shadow-xs transition hover:border-primary hover:shadow-sm"
                            onclick={(e) => {
                                e.preventDefault();
                                navigate("/components");
                                queueMicrotask(() =>
                                    document.getElementById(g.id)?.scrollIntoView({ behavior: "smooth", block: "start" }),
                                );
                            }}
                        >
                            <Icon icon={g.icon} size={14} class="shrink-0 text-primary" />
                            <span class="text-sm font-medium text-ink">{g.label}</span>
                            <Icon
                                icon="arrow-right"
                                size={11}
                                class="ml-auto text-ink-faint transition group-hover:text-primary"
                            />
                        </a>
                    )}
                </For>
            </div>
        </div>
    );
}

function Stage(props: { n: string; title: string; body: string }) {
    return (
        <div class="flex gap-4 border-l-2 border-line pl-4">
            <span class="mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-surface-raised text-xs font-semibold text-ink-soft">
                {props.n}
            </span>
            <div>
                <h3 class="font-semibold text-ink">{props.title}</h3>
                <p class="mt-1 text-sm leading-relaxed text-ink-soft">{props.body}</p>
            </div>
        </div>
    );
}
