import type { ProcessNode } from "../types/process";
import { GAP_X, GAP_Y, START_Y, MIDDMLE_X } from "../configs";

//创建节点
function createNode(
  raw: ProcessNode,
  level = 0,
  index = 0,
  max = 0,
  _middle = -1
) {
  let x = 0;
  const _index = index + 1;
  const y = START_Y + Number(level) * GAP_Y;
  const middle = _middle >= 0 ? _middle + 1 : Math.ceil(max / 2);

  if (_index === middle || max === 0) x = MIDDMLE_X;
  if (_index > middle) x = MIDDMLE_X + middle * GAP_X;
  if (_index < middle) x = MIDDMLE_X - middle * GAP_X;

  return {
    id: raw.order_process,
    text: raw.status_name,
    type: "NormalTask",
    x,
    y
  };
}

//创建开始节点
function createStartNode(source: ProcessNode[]) {
  const raw = source.find(({ action_type }) => action_type == "1");
  const start = createNode(raw!);

  return {
    start,
    startRaw: raw!
  };
}

//创建连线
function createEdge(sourceNodeId: string, targetNodeId: string) {
  return {
    sourceNodeId,
    targetNodeId,
    isHitable: false,
    type: "dashe-edge"
  };
}

//根据开始节点递归寻找生成其他节点和连线
function createNodes(source: ProcessNode[], startNode: ProcessNode) {
  const nodesRaw: any[] = [];
  const edgesRaw: any[] = [];

  function convert(raw: ProcessNode, parent = "0", level = 0) {
    level++;
    const { next_actions } = raw;
    const next = source.filter(({ status_name }) =>
      next_actions.includes(status_name)
    );

    for (let i = 0; i < next.length; i++) {
      const index = i;
      const current = next[i];
      const maxLength = next.length;
      const _middle = next.findIndex(({ isMain }) => isMain);
      const edge = createEdge(parent, current.order_process);
      const node = createNode(current, level, index, maxLength, _middle);

      const prevSameNodeIndex = nodesRaw.findIndex(
        ({ text }) => text === node.text
      );
      if (prevSameNodeIndex >= 0) nodesRaw.splice(prevSameNodeIndex, 1);
      nodesRaw.push(node);
      edgesRaw.push(edge);
      if (current.next_actions.length > 0)
        convert(current, current.order_process, level);
    }
  }

  convert(startNode, startNode.order_process);

  return {
    nodesRaw,
    edgesRaw
  };
}

//根据审批记录改变连线和节点类型
function createNodesWithRecord(
  nodesRaw: any[],
  edgesRaw: any[],
  record: any[]
) {
  for (let i = 0; i < record.length; i++) {
    const current = record[i];
    const next = record[i + 1];
    const isLast = i === record.length - 1;
    const sourceNodeIndex = nodesRaw.findIndex(
      ({ id }) => id === current.order_process
    );
    if (sourceNodeIndex >= 0) {
      nodesRaw[sourceNodeIndex].type = isLast ? "ProcessTask" : "FinishTask";
      nodesRaw[sourceNodeIndex].properties = {
        name: current.action_name,
        time: current.addtime
      };
    }

    const sourceEdgeIndex = edgesRaw.findIndex(
      ({ sourceNodeId, targetNodeId }) => {
        return (
          String(sourceNodeId) === String(current?.order_process) &&
          String(targetNodeId) === String(next?.order_process)
        );
      }
    );
    if (sourceEdgeIndex >= 0) edgesRaw[sourceEdgeIndex].type = "polyline";
  }

  return {
    edges: edgesRaw,
    nodes: nodesRaw
  };
}

export function createProcessData(source: ProcessNode[], record: any[]) {
  const processChart = {
    nodes: [] as any[],
    edges: [] as any[]
  };

  const { start, startRaw } = createStartNode(source!);
  const { nodesRaw: _nodesRaw, edgesRaw } = createNodes(source, startRaw);

  const nodesRaw = [start, ..._nodesRaw];

  const { nodes, edges } = createNodesWithRecord(nodesRaw, edgesRaw, record);

  processChart.nodes.push(...nodes);
  processChart.edges.push(...edges);

  return processChart;
}
