import { useCallback, useEffect, useState } from "react";
import { Activity, FileText, History, Users, Wrench } from "lucide-react";
import { ExecTrace } from "../components/ExecTrace";
import { Markdown } from "../components/Markdown";
import { ChartView } from "../components/ChartView";
import { extractChartBlocks, hasChart } from "../lib/chartspec";
import { deriveNodes, emptyRun, type RunState } from "../lib/run";
import { listRuns, taskEval, runReplay, type RunSummary, type EvalResult } from "../lib/api";
import { Tabs, Panel, Dot, Badge, EmptyState, cn, type TabDef } from "../ui";

type DetailTab = "trace" | "tools" | "eval";

const STATUS_DOT: Record<string, "success" | "danger" | "warn" | "running" | "neutral"> = {
  done: "success", failed: "danger", timeout: "danger", rejected: "danger",
  waiting: "warn", running: "running", submitted: "running",
};
const LEVEL_TONE: Record<string, "success" | "warn" | "danger"> = { ok: "success", warn: "warn", poor: "danger" };

function relTime(iso: string): string {
  const d = Date.now() - new Date(iso).getTime();
  if (d < 60_000) return "刚刚";
  if (d < 3_600_000) return `${Math.floor(d / 60_000)} 分钟前`;
  if (d < 86_400_000) return `${Math.floor(d / 3_600_000)} 小时前`;
  return `${Math.floor(d / 86_400_000)} 天前`;
}

