import dagre from "@dagrejs/dagre";
import { LayoutAlgorithm } from "..";
import { getIncomers, Node } from "@xyflow/react";
import { getEdgeLayouted, getNodeLayouted, getNodeSize } from "../../metadata";
import { randomInt } from "../../../utils/base";

// 布局配置常量
const LAYOUT_CONFIG = {
  VIRTUAL_ROOT_ID: '#root',
  VIRTUAL_NODE_SIZE: 1,
  RANKER: 'tight-tree',
} as const;

// 创建并配置 dagre 图实例
const createDagreGraph = () => {
  const graph = new dagre.graphlib.Graph();
  graph.setDefaultEdgeLabel(() => ({}));
  return graph;
};

// 获取布局方向配置
const getLayoutConfig = (
  direction: 'horizontal' | 'vertical',
  spacing: { x: number, y: number },
  graph: dagre.graphlib.Graph
) => ({
  nodesep: direction === 'horizontal' ? spacing.y : spacing.x,
  ranksep: direction === 'horizontal' ? spacing.x : spacing.y,
  ranker: LAYOUT_CONFIG.RANKER,
  rankdir: direction === 'horizontal' ? 'LR' : 'TB',

});

// 查找根节点
const findRootNodes = (nodes: Node[], edges: any[]): Node[] =>
  nodes.filter(node => getIncomers(node, nodes, edges).length < 1);

// 计算节点边界
const calculateBounds = (nodes: Node[], graph: dagre.graphlib.Graph) => {
  const bounds = {
    minX: Number.POSITIVE_INFINITY,
    minY: Number.POSITIVE_INFINITY,
    maxX: Number.NEGATIVE_INFINITY,
    maxY: Number.NEGATIVE_INFINITY,
  };

  nodes.forEach(node => {
    const pos = graph.node(node.id);
    if (pos) {
      bounds.minX = Math.min(bounds.minX, pos.x);
      bounds.minY = Math.min(bounds.minY, pos.y);
      bounds.maxX = Math.max(bounds.maxX, pos.x);
      bounds.maxY = Math.max(bounds.maxY, pos.y);
    }
  });

  return bounds;
};

export const layoutDagreTree: LayoutAlgorithm = async ({
  nodes,
  edges,
  direction,
  visibility,
  spacing
}) => {
  const dagreGraph = createDagreGraph();

  // 设置图的布局参数
  dagreGraph.setGraph(getLayoutConfig(direction, spacing, dagreGraph));

  // 添加节点
  nodes.forEach((node) => {
    const { widthWithDefault, heightWithDefault } = getNodeSize(node);
    dagreGraph.setNode(node.id, {
      width: widthWithDefault,
      height: heightWithDefault,
      order: randomInt(0, 10)
    });
  });

  // 添加边
  edges.forEach(edge => dagreGraph.setEdge(edge.source, edge.target));

  // 处理多个子工作流的情况
  const rootNodes = findRootNodes(nodes, edges);
  if (rootNodes.length > 1) {
    dagreGraph.setNode(LAYOUT_CONFIG.VIRTUAL_ROOT_ID, {
      width: LAYOUT_CONFIG.VIRTUAL_NODE_SIZE,
      height: LAYOUT_CONFIG.VIRTUAL_NODE_SIZE,
      rank: -1 // 确保虚拟根节点排在最前面
    });
    rootNodes.forEach(node =>
      dagreGraph.setEdge(LAYOUT_CONFIG.VIRTUAL_ROOT_ID, node.id)
    );
  }

  // 执行布局
  dagre.layout(dagreGraph);

  // 移除虚拟根节点
  if (rootNodes.length > 1) {
    dagreGraph.removeNode(LAYOUT_CONFIG.VIRTUAL_ROOT_ID);
  }

  // 计算边界并返回布局结果
  const bounds = calculateBounds(nodes, dagreGraph);

  return {
    nodes: nodes.map(node => getNodeLayouted({
      node,
      position: dagreGraph.node(node.id),
      direction,
      visibility,
      fixPosition: ({ x, y, width, height }) => ({
        x: x - width / 2 - bounds.minX,
        y: y - height / 2 - bounds.minY,
      }),
    })),
    edges: edges.map(edge => getEdgeLayouted({ edge, visibility })),
  };
};