<template>
  <div class="run-flow-page">
    <div class="flow-content" id="flow-view-content" v-loading="contentLoading"></div>
    <TeleportContainer />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { Graph } from '@antv/x6';
import { queryFlowTemplateDetailApi } from '@/api/capability/flow';
import { createNode, getNodeList } from '@/views/simulation/creation/components/stencil';
import { objectTypeArrayRemovesDuplicates } from '@/utils/common';
import { registerCustomNode } from './registerNode';
import { listSimulationFlowNodeApi } from '@/api/project/run';
import { getTeleport } from '@antv/x6-vue-shape';

const TeleportContainer = getTeleport();
const props = defineProps({
  runInfo: {
    type: Object,
    default: () => {},
  },
});

const emits = defineEmits(['change', 'update', 'execute']);

const contentLoading = ref(false);

const graph = ref<any>();
const flowName = ref<any>();

const nodeDataList = ref<any>([]);
const runProcessInfo = ref<any>({});
const querLlistSimulationFlowNode = async (id: any) => {
  const res: any = await listSimulationFlowNodeApi({
    runId: id,
  });
  if (res && res.code === 200) {
    nodeDataList.value = res.data.flowNodeDtoList;
    runProcessInfo.value = res.data.processInfo;
  } else {
    nodeDataList.value = [];
    runProcessInfo.value = {};
  }
};

const getFlowDetail = async (uuid: string) => {
  contentLoading.value = true;
  const res: any = await queryFlowTemplateDetailApi({ uuid: uuid, status: 1 });
  if (res.code === 200) {
    if (res.data.viewContent.length > 50) {
      const dataJson = JSON.parse(res.data.viewContent);
      // // 过滤起始节点和结束节点
      const beginandend = dataJson.cells.filter((item: any) => {
        return (
          item.type === 'local' ||
          item?.data?.label === '起始节点' ||
          item?.data?.label === '结束节点'
        );
      });
      const ids = beginandend.map((item: any) => {
        return item.id;
      });
      dataJson.cells = dataJson.cells.filter((item: any) => {
        return (
          !ids.includes(item.id) &&
          !ids.includes(item?.source?.cell) &&
          !ids.includes(item?.target?.cell)
        );
      });
      const nodes = dataJson.cells.filter((item: any) => {
        return item?.type;
      });

      // // 改变各个节点之间的距离
      let position = nodes.map((item: any) => {
        return item?.position?.x;
      });
      position = objectTypeArrayRemovesDuplicates(position, 2);

      // const num = dataJson.cells.length;
      position.sort((a: any, b: any) => {
        return a - b;
      });

      // // 避免两个节点重合了
      for (let i = 0; i < dataJson.cells.length; i++) {
        if (dataJson.cells[i].type) {
          dataJson.cells[i].size.width = 220;
          const index = position.indexOf(dataJson.cells[i].position.x);

          dataJson.cells[i].position.x = dataJson.cells[i].position.x + index * 70;
          // num > 5 ? dataJson.cells[i].position.x : dataJson.cells[i].position.x + i * 20;

          for (let j = 0; j < nodeDataList.value.length; j++) {
            if (dataJson.cells[i].id === nodeDataList.value[j].nodeId) {
              dataJson.cells[i].data.flowNodeInfo = nodeDataList.value[j];
            }
          }
        }
      }

      const paramNode = dataJson.cells.filter((item: any) => {
        return item.type;
      });

      const nodeConfigList: any = {};
      for (let i = 0; i < paramNode.length; i++) {
        nodeConfigList[paramNode[i].data.label] = paramNode[i].data.pageConfigList;
      }

      const userDetaileParams: any = {};

      for (let i = 0; i < nodeDataList.value.length; i++) {
        userDetaileParams[nodeDataList.value[i].nodeName] = nodeDataList.value[i].userParams;
      }

      emits('update', {
        list: nodeConfigList,
        param: userDetaileParams,
        nodeDatas: nodeDataList.value,
        flowNodeInfos: paramNode,
      });

      setTimeout(() => {
        graph.value.fromJSON(dataJson);
        graph.value.centerContent();
        contentLoading.value = false;

        if (graph.value) {
          setCurrentNodeFun();
        }
      }, 1000);
    } else {
      contentLoading.value = false;
    }
    flowName.value = res.data.templateName;
  } else {
    ElMessage.error(res.message);
  }
};

