<template>
  <div class="workflow">
    <TeleportContainer/>
    <el-button style="position: absolute; top: 0;left: 0; z-index: 2" type="primary" @click="getJsonData">保存配置</el-button>
    <div class="workflow-chart">
      <workflowChart :data="state.workflowData" ref="ref_workflow"/>
    </div>
    <workflowPanel v-model:show="state.showPanel" :node="state.currentNode"/>
  </div>
</template>

<script setup lang="ts">
import {getCurrentInstance, onMounted, provide, reactive, ref} from "vue";
import workflowChart from './chart/index.vue'
import workflowPanel from './panel/index.vue'
import { getTeleport, register } from '@antv/x6-vue-shape'
import {data} from './mockJson'
import {WorkflowFunc} from "@/views/workflow/types";
import WorkflowNode from "@/views/workflow/nodes/index.vue";
import {lineStyle, portStyle} from "@/views/workflow/config";
import {Markup} from "@antv/x6";
const TeleportContainer = getTeleport()
register({
  shape: 'workflow-node',
  component: WorkflowNode,
})
const emits = defineEmits([])
const props = defineProps({})
const {proxy}: any = getCurrentInstance()
const state: any = reactive({
  workflowData: null,
  showPanel: false,
  currentNode: null,
})
const ref_workflow = ref()
provide('workflowFunc', <WorkflowFunc>{
  nodeClick: (node) => {
    state.currentNode = node
    state.showPanel = true
  }
})
const getJsonData = () => {
  const data = ref_workflow.value.toJSON()
  console.log(data)
}
const initData = () => {
  const formatData = (data) => {
    const res: any = {
      nodes: [],
      edges: [],
    }
    data.nodes.forEach((v) => {
      const node = {
        ...v,
        shape: 'workflow-node',
        portMarkup: [Markup.getForeignObjectMarkup()],
        ports: {
          groups: {
            start: {
              ...portStyle,
              position: {
                name: 'left',
              }
            },
            end: portStyle,
            more: portStyle,
          },
          items: []
        }
      }
      if (v.data.type !== 'root') {
        node.ports.items.push({
          id: `${v.id}_start`,
          group: 'start'
        },)
      }
      if (v.data.ports?.length > 0) {
        v.data.ports.forEach((p, pI) => {
          const offset = 50
          node.ports.items.push({
            id: p.id,
            group: 'more',
            args: {
              dy: offset
            }
          },)
        })
      } else {
        node.ports.items.push({
          id: `${v.id}_end`,
          group: 'end'
        })
      }
      res.nodes.push(node)
    })
    data.edges.forEach((v) => {
      const edge = {
        ...v,
        shape: 'edge',
        attrs: lineStyle,
        router: {
          name: 'manhattan',
          args: {
            startDirections: ['right'],
            endDirections: ['left'],
          },
        },
      }
      edge.source = {
        cell: v.source,
        port: v.port || `${v.source}_end`
      }
      edge.target = {
        cell: v.target,
        port: `${v.target}_start`
      }
      res.edges.push(edge)
    })
    return res
  }
  state.workflowData = formatData(data)
}
onMounted(() => {
  initData()
})
</script>

<style lang="scss" scoped>
.workflow {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  .workflow-chart {
    width: 100%;
    height: 100%;
    z-index: 1;
  }
}
</style>