"use client";

import { useEffect, useMemo, useState } from "react";
import {
  Background,
  BackgroundVariant,
  Controls,
  ReactFlow,
  type Edge,
  type Node,
} from "@xyflow/react";
import { Users } from "lucide-react";

// React Flow 样式必须显式引入（组件经 dynamic ssr:false 加载，样式随该 chunk 打包）。
import "@xyflow/react/dist/style.css";

import { EmptyState } from "@/components/ui/EmptyState";
import {
  buildRelationshipGraph,
  NODE_WIDTH,
  type GraphNode,
} from "@/lib/characters/graphLayout";
import type { CharacterCardView } from "@/lib/api/types";

interface RelationshipGraphProps {
  characters: CharacterCardView[];
}

// 纸感节点样式：面板底 + 细线框 + 左侧按分组配色的强调条（色值走主题 CSS 变量）。
function paperNodeStyle(colorVar: string): React.CSSProperties {
  return {
    width: NODE_WIDTH,
    padding: "8px 10px",
    borderRadius: 6,
    background: "var(--color-panel)",
    color: "var(--color-ink)",
    border: "1px solid var(--color-line)",
    borderLeft: `4px solid var(${colorVar})`,
    boxShadow: "0 1px 3px var(--shadow-paper)",
    fontSize: 12,
    textAlign: "left",
  };
}

// 节点内容：角色名（宋体）+ 定位副标题。
function NodeLabel({ name, role }: { name: string; role: string }) {
  return (
    <div className="min-w-0">
      <p className="truncate font-serif text-sm text-ink">{name}</p>
      {role ? <p className="truncate text-2xs text-ink-soft">{role}</p> : null}
    </div>
  );
}

function toReactFlowNodes(nodes: GraphNode[]): Node[] {
  return nodes.map((node) => ({
    id: node.id,
    position: node.position,
    data: { label: <NodeLabel name={node.data.label} role={node.data.role} /> },
    style: paperNodeStyle(node.data.colorVar),
    // 只读可视化：可拖动重排，不可新建连线。
    connectable: false,
  }));
}

function toReactFlowEdges(
  edges: { id: string; source: string; target: string; label: string }[],
): Edge[] {
  return edges.map((edge) => ({
    id: edge.id,
    source: edge.source,
    target: edge.target,
    label: edge.label,
    labelStyle: { fill: "var(--color-ink-soft)", fontSize: 11 },
    labelBgStyle: { fill: "var(--color-bg)", fillOpacity: 0.9 },
    labelBgPadding: [4, 2] as [number, number],
    labelBgBorderRadius: 4,
    style: { stroke: "var(--color-line)", strokeWidth: 1.5 },
  }));
}

// 尊重 prefers-reduced-motion：减动偏好下关闭 fitView 平滑动画与边流动动画。
function usePrefersReducedMotion(): boolean {
  const [reduced, setReduced] = useState(false);
  useEffect(() => {
    const media = window.matchMedia("(prefers-reduced-motion: reduce)");
    const update = () => setReduced(media.matches);
    update();
    media.addEventListener("change", update);
    return () => media.removeEventListener("change", update);
  }, []);
  return reduced;
}

// 角色关系图谱（灵感⑥ 缩减版 / D4）：只用现有 relations 数据，节点按 role 上色、
// 边按 name-join、kind 作中文标签。悬空边（引用未入库角色）已在 graphLayout 略过并计数。
export function RelationshipGraph({ characters }: RelationshipGraphProps) {
  const reducedMotion = usePrefersReducedMotion();

  const graph = useMemo(
    () => buildRelationshipGraph(characters),
    [characters],
  );
  const nodes = useMemo(() => toReactFlowNodes(graph.nodes), [graph.nodes]);
  const edges = useMemo(() => toReactFlowEdges(graph.edges), [graph.edges]);

  if (graph.nodes.length === 0) {
    return (
      <EmptyState
        icon={Users}
        title="暂无可视化的人物"
        description="先入库角色并登记彼此关系，这里会绘制出关系图谱。"
      />
    );
  }

  return (
    <div className="flex flex-col gap-2">
      {/* React Flow 必须有显式尺寸的容器，否则画布高度为 0。 */}
      <div className="h-[28rem] w-full overflow-hidden rounded border border-line bg-bg">
        <ReactFlow
          nodes={nodes}
          edges={edges}
          fitView
          fitViewOptions={{ padding: 0.2, duration: reducedMotion ? 0 : 400 }}
          nodesConnectable={false}
          edgesFocusable={false}
          proOptions={{ hideAttribution: false }}
          minZoom={0.2}
          maxZoom={1.75}
          defaultEdgeOptions={{ animated: false }}
        >
          <Background
            variant={BackgroundVariant.Dots}
            gap={20}
            size={1}
            color="var(--color-line)"
          />
          <Controls showInteractive={false} />
        </ReactFlow>
      </div>
      {graph.danglingCount > 0 ? (
        <p className="text-2xs text-ink-soft">
          有 {graph.danglingCount} 条关系引用了未入库的角色，已略过。
        </p>
      ) : null}
    </div>
  );
}
