import { Graph } from '@antv/x6';
import { Snapline } from '@antv/x6-plugin-snapline';
import { Selection } from '@antv/x6-plugin-selection';
import { createNodeWithBorderPorts, registerAlgoNode } from '@/api/rule/node';
import { registerNodeDeleteTool } from '@/api/rule/nodeTools';
import { Stencil } from '@antv/x6-plugin-stencil';
import { getEdgeLables, registerEdgeDeleteTool } from '@/api/rule/edgeTools';
import { emitter } from '@/utils/eventBus';


export function CreateAntVX6setupGraph(
  graphContainer: HTMLElement,
  stencilContainer: HTMLElement,
  isFormVisible: Ref<boolean>,
  selectedNode: Ref<any>,
  proxy: any,
  showSaveFlag: Ref<boolean>
) {
  const containerWidth = window.innerWidth * 0.85;
  const containerHeight = window.innerHeight * 0.9;

  // 创建图形实例并启用连接、对齐线和滚动画布
  const graph = new Graph({
    container: graphContainer,
    background: {
      color: '#F2F7FA'
    },
    grid: true,
    width: containerWidth,
    height: containerHeight,
    panning: true, // 画布可拖动
    connecting: {
      snap: true,
      allowBlank: false,
      allowLoop: false,
      allowMulti: false,
      allowEdge: false,
      highlight: true,
      router: { name: 'manhattan' },
      connector: { name: 'rounded' },
      createEdge() {
        return graph.createEdge({
          shape: 'edge',
          attrs: {
            line: {
              stroke: '#8f8f8f',
              strokeWidth: 1
            }
          }
        });
      },
      validateEdge({ edge }) {
        const sourceNode = edge.getSourceCell();
        const targetNode = edge.getTargetCell();
        if (!sourceNode || !targetNode) {
          return true;
        }
        const isStartNode = targetNode.getData()?.type === 'start';
        const isEndNode = sourceNode.getData()?.type === 'end';
        if (isStartNode) {
          proxy?.$modal.msgError('开始节点不能作为连线终点');
          return false;
        }
        if (isEndNode) {
          proxy?.$modal.msgError('结束节点不能作为连线起点');
          return false;
        }
        //规则节点、计算节点、赋值节点只能有一个出边
        if (sourceNode.getData()?.type === 'filters' || sourceNode.getData()?.type === 'edits' || sourceNode.getData()?.type === 'calendar') {
          const count = graph.getOutgoingEdges(sourceNode).length;
          if (count > 1) {
            proxy?.$modal.msgError('规则节点、赋值节点、计算节点只能有一个出边');
            return false;
          }
        }
        //赋值节点不能直接连接结束节点
        if (sourceNode.getData()?.type === 'edits' && targetNode.getData()?.type === 'end') {
          proxy?.$modal.msgError('赋值节点不能直接连接结束节点');
          return false;
        }
        return true;
      }
    }
  });

  // 使用对齐线插件
  graph.use(new Snapline({ enabled: true, sharp: true }));
  // 使用框选插件
  graph.use(
    new Selection({
      enabled: true,
      movable: true,
      showNodeSelectionBox: true,
      showEdgeSelectionBox: true,
      pointerEvents: 'none'
    })
  );

  // 定义显示或隐藏端口的函数
  const togglePortsVisibility = (node, show) => {
    const ports = node.getPorts();
    ports.forEach((port) => {
      node.setPortProp(port.id, 'attrs/circle', {
        fill: show ? '#fff' : 'transparent',
        stroke: show ? '#31d0c6' : 'transparent'
      });
    });

    if (showSaveFlag && show && !node.hasTools('delete-node-tool')) {
      node.addTools([{ name: 'delete-node-tool' }]);
    } else {
      node.removeTools();
    }
  };

  // 监听鼠标进入节点事件
  graph.on('node:mouseenter', ({ node }) => {
    togglePortsVisibility(node, true);
  });

  // 监听鼠标离开节点事件
  graph.on('node:mouseleave', ({ node }) => {
    togglePortsVisibility(node, false);
  });

  // 监听节点选择事件
  graph.on('node:click', ({ node }) => {
    graph.getEdges().forEach((edge) => {
      edge.attr({
        line: { stroke: '#8f8f8f', strokeWidth: 1 }
      });
    });

    highlightConnectedEdges(node, 'source', '#007bff'); // 出边颜色
    highlightConnectedEdges(node, 'target', '#28a745'); // 入边颜色

    const type = node.getData().type;
    node.data.id = node.id;
    selectedNode.value = node.getData();
    if (type !== 'start' && type !== 'end') {
      isFormVisible.value = true;
    }
  });
  //监听边的创建
  graph.on('edge:connected', ({ isNew, edge }) => {
    if (isNew) {
      const sourceNode = edge.getSourceCell();
      if (sourceNode.getData().type == 'rank') {
        const count = graph.getOutgoingEdges(sourceNode).length;
        // 设置边上的标签，使用 attrs 来定义文本和背景样式
        edge.setLabels(getEdgeLables(count));
      }
      //如果是选中的节点新建了边，则触发事件
      if (selectedNode.value && sourceNode.id == selectedNode.value.id) {
        emitter.emit('edgesUpdated', edge);
      }
    }
  });
  //删除边的监听
  graph.on('edge:removed', ({ edge, index, options }) => {
    //未连线成功的边删除导致的报错
    try {
      const label = edge.store.data.labels[0].attrs.label.text;
      //更新边的标签
      const node = graph.getCellById(edge.store.data.source.cell);
      const edges = graph.getOutgoingEdges(node);
      edges.forEach((edge) => {
        const labels = edge.getLabels();
        const edgeLabel = labels[0].attrs.label.text;
        if (edgeLabel > label) {
          edge.setLabels(getEdgeLables(edgeLabel - 1));
        }
      });
      if (selectedNode.value && edge.store.data.source.cell == selectedNode.value.id) {
        emitter.emit('edgesUpdated', edge);
      }
    } catch (e) {}
  });

  // 监听鼠标进入边的事件
  graph.on('edge:mouseenter', ({ edge }) => {
    if (showSaveFlag && !edge.hasTools('delete-edge-tool')) {
      edge.addTools([{ name: 'delete-edge-tool', args: { distance: 0.5 } }]);
    }
    edge.attr({
      line: { stroke: '#007bff', strokeWidth: 3 }
    });
  });
  // 监听鼠标离开边的事件
  graph.on('edge:mouseleave', ({ edge }) => {
    edge.removeTools('delete-edge-tool');
    edge.attr({
      line: { stroke: '#8f8f8f', strokeWidth: 1 }
    });
  });

  // 监听空白点击以清除选中状态及高亮
  graph.on('blank:click', () => {
    graph.getEdges().forEach((edge) => {
      edge.attr({
        line: { stroke: '#8f8f8f', strokeWidth: 1 }
      });
    });
    isFormVisible.value = false;
  });

  // 定义一个函数用于高亮指定方向的边
  function highlightConnectedEdges(node, direction, color) {
    graph.getEdges().forEach((edge) => {
      const sourceNodeId = edge.getSourceCell()?.id;
      const targetNodeId = edge.getTargetCell()?.id;

      if ((direction === 'source' && sourceNodeId === node.id) || (direction === 'target' && targetNodeId === node.id)) {
        edge.attr({
          line: { stroke: color, strokeWidth: 3 }
        });
      }
    });
  }

  // 注册自定义节点
  registerAlgoNode();
  // 注册节点删除工具
  registerNodeDeleteTool(proxy);
  // 注册边的删除工具
  registerEdgeDeleteTool(proxy);

  // 创建Stencil实例
  const stencil = new Stencil({
    title: '输入输出',
    target: graph,
    collapsable: false,
    stencilGraphWidth: 370,
    stencilGraphHeight: 95,
    layoutOptions: {
      columns: 1,
      columnWidth: 180,
      rowHeight: 40
    },
    groups: [
      {
        name: 'group1',
        title: '输入输出',
        collapsable: false
      },
      {
        name: 'group2',
        title: '数据处理',
        graphHeight: 300,
        collapsable: false
      }
    ]
  });

  stencilContainer.appendChild(stencil.container);

  // 创建一些初始节点并加载到Stencil中
  const start = createNodeWithBorderPorts('开始节点', 'start');
  const end = createNodeWithBorderPorts('结束节点', 'end');
  const rank = createNodeWithBorderPorts('条件节点', 'rank');
  const filters = createNodeWithBorderPorts('规则节点', 'filters');
  const edits = createNodeWithBorderPorts('赋值节点', 'edits');
  const calendar = createNodeWithBorderPorts('计算节点', 'calendar');
  stencil.load([start, end], 'group1');
  stencil.load([rank, filters, edits, calendar], 'group2');
  return graph; // 返回图形实例，以便在组件中使用
}
