import { FLOW_NODE_TYPE_ENUM } from '@/utils/enum/flow';
import { ElMessage } from 'element-plus';

/**
 * 校验流程合理性
 * @param cells
 */
export const getRelationNodeAndVerifyFlowFun = (cells:any, templateName:string, uuid:string) => {
  console.log('cells', cells);
  const nodeArr = [];
  const edgeArr = [];
  for (let index = 0; index < cells.length; index++) {
    if (cells[index].shape === 'edge') {
      edgeArr.push({
        target: cells[index].target.cell,
        source: cells[index].source.cell,
        id: cells[index].id,
      });
    }
    if (cells[index].shape === 'custom-app-vue-node' || cells[index].shape === 'custom-local-vue-node') {
      nodeArr.push({
        ...cells[index].data,
        id: cells[index].id,
        shape: cells[index].shape,
      });
    }
  }
  if (!checkStartEndNode(nodeArr)) {
    return false;
  }
  const relationNode = sortNodeAndEdge(nodeArr, edgeArr);
  if (!relationNode) {
    return false;
  }
  const formatElementArr = formatNodeAndEdge(edgeArr, nodeArr);
  const formatElementOjb = {
    process: {
      id: uuid,
      name: templateName,
    },
    flowElements: formatElementArr,
  };
  console.log('formatElementArr', formatElementArr);
  return formatElementOjb;
};
const sortNodeAndEdge = (nodeArr: any, edgeArr: any) => {
  try {

    console.log('nodeArr edgeArr', nodeArr, edgeArr);
    const startNode = nodeArr.find((item: any) => item.nodeType === FLOW_NODE_TYPE_ENUM.START);
    // const endNode = nodeArr.find((item: any) => item.nodeType === FLOW_NODE_TYPE_ENUM.END);
    // console.log('startNode', startNode);
    // console.log('endNode', endNode);
    console.log('生成一个树结构的节点数据');
    getNodeRelation(startNode, [startNode.id], nodeArr, edgeArr);
    const relationNode = startNode;
    // console.log('relationNode', startNode);

    const repeatNodeObj:any = {};
    for (let index = 0; index < edgeArr.length; index++) {
      if (!repeatNodeObj[edgeArr[index].target]) {
        repeatNodeObj[edgeArr[index].target] = [];
      }
      for (let j = 0; j < edgeArr.length; j++) {
        if (index !== j) {
          if (edgeArr[index].target === edgeArr[j].target) {
            repeatNodeObj[edgeArr[index].target].push(edgeArr[j].source);
          }
        }
      }
    }
    // 获取需要处理前置条件的节点，即多个节点指向当前节点
    const repeatNodeArr = [];

    for (const key in repeatNodeObj) {
      if (repeatNodeObj[key].length > 0) {
        repeatNodeArr.push({
          selfId: key,
          repeatIds: repeatNodeObj[key],
        });
      }
    }
    console.log('开始向node里插入preNode');
    insertRepeatToNode([relationNode], repeatNodeArr, nodeArr);

    const includeIds:string[] = [];
    console.log('校验流程尾部是否都为结束节点');
    if (!verifyEndNode([relationNode], includeIds)) {
      return false;
    }
    if (includeIds.length !== nodeArr.length) {
      ElMessage.error('存在连接不完整的节点！');

      return false;
    }

    console.log('repeatNodeArr', repeatNodeArr);
    return relationNode;
  } catch (error) {
    console.log('error', error);
    ElMessage.error('拖拽的流程存在循环，不符合规则！');
    return false;
  }
};

/**
 * 生成一个树结构的节点数据
 * @param preNode 上一个节点
 * @param includeNode 已包含的节点
 * @param nodeArr
 * @param edgeArr
 */
const getNodeRelation = (preNode:any, includeId:any, nodeArr: any, edgeArr: any) => {
  preNode.children = [];
  for (let index = 0; index < edgeArr.length; index++) {
    if (edgeArr[index].source === preNode.id) {
      const nextNode = nodeArr.find((item:any) => item.id === edgeArr[index].target);
      includeId.push(nextNode.id);
      getNodeRelation(nextNode, includeId, nodeArr, edgeArr);
      preNode.children.push(nextNode);
    }
  }
};

const insertRepeatToNode = (relationNode:any, repeatNodeArr:any, nodeArr:any) => {
  for (let index = 0; index < relationNode.length; index++) {
    for (let j = 0; j < repeatNodeArr.length; j++) {
      if (relationNode[index].id === repeatNodeArr[j].selfId) {
        // console.log('relationNode[index]' + index, relationNode[index].label, relationNode[index].id);
        // console.log('repeatNodeArr' + index, repeatNodeArr[j]);
        relationNode[index].preNode = repeatNodeArr[j].repeatIds.map((item:any) => {
          return { ...nodeArr.find((node:any) => node.id === item), children: [] };
        });
      }
    }
    if (relationNode[index].children.length > 0) {
      insertRepeatToNode(relationNode[index].children, repeatNodeArr, nodeArr);
    }
  }
};

