// 运行状态 —— 跨 Studio 与底部抽屉共享。
import type { ExecEvent } from "./api";

export type RunPhase = "idle" | "submitting" | "streaming" | "done" | "error";

export interface RunEvent {
  t: number; // 相对开始的毫秒
  label: string;
}

export interface RunState {
  phase: RunPhase;
  taskId?: string;
  output: string;
  events: RunEvent[];
  exec: ExecEvent[]; // 后端回流的节点级执行轨迹（运行·观测）
  error?: string;
  lifecycle?: string; // 轮询到的后端任务状态（waiting 时弹审批；done/rejected 等终态）
  detail?: string; // 状态附带说明（如审批标题）
}

export const emptyRun: RunState = { phase: "idle", output: "", events: [], exec: [] };

// ---- 执行轨迹派生：把扁平 ExecEvent 流归并为按节点聚合的轨迹 ----

export type NodeStatus = "running" | "done" | "error" | "info" | "waiting";

export interface NodeTrace {
  node: string;
  kind: string; // memory|tool|prompt|model|plan|section|render|system
  label: string;
  status: NodeStatus;
  ms?: number;
  detail?: string;
  notes: string[]; // info 子事件（如检索到的参考资料预览）
  order: number;
}

// PendingApproval 是一个待人工审批的中断（HITL）：审批节点已发 await 事件、尚未被 end/error 收口。
export interface PendingApproval {
  node: string;
  title: string;
  summary: string;
}

// pendingApproval 从执行事件流里找出当前待审批的中断：取最后一个 kind=approval & phase=await，
// 且其后该节点没有 end/error（未被批准/拒绝收口）的事件。无则 null。
export function pendingApproval(events: ExecEvent[]): PendingApproval | null {
  let pending: PendingApproval | null = null;
  for (const e of events) {
    if (e.kind !== "approval") continue;
    if (e.phase === "await") {
      pending = { node: e.node, title: e.label || "人工审批", summary: e.detail || "" };
    } else if (e.phase === "end" || e.phase === "error") {
      if (pending && pending.node === e.node) pending = null; // 已决，收口
    }
  }
  return pending;
}

// deriveNodes 把事件流按 node 归并：start→running，end→done(带耗时)，error→error，info→点事件/附注。
export function deriveNodes(events: ExecEvent[]): NodeTrace[] {
  const map = new Map<string, NodeTrace>();
  let order = 0;
  for (const e of events) {
    let n = map.get(e.node);
    if (!n) {
      n = { node: e.node, kind: e.kind, label: e.label, status: "info", notes: [], order: order++ };
      map.set(e.node, n);
    }
    if (e.label) n.label = e.label;
    n.kind = e.kind;
    switch (e.phase) {
      case "start":
        if (n.status !== "done" && n.status !== "error") n.status = "running";
        break;
      case "await": // HITL 审批节点暂停，等人工决定
        n.status = "waiting";
        break;
      case "end":
        n.status = "done";
        n.ms = e.ms;
        if (e.detail) n.detail = e.detail;
        break;
      case "error":
        n.status = "error";
        n.ms = e.ms;
        if (e.detail) n.detail = e.detail;
        break;
      case "info":
        if (e.detail) n.notes.push(e.detail);
        else if (e.label) n.notes.push(e.label);
        break;
    }
  }
  return [...map.values()].sort((a, b) => a.order - b.order);
}
