"use client";

import { useState } from "react";
import { Braces, ChevronRight, CircleOff, Copy, GitFork, X } from "lucide-react";
import { FieldTree } from "@/components/FieldTree";
import type { FlowEdgeRecord, FlowNodeRecord, RunGraph } from "@/lib/types";

type Tab = "fields" | "lineage" | "contract";

function EdgeList({ title, edges, graph, direction }: {
  title: string;
  edges: FlowEdgeRecord[];
  graph: RunGraph;
  direction: "incoming" | "outgoing";
}) {
  return <section className="inspectorSection">
    <h3>{title}<span>{edges.length}</span></h3>
    {edges.length ? <div className="edgeList">{edges.map((edge) => {
      const otherId = direction === "incoming" ? edge.source : edge.target;
      const other = graph.nodes.find((item) => item.id === otherId);
      return <div key={edge.id} className={`edgeRow edge-${edge.kind}`}>
        <GitFork size={14} />
        <div><strong>{other?.title ?? otherId}</strong><small>{edge.label ?? edge.kind}</small></div>
        <ChevronRight size={14} />
      </div>;
    })}</div> : <p className="emptyState"><CircleOff size={15} /> 无连接</p>}
  </section>;
}

export function Inspector({ item, graph, onClose }: {
  item: FlowNodeRecord;
  graph: RunGraph;
  onClose: () => void;
}) {
  const [tab, setTab] = useState<Tab>("fields");
  const incoming = graph.edges.filter((edge) => edge.target === item.id);
  const outgoing = graph.edges.filter((edge) => edge.source === item.id);
  const expectedFields = graph.schema_catalog[item.record.model_name] ?? [];
  const copyJson = () => navigator.clipboard?.writeText(JSON.stringify(item.record.payload, null, 2));
  return <aside className="inspector">
    <header className="inspectorHeader">
      <div className={`inspectorIcon type-${item.node_type}`}><Braces size={19} /></div>
      <div><span>{item.phase} / {item.lane}</span><h2>{item.title}</h2></div>
      <button type="button" className="iconButton" onClick={onClose} aria-label="关闭详情"><X size={18} /></button>
    </header>
    <div className="inspectorMeta">
      <span className={`pill status-${item.status}`}>{item.status}</span>
      <code>{item.id}</code>
    </div>
    <nav className="inspectorTabs" aria-label="节点详情页签">
      <button className={tab === "fields" ? "active" : ""} onClick={() => setTab("fields")}>全部字段</button>
      <button className={tab === "lineage" ? "active" : ""} onClick={() => setTab("lineage")}>上下游</button>
      <button className={tab === "contract" ? "active" : ""} onClick={() => setTab("contract")}>字段合同</button>
    </nav>
    <div className="inspectorScroll">
      {tab === "fields" ? <>
        <section className="modelBanner">
          <div><small>PROJECT MODEL</small><strong>{item.record.model_name}</strong></div>
          <button type="button" onClick={copyJson}><Copy size={14} /> 复制 JSON</button>
        </section>
        <FieldTree value={item.record.payload} />
      </> : null}
      {tab === "lineage" ? <>
        <EdgeList title="输入" edges={incoming} graph={graph} direction="incoming" />
        <EdgeList title="输出" edges={outgoing} graph={graph} direction="outgoing" />
      </> : null}
      {tab === "contract" ? <section className="inspectorSection contractFields">
        <h3>当前源码字段<span>{expectedFields.length}</span></h3>
        <p>fake payload 必须与此清单完全同键；后端测试会拒绝遗漏和额外字段。</p>
        <ol>{expectedFields.map((field) => <li key={field}><code>{field}</code><span>{field in item.record.payload ? "present" : "missing"}</span></li>)}</ol>
      </section> : null}
    </div>
  </aside>;
}

