import clsx from "clsx";
import { FlaskConical } from "lucide-react";
import { fmt } from "@/lib/data";
import type { ModelRow, Provenance, SplitInfo, SplitMetrics } from "@/lib/types";
import SectionLabel from "./SectionLabel";

export interface GeneralizationStripProps {
  model: ModelRow;
  hardInfo: SplitInfo;
}

function hasNumbers(m?: SplitMetrics): boolean {
  return !!m && Object.values(m).some((v) => typeof v === "number");
}

function DeltaTile({
  label,
  test,
  hard,
}: {
  label: string;
  test?: number;
  hard?: number;
}) {
  const d =
    typeof test === "number" && typeof hard === "number" ? hard - test : null;
  const degrading = d !== null && d > 0;
  return (
    <div className="hairline depth-1 hover-lift flex min-w-[160px] flex-col gap-1 rounded-sm bg-surface px-4 py-3">
      <span className="text-[11px] uppercase tracking-[0.14em] text-muted">
        Δ {label}
      </span>
      <span
        className={clsx(
          "num text-2xl leading-none",
          d === null ? "text-muted/50" : degrading ? "text-warn" : "text-text",
        )}
      >
        {d === null ? "—" : `${d >= 0 ? "+" : "−"}${Math.abs(d).toFixed(2)}`}
      </span>
      <span className="num text-[11px] text-muted">
        {fmt(test)} → {fmt(hard)}
      </span>
    </div>
  );
}

function GhostTile({ label }: { label: string }) {
  return (
    <div
      aria-hidden
      className="flex min-w-[160px] flex-col gap-1 rounded-sm border border-dashed border-line px-4 py-3"
    >
      <span className="text-[11px] uppercase tracking-[0.14em] text-muted/70">
        Δ {label}
      </span>
      <span className="num text-2xl leading-none text-muted/50">—</span>
      <span className="num text-[11px] text-muted/50">test → hard</span>
    </div>
  );
}

function gapCopy(provenance: Provenance): string {
  if (provenance === "running")
    return "This model’s pilot run is executing on Test + Hard right now — the delta lands here the moment it commits.";
  if (provenance === "planned")
    return "A platform run covering Test + Hard is on the roadmap for this model.";
  return "Published results cover Test only; the platform pilot re-runs every model on Test + Hard, and this gap closes when its run lands.";
}

/**
 * Test → Hard generalization: signed delta tiles when both splits are
 * measured (amber when degrading), otherwise a dashed evidence-gap callout
 * with ghost tiles showing the shape of what will appear.
 */
export default function GeneralizationStrip({
  model,
  hardInfo,
}: GeneralizationStripProps) {
  const test = model.metrics?.test;
  const hard = model.metrics?.hard;
  const measured = hasNumbers(test) && hasNumbers(hard);

  return (
    <section className="flex flex-col gap-4">
      <SectionLabel
        index="03"
        title="Generalization"
        hint="Test → Hard delta"
      />

      {measured ? (
        <div className="flex flex-col gap-5 md:flex-row md:items-center md:justify-between">
          <div className="flex flex-wrap gap-3">
            <DeltaTile label="WER" test={test?.wer} hard={hard?.wer} />
            <DeltaTile label="CS-WER" test={test?.csWer} hard={hard?.csWer} />
          </div>
          <p className="max-w-sm text-[13px] leading-relaxed text-muted">
            The Hard split holds{" "}
            <span className="num">{fmt(hardInfo.hours)}</span>
            <span className="num text-[11px]">{" "}h</span> of rare and
            unseen code-switched terms. A positive Δ (amber) means the model
            degrades off the common-term distribution.
          </p>
        </div>
      ) : (
        <div className="flex flex-col gap-5 rounded-sm border border-dashed border-line p-5 md:flex-row md:items-center md:justify-between md:p-6">
          <div className="flex max-w-xl items-start gap-4">
            <span aria-hidden className="mt-1 shrink-0 text-muted">
              <FlaskConical size={18} />
            </span>
            <div>
              <h3 className="font-display text-lg italic text-text">
                Evidence gap — no Hard-split measurement yet
              </h3>
              <p className="mt-1.5 text-[13px] leading-relaxed text-muted">
                The Hard split holds{" "}
                <span className="num">{fmt(hardInfo.hours)}</span>
                <span className="num text-[11px]">{" "}h</span> /{" "}
                <span className="num">
                  {hardInfo.utts.toLocaleString("en-US")}
                </span>{" "}
                utterances of rare and unseen code-switched terms — the
                generalization leaderboard. {gapCopy(model.provenance)}
              </p>
            </div>
          </div>
          <div className="flex shrink-0 flex-wrap gap-3">
            <GhostTile label="WER" />
            <GhostTile label="CS-WER" />
          </div>
        </div>
      )}
    </section>
  );
}