// 运行 · 观测：左=运行历史，中=tab 切换(轨迹/工具/评测)+状态，右=模型输出(Markdown)。
// 选中历史运行从 Redis 回放；「当前运行」置顶沿用实时订阅。
export function RunsView({ run }: { run: RunState }) {
  const [runs, setRuns] = useState<RunSummary[]>([]);
  const [sel, setSel] = useState<string | null>(null); // null = 当前实时运行
  const [replay, setReplay] = useState<RunState>(emptyRun);
  const [evalRes, setEvalRes] = useState<EvalResult | null>(null);
  const [tab, setTab] = useState<DetailTab>("trace");

  useEffect(() => {
    let alive = true;
    const load = () => listRuns(40).then((r) => alive && setRuns(r)).catch(() => {});
    load();
    const id = setInterval(load, 5000);
    return () => { alive = false; clearInterval(id); };
  }, []);

  // 选中历史运行：读库取持久化的输出 + 轨迹复盘（秒回、不依赖 Redis TTL）。
  const selectRun = useCallback((taskId: string) => {
    if (taskId === run.taskId) { setSel(null); setEvalRes(null); return; }
    setSel(taskId);
    setReplay({ phase: "submitting", taskId, output: "", events: [], exec: [] });
    setEvalRes(null);
    runReplay(taskId)
      .then((d) => setReplay({ phase: "done", taskId, output: d.output, events: [], exec: d.exec }))
      .catch(() => setReplay({ phase: "error", taskId, output: "", events: [], exec: [], error: "复盘数据不可用" }));
    taskEval(taskId).then(setEvalRes).catch(() => {});
  }, [run.taskId]);

  // 新实时运行开始 → 切回「当前运行」+ 回到轨迹标签。
  useEffect(() => {
    if (run.taskId) { setSel(null); setEvalRes(null); setTab("trace"); }
  }, [run.taskId]);

  // 当前实时运行的评测：完成后拉一次。
  useEffect(() => {
    if (!sel && run.taskId && run.phase === "done") taskEval(run.taskId).then(setEvalRes).catch(() => {});
  }, [sel, run.taskId, run.phase]);

  const liveActive = run.taskId && run.phase !== "idle";
  const cur = sel ? replay : run;
  const nodes = deriveNodes(cur.exec);
  // 工具调用面板纳入专家派发：MCP 工具(kind=tool)与多智能体协调里的子智能体派发(kind=agent)都是「调用」。
  const calls = nodes.filter((n) => n.kind === "tool" || n.kind === "agent");
  const tabs: TabDef<DetailTab>[] = [
    { key: "trace", label: "执行轨迹", count: nodes.length },
    { key: "tools", label: "工具/专家", count: calls.length },
    { key: "eval", label: "评测" },
  ];
  const empty = !cur.taskId && cur.exec.length === 0 && !cur.output;

  // 运行状态指示（沿用原底部抽屉的「完成 ✓ / 流式中… / 出错」）。
  const statusCls =
    cur.phase === "streaming" ? "text-accent-400" : cur.phase === "done" ? "text-success" : cur.phase === "error" ? "text-danger" : "text-slate-500";
  const statusText =
    cur.phase === "streaming" ? "流式中…" : cur.phase === "done" ? "完成 ✓" : cur.phase === "error" ? `✗ ${cur.error ?? "出错"}` : cur.phase === "submitting" ? "提交中…" : "就绪";

  return (
    <div className="flex h-full min-h-0 flex-col gap-3 overflow-hidden p-6">
      <header className="flex items-center gap-3">
        <div className="flex-1">
          <h1 className="text-lg font-semibold text-slate-100">运行 · 观测</h1>
          <p className="mt-1 text-xs text-slate-500">运行历史复盘：选一次运行，左查轨迹/工具/评测（切换标签），右看模型输出。</p>
        </div>
        <span className="text-xs text-slate-500">{nodes.length} 节点 · {calls.length} 次调用/派发</span>
      </header>

      <div className="grid min-h-0 flex-1 grid-cols-[240px_1fr_1fr] gap-3">
        {/* 运行历史列表 */}
        <div className="flex min-h-0 flex-col rounded-lg border border-line bg-ink-900">
          <div className="flex items-center gap-2 border-b border-line px-3 py-2 text-xs font-medium text-slate-400">
            <History className="h-3.5 w-3.5" /> 运行历史
          </div>
          <div className="min-h-0 flex-1 overflow-auto p-1.5">
            {liveActive && (
              <button onClick={() => { setSel(null); setEvalRes(null); }}
                className={cn("mb-1 flex w-full items-center gap-2 rounded-md px-2 py-2 text-left", sel === null ? "bg-ink-800 ring-1 ring-brand/40" : "hover:bg-ink-850")}>
                <Dot tone={run.phase === "streaming" ? "running" : run.phase === "done" ? "success" : "neutral"} pulse={run.phase === "streaming"} />
                <span className="flex-1 truncate text-xs text-slate-200">当前运行</span>
                <span className="text-[10px] text-brand-400">live</span>
              </button>
            )}
            {runs.map((r) => (
              <button key={r.task_id} onClick={() => selectRun(r.task_id)}
                className={cn("flex w-full items-center gap-2 rounded-md px-2 py-2 text-left", sel === r.task_id ? "bg-ink-800 ring-1 ring-brand/40" : "hover:bg-ink-850")}>
                <Dot tone={STATUS_DOT[r.status] ?? "neutral"} />
                <span className="min-w-0 flex-1">
                  <span className="block truncate font-mono text-[11px] text-slate-300">{r.task_id}</span>
                  <span className="block text-[10px] text-slate-600">{r.status} · {relTime(r.at)}</span>
                </span>
                {r.eval_level && <Badge tone={LEVEL_TONE[r.eval_level] ?? "neutral"}>{r.eval_overall.toFixed(2)}</Badge>}
              </button>
            ))}
            {runs.length === 0 && <div className="py-8 text-center text-xs text-slate-600">暂无运行记录</div>}
          </div>
        </div>

        {/* 中：tab 切换 轨迹/工具/评测 + 状态指示 */}
        <div className="flex min-h-0 flex-col rounded-lg border border-line bg-ink-900">
          <div className="flex items-center border-b border-line px-2">
            <Tabs tabs={tabs} value={tab} onChange={setTab} />
            <span className={cn("ml-auto pr-2 text-[11px]", statusCls)}>{statusText}</span>
          </div>
          <div className="min-h-0 flex-1 overflow-auto p-4">
            {empty ? (
              <EmptyState icon={Activity} title="选择一次运行" desc="左侧点选历史运行即可回放轨迹；或在编排/报告页发起新运行。" />
            ) : tab === "trace" ? (
              <ExecTrace events={cur.exec} phase={cur.phase} />
            ) : tab === "tools" ? (
              <ToolCalls run={cur} />
            ) : (
              <EvalView ev={evalRes} />
            )}
          </div>
        </div>

        {/* 右：模型输出（Markdown，固定面板，与之前一致） */}
        <Panel title="模型输出" icon={FileText}>
          {cur.output ? (
            <OutputView output={cur.output} />
          ) : (
            <EmptyState icon={Activity} title="尚无输出" desc="选择一次运行查看其模型输出；或发起新运行，token 在此流式呈现。" />
          )}
        </Panel>
      </div>
    </div>
  );
}

