import {
  Cpu,
  Bookmark,
  Wrench,
  MessageSquareText,
  Sparkles,
  ListTree,
  FileText,
  FileOutput,
  CheckCircle2,
  XCircle,
  Loader2,
  Circle,
  type LucideIcon,
} from "lucide-react";
import { deriveNodes, type NodeTrace, type RunPhase } from "../lib/run";
import type { ExecEvent } from "../lib/api";
import { cn } from "../ui";

// 各节点类别的图标与配色（与后端 ExecEvent.kind 对应）。
const KIND: Record<string, { icon: LucideIcon; cls: string; name: string }> = {
  system: { icon: Cpu, cls: "text-slate-400", name: "系统" },
  memory: { icon: Bookmark, cls: "text-brand-400", name: "记忆召回" },
  tool: { icon: Wrench, cls: "text-warn", name: "工具调用" },
  prompt: { icon: MessageSquareText, cls: "text-sky-300", name: "提示词" },
  model: { icon: Sparkles, cls: "text-success", name: "模型推理" },
  plan: { icon: ListTree, cls: "text-accent-400", name: "规划" },
  section: { icon: FileText, cls: "text-indigo-300", name: "章节" },
  render: { icon: FileOutput, cls: "text-danger", name: "渲染" },
};

function meta(kind: string) {
  return KIND[kind] ?? { icon: Circle, cls: "text-slate-400", name: kind };
}

function StatusDot({ status }: { status: NodeTrace["status"] }) {
  if (status === "running") return <Loader2 className="h-4 w-4 animate-spin text-accent-400" strokeWidth={2.4} />;
  if (status === "done") return <CheckCircle2 className="h-4 w-4 text-success" strokeWidth={2.2} />;
  if (status === "error") return <XCircle className="h-4 w-4 text-danger" strokeWidth={2.2} />;
  if (status === "waiting") return <Loader2 className="h-4 w-4 animate-spin text-amber-400" strokeWidth={2.4} />; // 待审批
  return <Circle className="h-4 w-4 text-slate-600" strokeWidth={2} />;
}

// ExecTrace 把执行事件流渲染为竖向轨道：每个节点一颗灯，实时点亮 + 耗时 + 入参/产出。
export function ExecTrace({ events, phase, compact }: { events: ExecEvent[]; phase?: RunPhase; compact?: boolean }) {
  const raw = deriveNodes(events);
  // 运行整体已完成，但轨迹可能缺了中断后(resume)续录的事件（如审批通过、续跑节点），
  // 导致审批节点停在 waiting 转圈。既然已完成，把悬挂的 waiting/running 收敛为 done，不再假装进行中。
  const nodes =
    phase === "done"
      ? raw.map((n) => (n.status === "waiting" || n.status === "running" ? { ...n, status: "done" as const } : n))
      : raw;
  if (nodes.length === 0) {
    return (
      <div className="flex h-full flex-col items-center justify-center gap-1 px-4 py-8 text-center text-xs text-slate-600">
        <span>运行后逐节点点亮执行轨迹</span>
        <span className="text-slate-700">记忆召回 → 工具调用 → 提示词 → 模型推理 / 报告：规划 → 各章并行 → 渲染</span>
      </div>
    );
  }
  const total = nodes.reduce((s, n) => s + (n.ms ?? 0), 0);
  return (
    <div className={compact ? "" : "p-1"}>
      {!compact && (
        <div className="mb-2 flex items-center gap-3 px-1 text-[11px] text-slate-500">
          <span>{nodes.length} 个节点</span>
          <span>·</span>
          <span>累计 {total} ms</span>
          {phase === "streaming" && <span className="text-accent-400">● 执行中</span>}
          {phase === "done" && <span className="text-success">✓ 完成</span>}
          {phase === "error" && <span className="text-danger">✗ 出错</span>}
        </div>
      )}
      <ol className="relative ml-2 space-y-2 border-l border-line pl-4">
        {nodes.map((n) => {
          const m = meta(n.kind);
          const Icon = m.icon;
          return (
            <li key={n.node} className="relative">
              <span className="absolute -left-[22px] top-1.5 flex h-4 w-4 items-center justify-center rounded-full bg-ink-900">
                <StatusDot status={n.status} />
              </span>
              <div className="rounded-md border border-line bg-ink-950/60 px-3 py-2">
                <div className="flex items-center gap-2">
                  <Icon className={cn("h-3.5 w-3.5 shrink-0", m.cls)} strokeWidth={2} />
                  <span className="text-xs font-medium text-slate-200">{n.label}</span>
                  <span className={cn("rounded bg-ink-800 px-1.5 py-0.5 text-[9px]", m.cls)}>{m.name}</span>
                  {n.ms != null && n.ms > 0 && <span className="ml-auto font-mono text-[10px] text-slate-500">{n.ms} ms</span>}
                  {n.status === "running" && <span className="ml-auto text-[10px] text-accent-400">运行中…</span>}
                </div>
                {n.detail && <p className="mt-1 break-words text-[11px] leading-relaxed text-slate-400">{n.detail}</p>}
                {n.notes.map((note, i) => (
                  <p key={i} className="mt-1 break-words border-l border-line pl-2 text-[11px] text-slate-500">
                    {note}
                  </p>
                ))}
              </div>
            </li>
          );
        })}
      </ol>
    </div>
  );
}
