import type { FlowKeyType } from '../flowProperties.ts';
import { flowProperties } from '../flowProperties';
import { useElementsInfoStore } from '../stores/elementsInfo.ts';
import { getTransformedNodePointForImport } from './shapeCalculate.ts';
import { getAllByLocalName, getPropsData, nodeMap } from './xmlToPropsData';

const elementsInfoStore = useElementsInfoStore();

export default function parseBpmnXmlToGraph(xmlString: string): any {
  const parser = new DOMParser();
  const doc = parser.parseFromString(xmlString, 'text/xml');
  console.warn('doc-->', doc);
  const propsDataList = getPropsData(xmlString);
  elementsInfoStore.clearElements();
  propsDataList.forEach((pd) => {
    elementsInfoStore.updateElement(pd.id, pd);
  });
  // 1) 读取 BPMNDI 中的 shape/edge 布局信息（方便取坐标和边的 waypoints）
  const shapeBoundsByElementId: Record<string, { x: number, y: number, width: number, height: number }> = {};
  const edgeWaypointsByElementId: Record<string, { x: number, y: number }[]> = {};

  const bpmnDiagrams = getAllByLocalName(doc, 'BPMNDiagram');
  for (const diagram of bpmnDiagrams) {
    const planes = getAllByLocalName(diagram, 'BPMNPlane');
    for (const plane of planes) {
      // BPMNShape -> Bounds
      const shapes = getAllByLocalName(plane, 'BPMNShape');
      for (const sh of shapes) {
        const bpmnElement = sh.getAttribute('bpmnElement') || sh.getAttribute('bpmnElement'.toLowerCase());
        if (!bpmnElement) {
          continue;
        }
        const bounds = getAllByLocalName(sh, 'Bounds')[0];
        if (bounds) {
          const bx = Number.parseFloat(bounds.getAttribute('x') || '0');
          const by = Number.parseFloat(bounds.getAttribute('y') || '0');
          // const bw = Number.parseFloat(bounds.getAttribute('width') || '100');
          // const bh = Number.parseFloat(bounds.getAttribute('height') || '40');
          shapeBoundsByElementId[bpmnElement] = { x: bx, y: by, width: 200, height: 40 };
        }
      }
      // BPMNEdge -> waypoint*
      const edgesDi = getAllByLocalName(plane, 'BPMNEdge');
      for (const ed of edgesDi) {
        const bpmnElement = ed.getAttribute('bpmnElement');
        if (!bpmnElement) {
          continue;
        }
        const waypoints = getAllByLocalName(ed, 'waypoint');
        const pts: { x: number, y: number }[] = [];
        for (const wp of waypoints) {
          const x = Number.parseFloat(wp.getAttribute('x') || '0');
          const y = Number.parseFloat(wp.getAttribute('y') || '0');
          pts.push({ x, y });
        }
        if (pts.length) {
          edgeWaypointsByElementId[bpmnElement] = pts;
        }
      }
    }
  }

  // 2) 在 process 下收集节点和连线
  // 找到第一个 process 节点（有命名空间或无）
  let processEl: Element | null = null;
  const allProcesses = getAllByLocalName(doc, 'process');
  if (allProcesses.length) {
    processEl = allProcesses[0];
  }
  // 若没有 process，尝试直接在根下查找一些元素
  const container = processEl || doc;

  const nodes: any[] = [];
  const edges: any[] = [];
  // const defaultEdges: string[] = [];
  // nodes: 遍历支持的 node 标签
  for (const bpmnName of Object.keys(nodeMap)) {
    const els = getAllByLocalName(container, bpmnName);
    for (const el of els) {
      const id = el.getAttribute('id') || `node-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
      const title = el.getAttribute('name') || '';
      const bounds = shapeBoundsByElementId[id];
      const lfType = nodeMap[bpmnName];
      const nodePropInfo = propsDataList.find(pd => pd.id === id);
      const typePropsMap = {
        'start-node': ['formKey', 'executionListener', 'properties', 'documentation'],
        'end-node': ['executionListener', 'properties', 'documentation'],
        'normal-task-node': ['executionListener', 'properties', 'documentation'],
        'exclusive-gateway-node': ['executionListener', 'properties', 'documentation'],
        'parallel-gateway-node': ['executionListener', 'properties', 'documentation'],
        'user-task-node': ['formKey', 'userTask', 'executionListener', 'properties', 'documentation', 'approvalModePrecent', 'approveMethod', 'customConfiguration', 'taskListener'],
      };
      const kayArr = typePropsMap[lfType as keyof typeof typePropsMap];
      const propOnj: any = {};
      for (const key of kayArr) {
        if (key === 'userTask') {
          propOnj[key] = nodePropInfo.userTaskProps;
        }
        else {
          propOnj[key] = nodePropInfo[key];
        }
      }
      const newPoint = getTransformedNodePointForImport(bounds.x, bounds.y, lfType);
      const node = {
        id,
        type: lfType,
        x: newPoint.x || 100,
        y: newPoint.y || 100,
        text: title,
        properties: {
          title,
          type: lfType,
          iconName: flowProperties[lfType as FlowKeyType].iconName || 'QuestionOutlined',
          width: 200,
          height: 40,
          ...propOnj,
        },
      };
      if (el.getAttribute('default')) {
        node.properties.default = el.getAttribute('default');
      }
      nodes.push(node);
    }
  }

  // edges: sequenceFlow
  const seqs = getAllByLocalName(container, 'sequenceFlow');
  for (const sf of seqs) {
    const id = sf.getAttribute('id') || `edge-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
    const name = sf.getAttribute('name') || '';
    const sourceRef = sf.getAttribute('sourceRef') || sf.getAttribute('source') || '';
    const targetRef = sf.getAttribute('targetRef') || sf.getAttribute('target') || '';
    // const pts = edgeWaypointsByElementId[id];
    const startNode = nodes.find(n => n.id === sourceRef);
    const startPoint = { x: startNode.x + 100, y: startNode.y };
    const endNode = nodes.find(n => n.id === targetRef);
    const endPoint = { x: endNode.x - 100, y: endNode.y };
    // const midX = getSmallX(startPoint, endPoint) + Math.abs(startPoint.x - endPoint.x) / 2;
    const pointsList: { x: number, y: number }[] = [];
    // 获得贝塞尔曲线的控制点信息
    pointsList[0] = startPoint;
    pointsList[1] = { x: startPoint.x + 100, y: startPoint.y };
    pointsList[2] = { x: endPoint.x - 100, y: endPoint.y };
    pointsList[3] = endPoint;
    // const isDefault = defaultEdges.includes(id);
    const edgePropInfo = propsDataList.find(pd => pd.id === id);
    const edge: any = {
      id,
      type: 'custom-bezier-edge', // 与项目中默认边类型保持一致
      startPoint,
      endPoint,
      sourceNodeId: sourceRef,
      sourceAnchorId: `${sourceRef}_right`,
      targetNodeId: targetRef,
      targetAnchorId: `${targetRef}_left`,
      pointsList,
      text: name,
      properties: {
        // text: name,
        title: name,
        selected: false,
      },
    };
    if (edgePropInfo) {
      edge.properties.arrowType = edgePropInfo.edgeTransfer?.type;
      edge.properties.edgeTransfer = edgePropInfo.edgeTransfer;
    }

    edges.push(edge);
  }

  // 回退布局：若 nodes 没有坐标（没有 BPMNDI），进行简单网格布局
  // const anyNodeHasPos = nodes.some(n => typeof n.x === 'number' && typeof n.y === 'number');
  // if (!anyNodeHasPos) {
  //   const gapX = 200;
  //   const gapY = 140;
  //   nodes.forEach((n, idx) => {
  //     const row = Math.floor(idx / 6);
  //     const col = idx % 6;
  //     n.x = 100 + col * gapX;
  //     n.y = 80 + row * gapY;
  //     if (!n.width) {
  //       n.width = 100;
  //     }
  //     if (!n.height) {
  //       n.height = 40;
  //     }
  //   });
  // }

  // console.log('parsed graph nodes:', nodes);
  // console.log('parsed graph edges:', edges);
  return { nodes, edges };
}