// OutputView：模型输出 = Markdown 渲染；含 ```chart 块时分段（文本走 Markdown，图表走 ChartView）。
function OutputView({ output }: { output: string }) {
  if (!hasChart(output)) return <Markdown text={output} className="text-sm" />;
  return (
    <div className="text-sm">
      {extractChartBlocks(output).map((seg, i) =>
        seg.kind === "chart" ? (
          <ChartView key={i} spec={seg.spec} />
        ) : (
          seg.text.trim() && <Markdown key={i} text={seg.text} className="text-sm" />
        ),
      )}
    </div>
  );
}

// ToolCalls：从执行事件筛出「调用」节点 —— MCP 工具(kind=tool)与多智能体协调里的子智能体派发
// (kind=agent)，逐条展示入参/简报 → 产出 + 耗时/状态。
function ToolCalls({ run }: { run: RunState }) {
  const calls = deriveNodes(run.exec).filter((n) => n.kind === "tool" || n.kind === "agent");
  if (calls.length === 0) {
    return <p className="text-xs text-slate-600">本次运行暂无工具调用或专家派发。图里挂了检索/工具节点、或多智能体协调派发专家时，每次调用会在此列出入参/简报与产出。</p>;
  }
  return (
    <ul className="space-y-1.5 text-xs">
      {calls.map((t) => {
        const isAgent = t.kind === "agent";
        return (
          <li key={t.node} className="rounded-md border border-line bg-ink-950/60 px-3 py-2">
            <div className="flex items-center gap-2">
              {isAgent ? <Users className="h-3.5 w-3.5 text-indigo-400" strokeWidth={2} /> : <Wrench className="h-3.5 w-3.5 text-warn" strokeWidth={2} />}
              <span className="font-mono text-[11px] text-slate-200">{t.node.replace(/^(tool|agent):/, "")}</span>
              <Badge tone={isAgent ? "accent" : "neutral"}>{isAgent ? "专家" : "工具"}</Badge>
              <Badge tone={t.status === "error" ? "danger" : t.status === "running" ? "accent" : "success"}>
                {t.status === "error" ? "失败" : t.status === "running" ? "调用中" : "成功"}
              </Badge>
              {t.ms != null && t.ms > 0 && <span className="ml-auto font-mono text-[10px] text-slate-500">{t.ms} ms</span>}
            </div>
            {t.detail && <p className="mt-1 break-words text-[11px] leading-relaxed text-slate-400">{t.detail}</p>}
          </li>
        );
      })}
    </ul>
  );
}

// EvalView：本次运行的自动化评测（分级/综合/忠实度/纠偏/评语/flags）。
function EvalView({ ev }: { ev: EvalResult | null }) {
  if (!ev) return <p className="text-xs text-slate-600">暂无评测结果（任务未完成或评测进行中）。</p>;
  return (
    <div className="space-y-2 text-xs">
      <div className="flex flex-wrap items-center gap-2">
        <Badge tone={LEVEL_TONE[ev.level] ?? "neutral"}>{ev.level} · {ev.overall.toFixed(2)}</Badge>
        {ev.corrected && <Badge tone="accent">已纠偏</Badge>}
        <span className="text-slate-500">规则 {ev.rule.toFixed(2)} · 质量 {ev.llm.toFixed(2)}</span>
        {ev.sources > 0 && <span className="text-slate-500">忠实 {ev.faithful.toFixed(2)} · {ev.sources} 来源</span>}
      </div>
      {ev.reason && <p className="leading-relaxed text-slate-400">{ev.reason}</p>}
      {ev.flags?.length > 0 && <p className="text-warn">{ev.flags.join("；")}</p>}
    </div>
  );
}