const selectNode = ref<any>({});
const initGraph = async () => {
  graph.value = new Graph({
    panning: {
      enabled: true,
    },
    interacting: {
      // 禁用画布拖拽
      nodeMovable: false,
    },
    container: document.getElementById('flow-view-content') as HTMLElement,
    autoResize: true,
    //	画布的最小最大缩放级别
    scaling: { min: 0.5, max: 3 },
    // grid: true,
    // width: 800,
    // height: 800,
    background: {
      color: '#FFF',
    },
  });
  registerCustomNode();
  const nodeList = await getNodeList(true);
  createNode(nodeList, graph.value);

  graph.value.on('node:click', ({ node }: any) => {
    selectNode.value = node;
    const allNodes = graph.value.getNodes();
    const allNodeData = allNodes.map((item: any) => {
      return item?.store?.data?.data;
    });

    for (let i = 0; i < allNodes.length; i++) {
      if (selectNode.value.id === allNodes[i].id) {
        allNodes[i].addTools({
          name: 'boundary',
          args: {
            padding: 0,
            attrs: {
              // fill: '#7c68fc',
              stroke: '#0366FF',
              'stroke-width': 2,
              'stroke-dasharray': '',
              rx: 4,
              ry: 4,
            },
          },
        });

        localStorage.setItem('CURRENT_RUN_FLOW_NODE_INFO', allNodes[i].id);
      } else {
        allNodes[i].removeTools();
      }
    }

    const data = nodeDataList.value.find((item: any) => {
      return item.nodeId === node.id;
    });

    emits('change', {
      node,
      data,
      process: runProcessInfo.value,
      allData: allNodeData,
      flag: true,
    });
  });

  graph.value.on('node:dblclick', ({ node }: any) => {
    emits('execute');
  });
};

// 设置默认点击节点
const setCurrentNodeFun = () => {
  const allNodes = graph.value.getNodes();

  const currentId = localStorage.getItem('CURRENT_RUN_FLOW_NODE_INFO') || '';
  let currentNodes: any = {};

  if (currentId) {
    currentNodes =
      allNodes.find((item: any) => {
        return item.id === currentId;
      }) || allNodes[0];

    currentNodes.addTools({
      name: 'boundary',
      args: {
        padding: 0,
        attrs: {
          // fill: '#7c68fc',
          stroke: '#0366FF ',
          'stroke-width': 2,
          'stroke-dasharray': '',
          rx: 4,
          ry: 4,
        },
      },
    });
  } else {
    currentNodes = allNodes[0];

    currentNodes.addTools({
      name: 'boundary',
      args: {
        padding: 0,
        attrs: {
          // fill: '#7c68fc',
          stroke: '#0366FF ',
          'stroke-width': 2,
          'stroke-dasharray': '',
          rx: 4,
          ry: 4,
        },
      },
    });
  }
  const allNodeData = allNodes.map((item: any) => {
    return item?.store?.data?.data;
  });
  const data = nodeDataList.value.find((item: any) => {
    return item.nodeId === currentNodes.id;
  });

  emits('change', {
    node: currentNodes,
    data: data,
    process: runProcessInfo.value,
    allData: allNodeData,
    flag: false,
  });
};

watch(
  () => props.runInfo,
  async (newVal) => {
    if (newVal) {
      // currentRunNodeInfo.value = newVal;
      // await initGraph();
      // await getFlowDetail(currentRunNodeInfo.value.flowTemplate);
      // await querLlistSimulationFlowNode(currentRunNodeInfo.value.uuid);
    }
  },
  {
    immediate: true,
    deep: true,
  }
);

onMounted(async () => {
  setTimeout(async () => {
    if (props.runInfo) {
      await initGraph();
      await querLlistSimulationFlowNode(props.runInfo.uuid);
      await getFlowDetail(props.runInfo.flowTemplate);
    }
  });
});
</script>

<style lang="scss" scoped>
.run-flow-page {
  width: 100%;
  height: 100%;

  .flow-content {
    width: 100%;
    height: 100%;
  }
}
</style>
