/**
 * Graph 交互处理 — 鼠标悬停/点击/拖拽事件
 */

import type { GraphNode, GraphEdge, NodePosition, HoverState } from './graphTypes';
import { getNodeDegree, degreeToRadius } from './graphLayout';
import { NODE_HOVER_SCALE } from './graphConstants';

/** 鼠标移动 — 检测 hover 节点 */
export function handleCanvasMouseMove(
  e: React.MouseEvent<HTMLCanvasElement>,
  canvas: HTMLCanvasElement,
  positions: Map<string, NodePosition>,
  nodes: GraphNode[],
  edges: GraphEdge[],
  selectedCenter: string | null,
  setHoverState: (state: HoverState | ((prev: HoverState) => HoverState)) => void,
) {
  const rect = canvas.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;

  let foundId: string | null = null;
  for (const node of nodes) {
    const pos = positions.get(node.id);
    if (!pos) continue;
    const degree = getNodeDegree(node.id, edges);
    const r = degreeToRadius(degree, node.id === selectedCenter) * NODE_HOVER_SCALE;
    const dx = x - pos.x;
    const dy = y - pos.y;
    if (dx * dx + dy * dy < r * r) {
      foundId = node.id;
      break;
    }
  }

  canvas.style.cursor = foundId ? 'pointer' : 'default';
  setHoverState((prev) => {
    if (prev.nodeId === foundId) return prev;
    return { nodeId: foundId, x, y };
  });

  if (foundId) {
    setHoverState({ nodeId: foundId, x, y });
  }
}

/** 鼠标离开 — 清除 hover 状态 */
export function handleCanvasMouseLeave(
  setHoverState: (state: HoverState) => void,
) {
  setHoverState({ nodeId: null, x: 0, y: 0 });
}

/** 鼠标点击 — 选择/取消中心节点 */
export function handleCanvasClick(
  e: React.MouseEvent<HTMLCanvasElement>,
  canvas: HTMLCanvasElement,
  positions: Map<string, NodePosition>,
  nodes: GraphNode[],
  edges: GraphEdge[],
  selectedCenter: string | null,
  setSelectedCenter: (fn: (prev: string | null) => string | null) => void,
) {
  const rect = canvas.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;

  for (const node of nodes) {
    const pos = positions.get(node.id);
    if (!pos) continue;
    const degree = getNodeDegree(node.id, edges);
    const r = degreeToRadius(degree, node.id === selectedCenter);
    const dx = x - pos.x;
    const dy = y - pos.y;
    if (dx * dx + dy * dy < r * r) {
      setSelectedCenter((prev) => (prev === node.id ? null : node.id));
      return;
    }
  }
}
