import { useEffect, useMemo, useRef, useState } from "react";
import { TopBar } from "./components/TopBar/TopBar";
import { MainContent } from "./components/MainContent/MainContent";
import { DetailPanel } from "./components/DetailPanel/DetailPanel";

import type { Goal } from "./types/goal";
import type { Edge, Message } from "./types/message";
import { useFlowChartData } from "./components/FlowChart/hooks/useFlowChartData";
import "./styles/global.css";

function App() {
  const [selectedTraceId, setSelectedTraceId] = useState<string | null>(null);
  const [selectedTraceTitle, setSelectedTraceTitle] = useState("流程图可视化系统");
  const [selectedNode, setSelectedNode] = useState<Goal | Message | null>(null);
  const [selectedEdge, setSelectedEdge] = useState<Edge | null>(null);
  const [rightWidth, setRightWidth] = useState(360);
  const [isDragging, setIsDragging] = useState(false);

  const [refreshTrigger, setRefreshTrigger] = useState(0);
  const [messageRefreshTrigger, setMessageRefreshTrigger] = useState(0);
  const bodyRef = useRef<HTMLDivElement | null>(null);

  // 获取数据以传递给 DetailPanel
  const { msgGroups } = useFlowChartData(selectedTraceId, messageRefreshTrigger);

  const handleNodeClick = (node: Goal | Message, edge?: Edge) => {
    setSelectedNode(node);
    setSelectedEdge(edge || null);
  };

  const handleCloseDetail = () => {
    setSelectedNode(null);
    setSelectedEdge(null);
  };

  const isGoalNode = (node: Goal | Message): node is Goal => "status" in node && "created_at" in node;

  // 根据选中的节点获取对应的消息
  const selectedMessages = useMemo(() => {
    if (selectedNode) {
      if (isGoalNode(selectedNode)) {
        return msgGroups[selectedNode.id] || [];
      }
      return [selectedNode as Message];
    }
    // 如果点击的是边，且该边是主链上的边，通常我们显示源节点的消息（如果需要）
    // 但根据用户需求 "边里面的信息，显示对应msgGroup里面的所有的子集的描述"
    // 如果 selectedEdge 存在且 selectedNode 为空（虽然目前逻辑是联动），这里可以做处理
    // 目前 handleNodeClick 会设置 selectedNode 为 link.source
    // 所以 selectedNode.id 就是边的源节点 ID，直接取 msgGroups 即可
    return [];
  }, [selectedNode, msgGroups]);

  useEffect(() => {
    if (!isDragging) return;
    const handleMove = (event: MouseEvent) => {
      const rect = bodyRef.current?.getBoundingClientRect();
      if (!rect) return;
      const next = rect.right - event.clientX;
      const clamped = Math.min(800, Math.max(240, next));
      setRightWidth(clamped);
    };
    const handleUp = () => {
      setIsDragging(false);
    };
    window.addEventListener("mousemove", handleMove);
    window.addEventListener("mouseup", handleUp);
    return () => {
      window.removeEventListener("mousemove", handleMove);
      window.removeEventListener("mouseup", handleUp);
    };
  }, [isDragging]);

  return (
    <div className="app">
      <div className="app-top">
        <TopBar
          selectedTraceId={selectedTraceId}
          selectedNode={selectedNode}
          title={selectedTraceTitle}
          onTraceSelect={(id, title) => {
            setSelectedTraceId(id);
            if (title) setSelectedTraceTitle(title);
          }}
          onTraceCreated={() => setRefreshTrigger((t) => t + 1)}
          onMessageInserted={() => setMessageRefreshTrigger((t) => t + 1)}
        />
      </div>
      <div
        className="app-body"
        ref={bodyRef}
        style={{ userSelect: isDragging ? "none" : "auto" }}
      >
        <div className="app-main">
          <MainContent
            traceId={selectedTraceId}
            onNodeClick={handleNodeClick}
            onTraceChange={(id, title) => {
              setSelectedTraceId(id);
              if (title) setSelectedTraceTitle(title);
            }}
            refreshTrigger={refreshTrigger}
            messageRefreshTrigger={messageRefreshTrigger}
          />
        </div>
        {(selectedNode || selectedEdge) && (
          <>
            <div
              className="app-splitter"
              onMouseDown={() => setIsDragging(true)}
              role="separator"
              aria-orientation="vertical"
              aria-valuenow={rightWidth}
              aria-valuemin={240}
              aria-valuemax={800}
            />
            <div
              className="app-right"
              style={{ width: rightWidth }}
            >
              <DetailPanel
                node={selectedNode}
                edge={selectedEdge}
                messages={selectedMessages as Message[]}
                onClose={handleCloseDetail}
              />
            </div>
          </>
        )}
      </div>
    </div>
  );
}

export default App;
