import { motion } from "framer-motion";
import {
  ChevronDown,
  ChevronUp,
  AlertTriangle,
  CheckCircle2,
  Clock,
  Cpu,
  Beaker,
  Sparkle,
} from "lucide-react";
import { useState } from "react";
import type { ModelResult } from "@/types/inference";
import {
  classifyStatus,
  cn,
  confidenceColor,
  formatMs,
  formatPercent,
  formatParams,
} from "@/lib/utils";
import ConfidenceGauge from "./ConfidenceGauge";

interface Props {
  result: ModelResult;
}

const PAPER_IDS = new Set([
  "nes2net",
  "sonar",
  "bicrossmamba_st",
  "voiceradar",
  "holi_antispoof",
]);

export default function ModelCard({ result }: Props) {
  const [open, setOpen] = useState(false);
  const isFake = result.prediction === "fake";
  const status = classifyStatus(result.status);
  const confColor = confidenceColor(result.confidence, result.prediction);
  const isPaper = PAPER_IDS.has(result.model_id);

  const ribbon = isPaper ? "bg-warn" : "bg-cyber";
  const familyLabel = isPaper ? "paper architecture" : "production";
  const FamilyIcon = isPaper ? Beaker : Sparkle;

  return (
    <motion.div
      layout
      initial={{ opacity: 0, y: 8 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.3 }}
      className={cn(
        "panel relative flex h-full flex-col overflow-hidden p-4 pl-5",
        isFake ? "shadow-danger" : "shadow-cyber"
      )}
    >
      {/* Family ribbon along the left edge */}
      <div className={cn("absolute left-0 top-0 h-full w-1.5", ribbon, "opacity-70")} />

      {/* Soft accent glow */}
      <div
        className={cn(
          "pointer-events-none absolute -right-16 -top-16 h-36 w-36 rounded-full blur-3xl",
          isFake ? "bg-danger/20" : "bg-cyber/15"
        )}
      />

      {/* ── Header ────────────────────────────────────────────────── */}
      <div className="flex items-start justify-between gap-2">
        <div className="min-w-0 flex-1">
          <span className="font-display text-base font-semibold text-ink truncate block">
            {result.display_name}
          </span>
          <div className="mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-[11px] text-ink-dim">
            <span
              className={cn(
                "inline-flex items-center gap-1 font-mono uppercase",
                isPaper ? "text-warn" : "text-cyber"
              )}
            >
              <FamilyIcon className="h-3 w-3" /> {familyLabel}
            </span>
            <span className="text-ink-mute">·</span>
            <span className="truncate">{result.paradigm}</span>
          </div>
        </div>
        <div
          className={cn(
            "shrink-0 rounded-md border px-2 py-1 font-mono text-xs font-bold",
            isFake
              ? "border-danger/40 bg-danger/10 text-danger"
              : "border-cyber/40 bg-cyber/10 text-cyber"
          )}
        >
          {result.prediction.toUpperCase()}
        </div>
      </div>

      {/* ── Status pill row ───────────────────────────────────────── */}
      <div className="mt-2 flex flex-wrap items-center gap-1.5">
        <span
          className={cn(
            "inline-flex items-center gap-1 rounded-full px-2 py-0.5 font-mono text-[10px] uppercase tracking-wider",
            status === "live" && "bg-cyber/15 text-cyber",
            status === "fallback" && "bg-warn/15 text-warn",
            status === "error" && "bg-danger/15 text-danger",
            status === "loading" && "bg-surface-alt text-ink-dim"
          )}
          title={result.status}
        >
          {status === "live" && <CheckCircle2 className="h-2.5 w-2.5" />}
          {status === "fallback" && <AlertTriangle className="h-2.5 w-2.5" />}
          {status}
        </span>
        <span className="inline-flex items-center gap-1 rounded-full border border-line bg-surface-alt/60 px-2 py-0.5 font-mono text-[10px] text-ink-dim">
          <Clock className="h-2.5 w-2.5" /> {formatMs(result.inference_time_ms)}
        </span>
        <span className="inline-flex items-center gap-1 rounded-full border border-line bg-surface-alt/60 px-2 py-0.5 font-mono text-[10px] text-ink-dim">
          <Cpu className="h-2.5 w-2.5" /> {formatParams(result.params_k)}
        </span>
      </div>

      {/* ── Gauge + numbers ──────────────────────────────────────── */}
      <div className="mt-3 grid grid-cols-[auto,1fr] gap-4">
        <ConfidenceGauge value={result.confidence} prediction={result.prediction} />
        <div className="flex flex-col justify-center gap-1 font-mono text-[11px]">
          <div className="flex items-baseline gap-2">
            <span className="text-ink-mute">confidence</span>
            <span className={cn("text-base font-bold", confColor)}>
              {formatPercent(result.confidence)}
            </span>
          </div>
          {result.eer_reference?.df21 != null && (
            <div className="text-ink-dim">
              DF21 EER:{" "}
              <span className="text-ink">{result.eer_reference.df21}%</span>
            </div>
          )}
          {result.eer_reference?.in_the_wild != null && (
            <div className="text-ink-dim">
              ITW EER:{" "}
              <span className="text-ink">
                {result.eer_reference.in_the_wild}%
              </span>
            </div>
          )}
          {result.eer_reference?.la21 != null && (
            <div className="text-ink-dim">
              LA21 EER:{" "}
              <span className="text-ink">{result.eer_reference.la21}%</span>
            </div>
          )}
        </div>
      </div>

      {/* Spacer pushes the details block to the bottom for visual alignment */}
      <div className="flex-1" />

      {/* ── Status detail strip ──────────────────────────────────── */}
      {status === "fallback" && (
        <div className="mt-3 flex items-start gap-2 rounded-md border border-warn/30 bg-warn/5 p-2 text-[11px] text-warn">
          <AlertTriangle className="mt-0.5 h-3 w-3 shrink-0" />
          <span>
            No checkpoint — routed to{" "}
            <span className="font-bold">{result.fallback_to ?? "fallback"}</span>.
            Drop weights in{" "}
            <code className="font-mono">backend/checkpoints/</code> to go live.
          </span>
        </div>
      )}

      {/* ── Why? expander ───────────────────────────────────────── */}
      <button
        onClick={() => setOpen((v) => !v)}
        className="mt-3 inline-flex items-center gap-1 self-start font-mono text-[11px] text-ink-dim transition hover:text-cyber"
      >
        {open ? "hide details" : "details"}
        {open ? (
          <ChevronUp className="h-3 w-3" />
        ) : (
          <ChevronDown className="h-3 w-3" />
        )}
      </button>

      {open && (
        <motion.div
          initial={{ opacity: 0, height: 0 }}
          animate={{ opacity: 1, height: "auto" }}
          className="mt-2 overflow-hidden border-t border-line pt-2 text-[11px] leading-relaxed text-ink-dim"
        >
          {result.notes && (
            <p className="mb-2 whitespace-normal">{result.notes}</p>
          )}
          <FeatureGrid features={result.features} />
        </motion.div>
      )}
    </motion.div>
  );
}

function FeatureGrid({ features }: { features: Record<string, unknown> }) {
  const flat = Object.entries(features).filter(
    ([, v]) =>
      typeof v === "number" || typeof v === "string" || typeof v === "boolean"
  );
  if (!flat.length) return null;
  return (
    <div className="grid grid-cols-2 gap-x-3 gap-y-1 font-mono text-[10px]">
      {flat.slice(0, 12).map(([k, v]) => (
        <div key={k} className="flex justify-between gap-2 truncate">
          <span className="text-ink-mute truncate">{k}</span>
          <span className="text-ink truncate">{String(v)}</span>
        </div>
      ))}
    </div>
  );
}
