"use client"

import { useMemo, useState } from "react"
import { BookOpen, ChevronDown, ChevronUp, ExternalLink, FileText, Globe, Layers, ScrollText, Tag, Users } from "lucide-react"
import { SignalTooltip } from "@/components/signals/signal-tooltip"
import type { BenchmarkEvalSummary } from "@/lib/eval-processing"
import { getKnownIssues } from "@/lib/known-issues"
import { KnownIssuesPanel } from "@/components/known-issues-panel"

interface PolicyOverviewProps {
  summary: BenchmarkEvalSummary
}

const SUMMARY_PREVIEW_CHARS = 280

function classifyResource(url: string): { kind: "paper" | "dataset" | "leaderboard" | "site"; label: string } {
  const lower = url.toLowerCase()
  if (lower.includes("arxiv.org") || lower.endsWith(".pdf") || lower.includes("/papers/")) {
    return { kind: "paper", label: "Paper" }
  }
  if (lower.includes("huggingface.co/datasets") || lower.includes("/dataset")) {
    return { kind: "dataset", label: "Dataset" }
  }
  if (lower.includes("leaderboard")) {
    return { kind: "leaderboard", label: "Leaderboard" }
  }
  return { kind: "site", label: "Source" }
}

function shortHost(url: string) {
  return url.replace(/^https?:\/\//, "").replace(/\/.*$/, "")
}

/**
 * Plain-language summary surface shown at the top of the benchmark page in
 * policy mode. Designed to answer three questions a non-technical reader has:
 * what does this measure, who built it, and where does it come from?
 *
 * Technical detail (variants, metric specifications, score scales) lives in
 * the existing overview card below this and is collapsed by default.
 */
function normalizeId(value: string | undefined | null): string {
  if (!value) return ""
  return value
    .toLowerCase()
    .trim()
    .replace(/[\s_\-/]+/g, "")
}

export function PolicyOverview({ summary }: PolicyOverviewProps) {
  const card = summary.benchmark_card

  // Defensive check: pipelines older than the "ancestor card leak" fix
  // sometimes attach the parent composite's card to a leaf benchmark (e.g.
  // helm_classic's card embedded under XSUM). Detect when the card's own
  // name is clearly not this benchmark and ignore its narrative text — the
  // synthesized fallback below produces something accurate instead.
  const cardName = card?.benchmark_details?.name
  const cardNameNorm = normalizeId(cardName)
  const evalIdentifiers = [
    summary.evaluation_name,
    summary.benchmark_leaf_key,
    summary.composite_benchmark_key,
    summary.composite_benchmark_name,
    summary.canonical_display_name,
    summary.evaluation_id,
  ].map(normalizeId)
  // Treat the card as belonging to this eval when its name fuzzily appears in
  // any of the eval's identifiers (or vice versa). Otherwise the card is from
  // a different (typically ancestor) benchmark.
  const cardMatchesEval =
    !cardName ||
    evalIdentifiers.some(
      (id) =>
        id.length > 0 &&
        cardNameNorm.length > 0 &&
        (id.includes(cardNameNorm) || cardNameNorm.includes(id)),
    )

  const overview = cardMatchesEval ? card?.benchmark_details?.overview?.trim() || "" : ""
  const goal = cardMatchesEval ? card?.purpose_and_intended_users?.goal?.trim() || "" : ""

  // Detect "parent" benchmark pages — either an aggregated composite or a
  // multi-metric matrix where each column is a slice. In both cases the
  // per-evaluation `metric_config.evaluation_description` belongs to whichever
  // component was processed first (e.g. just the "airline" subset of Tau
  // Bench 2) and would mislead a policy reader. Synthesize parent framing
  // instead and surface the slices separately.
  // Note: at the data layer the backend still ships these as `subtasks` /
  // `metric.scope === "subtask"`; we read those fields directly but label
  // them "slice" in the UI.
  const isAggregated = summary.is_aggregated === true
  const aggregateNames = (summary.aggregate_sources ?? [])
    .map((s) => s.composite_benchmark_name)
    .filter((s): s is string => typeof s === "string" && s.length > 0)

  const sliceLabels = useMemo(() => {
    const seen = new Set<string>()
    const labels: string[] = []
    const add = (raw: string | undefined | null) => {
      if (!raw) return
      const trimmed = raw.trim()
      if (!trimmed) return
      const key = trimmed.toLowerCase()
      if (seen.has(key)) return
      seen.add(key)
      labels.push(trimmed)
    }
    for (const slice of summary.subtasks ?? []) {
      add(slice.display_name || slice.subtask_name)
    }
    for (const metric of summary.leaderboard_metrics ?? []) {
      if (metric.scope === "subtask") {
        add(metric.subtask_name || metric.display_name)
      }
    }
    for (const name of aggregateNames) add(name)
    return labels
  }, [summary.subtasks, summary.leaderboard_metrics, aggregateNames])

  const isMatrix = (summary.leaderboard_metrics?.length ?? 0) > 1
  const isParentPage = isAggregated || (isMatrix && sliceLabels.length > 1)
  const useComponentDescription = !isParentPage

  const parentFallback = isParentPage && sliceLabels.length > 1
    ? `${summary.evaluation_name} reports results across ${sliceLabels.length} ${
        isAggregated ? "component benchmarks" : "slices"
      }. Each is evaluated separately; the score shown is the ${
        isAggregated ? "average" : "per-slice result"
      }.`
    : null

  const summaryText =
    overview ||
    goal ||
    parentFallback ||
    (useComponentDescription ? summary.metric_config.evaluation_description : summary.evaluation_name)

  const [expanded, setExpanded] = useState(false)
  const [slicesOpen, setSlicesOpen] = useState(false)
  const isLong = summaryText.length > SUMMARY_PREVIEW_CHARS
  const visibleText = expanded || !isLong
    ? summaryText
    : summaryText.slice(0, SUMMARY_PREVIEW_CHARS).replace(/\s+\S*$/, "") + "…"

  const domains = useMemo(() => {
    const fromTags = summary.tags?.domains ?? []
    const fromCard = cardMatchesEval ? card?.benchmark_details?.domains ?? [] : []
    return Array.from(new Set([...fromTags, ...fromCard].map((d) => d.trim()).filter(Boolean))).slice(0, 6)
  }, [summary.tags?.domains, card?.benchmark_details?.domains, cardMatchesEval])

  const languages = useMemo(() => {
    const fromTags = summary.tags?.languages ?? []
    const fromCard = cardMatchesEval ? card?.benchmark_details?.languages ?? [] : []
    return Array.from(new Set([...fromTags, ...fromCard].map((d) => d.trim()).filter(Boolean))).slice(0, 4)
  }, [summary.tags?.languages, card?.benchmark_details?.languages, cardMatchesEval])

  const license = card?.ethical_and_legal_considerations?.data_licensing
  const showLicense = license && license !== "Not specified"

  const resources = useMemo(() => {
    if (!cardMatchesEval) return []
    const urls = (card?.benchmark_details?.resources ?? []).filter((r) => typeof r === "string" && r.startsWith("http"))
    const seen = new Map<string, { kind: ReturnType<typeof classifyResource>["kind"]; label: string; url: string }>()
    for (const url of urls) {
      const c = classifyResource(url)
      if (!seen.has(c.kind)) {
        seen.set(c.kind, { ...c, url })
      }
    }
    return Array.from(seen.values())
  }, [card?.benchmark_details?.resources, cardMatchesEval])

  const evaluators = (summary.evaluator_names ?? []).slice(0, 3)
  const hasMoreEvaluators = (summary.evaluator_names?.length ?? 0) > evaluators.length

  const knownIssues = useMemo(
    () =>
      getKnownIssues(
        summary.evaluation_name,
        summary.composite_benchmark_name,
        summary.composite_benchmark_key,
        summary.benchmark_family_key,
        summary.benchmark_leaf_key,
        card?.benchmark_details?.name,
      ),
    [
      summary.evaluation_name,
      summary.composite_benchmark_name,
      summary.composite_benchmark_key,
      summary.benchmark_family_key,
      summary.benchmark_leaf_key,
      card?.benchmark_details?.name,
    ],
  )

  const directionLabel = summary.metric_config.lower_is_better
    ? "Lower scores are better"
    : "Higher scores are better"

  // Policy-note triple (paper §4.2.2): What it measures · Main caveat · Intended for.
  const measuresText = visibleText
  const caveatText = card?.purpose_and_intended_users?.limitations?.trim() || null
  const audienceArr = card?.purpose_and_intended_users?.audience
  const audienceText = Array.isArray(audienceArr)
    ? audienceArr.filter(Boolean).join("; ")
    : (typeof audienceArr === "string" ? audienceArr : "")

  return (
    <section className="ec-card warm" style={{ padding: "20px 24px" }}>
      <header className="mb-3 flex flex-wrap items-center gap-3">
        <BookOpen className="h-4 w-4" style={{ color: "var(--fg-muted)" }} />
        <span className="kicker kicker-fg" style={{ fontSize: 12, letterSpacing: "0.16em" }}>
          Policy note
        </span>
        <span
          className="font-mono text-[10px] uppercase tracking-[0.12em]"
          style={{ color: "var(--fg-subtle)" }}
        >
          {summary.evaluation_name} · in plain language
        </span>
      </header>

      {knownIssues.length > 0 && (
        <div className="mb-3">
          <KnownIssuesPanel issues={knownIssues} variant="compact" />
        </div>
      )}

      <dl
        className="grid gap-y-3 text-[14px]"
        style={{ gridTemplateColumns: "max-content 1fr", columnGap: 24 }}
      >
        <dt
          className="font-mono uppercase tracking-[0.14em]"
          style={{ fontSize: 10, color: "var(--fg-subtle)", paddingTop: 3 }}
        >
          Measures
        </dt>
        <dd style={{ color: "var(--fg)", lineHeight: 1.6, margin: 0 }}>
          {measuresText}
          {isLong && (
            <button
              type="button"
              onClick={() => setExpanded((v) => !v)}
              className="ml-1 text-[13px] font-medium underline-offset-4 hover:underline"
              style={{ color: "var(--accent)" }}
            >
              {expanded ? "Show less" : "Read more"}
            </button>
          )}
        </dd>

        {caveatText && (
          <>
            <dt
              className="font-mono uppercase tracking-[0.14em]"
              style={{ fontSize: 10, color: "var(--accent)", paddingTop: 3 }}
            >
              Caveat
            </dt>
            <dd style={{ color: "var(--fg)", lineHeight: 1.6, margin: 0 }}>{caveatText}</dd>
          </>
        )}

        {audienceText && (
          <>
            <dt
              className="font-mono uppercase tracking-[0.14em]"
              style={{ fontSize: 10, color: "var(--fg-subtle)", paddingTop: 3 }}
            >
              Intended for
            </dt>
            <dd style={{ color: "var(--fg)", lineHeight: 1.6, margin: 0 }}>{audienceText}</dd>
          </>
        )}

        <dt
          className="font-mono uppercase tracking-[0.14em]"
          style={{ fontSize: 10, color: "var(--fg-subtle)", paddingTop: 3 }}
        >
          How to read
        </dt>
        <dd style={{ color: "var(--fg)", lineHeight: 1.6, margin: 0 }}>
          <SignalTooltip
            content={
              summary.metric_config.lower_is_better
                ? "On this benchmark, a lower number means the model did better."
                : "On this benchmark, a higher number means the model did better."
            }
          >
            <span
              className="underline decoration-dotted underline-offset-4 cursor-help"
              style={{ textDecorationColor: "var(--fg-subtle)" }}
            >
              {directionLabel}.
            </span>
          </SignalTooltip>{" "}
          <span style={{ color: "var(--fg-muted)" }}>
            Compared across {summary.models_count} model{summary.models_count === 1 ? "" : "s"}.
          </span>
        </dd>
      </dl>

      {isParentPage && sliceLabels.length > 1 && (
        <div
          className="mt-4"
          style={{ border: "1px solid var(--border-soft)", background: "var(--bg)" }}
        >
          <button
            type="button"
            onClick={() => setSlicesOpen((v) => !v)}
            aria-expanded={slicesOpen}
            className="flex w-full items-center justify-between gap-3 px-3.5 py-2.5 text-left transition-colors hover:bg-[color:var(--bg-warm)]"
          >
            <span
              className="flex items-center gap-1.5 font-mono uppercase"
              style={{ fontSize: 10, letterSpacing: "0.14em", color: "var(--fg-muted)" }}
            >
              <Layers className="h-3.5 w-3.5" />
              {isAggregated ? `Component benchmarks (${sliceLabels.length})` : `Slices (${sliceLabels.length})`}
            </span>
            {slicesOpen ? (
              <ChevronUp className="h-4 w-4" style={{ color: "var(--fg-muted)" }} />
            ) : (
              <ChevronDown className="h-4 w-4" style={{ color: "var(--fg-muted)" }} />
            )}
          </button>
          {slicesOpen && (
            <ul
              className="grid list-disc gap-x-6 gap-y-1 px-3.5 pb-3.5 pl-9 text-[13px] sm:grid-cols-2 lg:grid-cols-3"
              style={{ color: "var(--fg)" }}
            >
              {sliceLabels.map((name) => (
                <li key={name} className="capitalize">
                  {name}
                </li>
              ))}
            </ul>
          )}
        </div>
      )}

      {(domains.length > 0 || languages.length > 0 || showLicense) && (
        <div className="mt-4 flex flex-wrap gap-1.5">
          {domains.map((d) => (
            <span
              key={`d-${d}`}
              className="ec-tag"
              style={{ textTransform: "uppercase" }}
            >
              <Tag className="h-3 w-3 shrink-0" />
              {d}
            </span>
          ))}
          {languages.map((l) => (
            <span key={`l-${l}`} className="ec-tag accent" style={{ textTransform: "uppercase" }}>
              <Globe className="h-3 w-3 shrink-0" />
              {l}
            </span>
          ))}
          {showLicense && (
            <SignalTooltip content="The license under which the benchmark dataset is released.">
              <span className="ec-tag outline cursor-help">
                <ScrollText className="h-3 w-3 shrink-0" />
                {license}
              </span>
            </SignalTooltip>
          )}
        </div>
      )}

      {(resources.length > 0 || evaluators.length > 0) && (
        <div
          className="mt-5 pt-4"
          style={{ borderTop: "1px dashed var(--border-soft)" }}
        >
          <div
            className="mb-2 font-mono uppercase"
            style={{ fontSize: 10, letterSpacing: "0.14em", color: "var(--fg-subtle)" }}
          >
            Where this comes from
          </div>
          <div className="flex flex-wrap items-center gap-2">
            {resources.map((r) => (
              <a
                key={r.url}
                href={r.url}
                target="_blank"
                rel="noreferrer"
                className="ec-tag outline inline-flex items-center gap-1.5"
                style={{ textDecoration: "none" }}
              >
                <FileText className="h-3 w-3 shrink-0" />
                <span style={{ color: "var(--fg)" }}>{r.label}</span>
                <span style={{ color: "var(--fg-muted)" }}>{shortHost(r.url)}</span>
                <ExternalLink className="h-3 w-3 shrink-0" />
              </a>
            ))}
            {evaluators.length > 0 && (
              <SignalTooltip
                content={
                  <span className="block space-y-1">
                    <span className="block font-semibold">Who reported these scores</span>
                    <span className="block">{summary.evaluator_names?.join(", ")}</span>
                    {summary.third_party_ratio > 0 && (
                      <span className="block text-muted-foreground">
                        {Math.round(summary.third_party_ratio * 100)}% of results come from independent evaluators (not the model's own developer).
                      </span>
                    )}
                  </span>
                }
              >
                <span className="ec-tag outline cursor-help inline-flex items-center gap-1.5">
                  <Users className="h-3 w-3 shrink-0" />
                  <span style={{ color: "var(--fg)" }}>Reported by</span>
                  <span style={{ color: "var(--fg-muted)" }}>
                    {evaluators.join(", ")}
                    {hasMoreEvaluators ? ` +${(summary.evaluator_names?.length ?? 0) - evaluators.length} more` : ""}
                  </span>
                </span>
              </SignalTooltip>
            )}
          </div>
        </div>
      )}
    </section>
  )
}