const verifyEndNode = (nodeArr:any, includeIds:string[]):boolean => {
  let isEnd = true;
  for (let index = 0; index < nodeArr.length; index++) {
    if (!includeIds.includes(nodeArr[index].id)) {
      includeIds.push(nodeArr[index].id);
    }
    if (nodeArr[index].children.length > 0 ) {
      if (isEnd) {
        isEnd = verifyEndNode(nodeArr[index].children, includeIds);
      }
    } else {
      if (nodeArr[index].nodeType !== FLOW_NODE_TYPE_ENUM.END) {
        ElMessage.error('拖拽的流程节点未形成闭环，不符合规则！');
        return false;
      }
    }
  }
  return isEnd;
};

const checkStartEndNode = (nodeArr: any) => {
  let startNum = 0;
  let endNum = 0;
  for (let index = 0; index < nodeArr.length; index++) {
    if (nodeArr[index].nodeType === FLOW_NODE_TYPE_ENUM.START) {
      startNum++;
    }
    if (nodeArr[index].nodeType === FLOW_NODE_TYPE_ENUM.END) {
      endNum++;
    }
  }
  if (startNum > 1 || endNum > 1) {
    ElMessage.error('开始或结束的节点数量不符合规则！');
    return false;
  }
  return true;
};

const formatNodeAndEdge = (edgeArr:any[], nodeArr:any[]) => {
  console.log('edgeArr', edgeArr);
  console.log('nodeArr', nodeArr);
  const edgeFormatArr:any = [];
  const nodeFormatArr:any = [];
  edgeArr.forEach((item:any) => {
    edgeFormatArr.push({
      id: item.id,
      type: 'sequenceFlow',
      sourceRef: item.source,
      targetRef: item.target,
    });
  });
  nodeArr.forEach((node:any) => {
    const formatItem:any = {
      id: node.id, type: node.type,
      nodeType: node.nodeType,
      name: node.label,
    };
    edgeArr.forEach((edge:any) => {
      if (node.id === edge.source) {
        formatItem['incomingFlows'] = [edge.id];
      }
      if (node.id === edge.target) {
        formatItem['outgoingFlows'] = [edge.id];
      }
    });
    formatItem['extensionElements'] = { executeConfig: {} };
    formatItem['extensionElements']['executeConfig'] = {
      type: '',
      inputFormat: node.inputFormat,
      outputFormat: node.outputFormat,
      // 默认是and条件
      nodeCondition: node.nodeCondition ? node.nodeCondition : 'and',
      exeCommand: node.exeCommand,
      // 默认是本地应用
      executeType: 'localApp',
      postScripts: node.postScripts,
      preScripts: node.preScripts,
      uuid: node.uuid,
    };

    if (node.type === '本地应用') {
      formatItem['extensionElements']['executeConfig'].type = 'localApp';
      formatItem['extensionElements']['executeConfig'].executeType = 'localApp';
    }
    if (node.type === '云应用') {
      formatItem['extensionElements']['executeConfig'].type = 'cloudApp';
      formatItem['extensionElements']['executeConfig'].executeType = 'cloudApp';
    }
    if (node.type === 'HPC') {
      formatItem['extensionElements']['executeConfig'].type = 'HPC';
      formatItem['extensionElements']['executeConfig'].executeType = 'HPC';
    }
    if (node.type === '脚本节点') {
      formatItem['extensionElements']['executeConfig'].type = 'scriptNode';
      formatItem['extensionElements']['executeConfig'].executeType = 'scriptNode';
    }

    delete formatItem['extensionElements']['executeConfig']['iconUrl'];
    delete formatItem['extensionElements']['executeConfig']['children'];
    delete formatItem['extensionElements']['executeConfig']['children'];
    delete formatItem.iconUrl;
    delete formatItem.pageConfigList;
    delete formatItem.children;
    delete formatItem.preNode;
    delete formatItem.nodeType;
    if (formatItem.nodeType === FLOW_NODE_TYPE_ENUM.START) {
      formatItem.type = 'startEvent';
    }
    if (formatItem.nodeType === FLOW_NODE_TYPE_ENUM.END) {
      formatItem.type = 'endEvent';
    }
    if (node.exeMethod === 'userTask') {
      formatItem.type = 'userTask';
    }
    else if (node.exeMethod === 'serviceTask') {
      formatItem.type = 'serviceTask';
    } else {
      // 默认自动执行
      formatItem.type = 'serviceTask';
    }

    nodeFormatArr.push(formatItem);
  });
  return [...nodeFormatArr, ...edgeFormatArr];
};
