<script setup name="configEdit">
import { ref, reactive, nextTick, provide, onMounted, getCurrentInstance } from 'vue'
import childFlow from './components/childFlow.vue'
import playCircle from '@/assets/images/flowConfig/playCircle.png'
import ApprovalDialog from './components/approvalDialog.vue'
import ConditionDialog from './components/conditionDialog.vue'
import { processConfigDetail, systemProcessSave, systemProcessRelease } from '@/http/apis/systemManage/flowConfiguration'
import { useRouter, useRoute } from 'vue-router'
import ConcurrentDialog from './components/concurrentDialog.vue'
const { proxy } = getCurrentInstance(),
  router = useRouter(),
  route = useRoute(),
  // 添加节点
  addNode = ({ key, type, item }) => {
    let node = {}
    const name =
        type === 'SUB'
          ? '审批'
          : type === 'CONDITIONS' ? '条件' : type === 'CONCURRENTS' ? '并行分支' : '空节点'
    if (type === 'SUB' || type === 'EMPTY') {
      node = {
        name,
        type, // SUB审批单位  CONDITIONS条件  CONCURRENTS并行条件
        props: undefined,
        id: ''
      }
    } else if (type === 'CONCURRENTS') {
      node = {
        name,
        type: 'CONCURRENTS',
        branchs: [
          {
            name,
            type: 'CONCURRENT',
            props: {
              groups: []
            },
            children: [{
              type: 'AUTO_PASS'
            }]
          },
          {
            name: '并行分支',
            type: 'CONCURRENT',
            props: {
              groups: []
            },
            children: [{
              type: 'AUTO_PASS'
            }]
          }
        ],
        id: ''
      }
    } else {
      node = {
        name,
        type: 'CONDITIONS',
        branchs: [
          {
            name: '所有数据可进入该分支',
            type: 'CONDITION',
            props: {
              groups: []
            },
            children: [{
              type: 'AUTO_PASS'
            }]
          },
          {
            name: '所有数据可进入该分支',
            type: 'CONDITION',
            props: {
              groups: []
            },
            children: [{
              type: 'AUTO_PASS'
            }]
          }
        ],
        id: ''
      }
    }
    if (key === -1) { // key:-1,开始节点下面
      nodeData.value.splice(0, 0, node)
      if (type === 'CONDITIONS' || type === 'CONCURRENTS') {
        addNode({
          key: key + 1,
          type: 'EMPTY', // 合并节点
          item: nodeData.value
        })
      }
    } else {
      if (item.children === undefined) {
        item.splice(key + 1, 0, node)
        if (type === 'CONDITIONS' || type === 'CONCURRENTS') {
          addNode({
            key: key + 1,
            type: 'EMPTY',
            item: item
          })
        }
      } else {
        item.children.splice(0, 0, node)
        if (type === 'CONDITIONS' || type === 'CONCURRENTS') {
          addNode({
            key: key,
            type: 'EMPTY',
            item: item.children
          })
        }
      }
    }
  },
  // 添加条件
  addCondition = (item, type) => {
    const node = {
      name: type === 'CONDITIONS' ? '所有数据可进入该分支' : '并行分支',
      type: type === 'CONDITIONS' ? 'CONDITION' : 'CONCURRENT',
      props: {
        groups: []
      },
      children: [{
        type: 'AUTO_PASS'
      }]
    }
    item.push(node)
  },
  // 删除节点
  removeNode = async (con_index, item, index, nodeData) => {
    if (item.branchs) {
      if (item.branchs.length === 2) {
        nodeData.splice(index, 2)
      } else {
        item.branchs.splice(con_index, 1)
      }
    } else {
      if (item.children === undefined) {
        item.splice(con_index, 1)
      } else {
        item.children.splice(0, 1)
      }
    }
  },
  // 操作弹窗-审批节点配置
  approvalDialogData = reactive({
    visible: false,
    data: {
      name: undefined
    }
  }),
  showApprovalDialog = ({ key, item }) => {
    approvalDialogData.visible = true
    approvalDialogData.data = item[key]
  },
  closeApproval = flag => {
    approvalDialogData.visible = false
  },
  updateApprovalData = (data) => {
    nextTick(() => {
      Object.entries(data).forEach(i => {
        approvalDialogData.data[i[0]] = i[1]
      })
    })
  },
  // 操作弹窗-条件节点配置
  conditionDialogData = reactive({
    visible: false,
    data: undefined
  }),
  showConditionDialog = ({ item }) => {
    conditionDialogData.visible = true
    conditionDialogData.data = item
  },
  closeConditon = flag => {
    conditionDialogData.visible = false
  },
  updateConditionData = (data) => {
    nextTick(() => {
      Object.entries(data).forEach(i => {
        conditionDialogData.data[i[0]] = i[1]
      })
    })
  },
  // 操作弹窗-并行分支节点配置
  concurrentDialogData = reactive({
    visible: false,
    data: undefined
  }),
  showConcurrentDialog = ({ item }) => {
    concurrentDialogData.visible = true
    concurrentDialogData.data = item
  },
  closeConcurrent = flag => {
    concurrentDialogData.visible = false
  },
  updateConcurrentData = (data) => {
    nextTick(() => {
      Object.entries(data).forEach(i => {
        concurrentDialogData.data[i[0]] = i[1]
      })
    })
  },
  // 获取数据
  procDefId = ref(),
  nodeData = ref([]),
  getNodeData = async () => {
    const res = await processConfigDetail({ formId: route.query.formId })
    procDefId.value = res.data.processDefId
    nodeData.value = getChildNode([], res.data.process, true)
  },
  getChildNode = (arr, item, isNodeId) => {
    if (item?.branchs) {
      const branchs = []
      item.branchs.forEach(val => {
        let obj = {}
        obj = {
          name: val.name,
          type: val.type,
          props: val.props,
          id: isNodeId ? val.id : undefined,
          parentType: val.parentType || undefined
        }
        if (val?.children && JSON.stringify(val.children) !== '{}') {
          const childArr = []
          if (!val.children.branchs) {
            childArr.push({
              name: val.children.name,
              type: val.children.type,
              props: val.children.props,
              id: isNodeId ? val.children.id : undefined,
              parentType: val.children.parentType || undefined
            })
          }
          getChildNode(childArr, val.children, isNodeId)
          obj.children = childArr
        } else {
          obj.children = []
        }
        branchs.push(obj)
      })
      arr.push({
        type: item.type,
        'props': {},
        branchs
      })
    }
    if (item?.children && JSON.stringify(item.children) !== '{}') {
      if (!item.children.branchs) {
        arr.push({
          name: item.children.name,
          type: item.children.type,
          props: item.children.props,
          id: isNodeId ? item.children.id : undefined,
          parentType: item.children.parentType || undefined
        })
      }
      getChildNode(arr, item.children, isNodeId)
    }
    return arr
  },

  // 获取随机id
  uuid = () => {
    const s = []
    const hexDigits = '0123456789abcdef'
    for (let i = 0; i < 36; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
    }
    s[14] = '4'
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
    s[8] = s[13] = s[18] = s[23] = '-'

    const uuid = 'node_' + s.join('')
    return uuid
  },
  // 转换数据结构
  formatter = (nodes, preNode) => {
    nodes = nodes.reverse()

    return nodes.reduce((res, cur, index) => {
      const id = cur.id || uuid()
      const type = cur.type

      if (preNode && index === nodes.length - 1) {
        cur.parentId = preNode.id
        cur.parentType = preNode.type
      }

      if (cur.branchs) {
        cur.branchs.forEach(i => {
          i.parentId = id
          i.parentType = type
          i.id = i.id || uuid()
          if (i.children && i.children.length) {
            i.children = formatter(i.children, i)
          } else if (i.children && !i.children.length) {
            delete i.children
          }
        })

        if (!index) {
          cur.id = id
          cur.type = type
          return cur
        }

        res.parentId = id
        res.parentType = type

        return {
          type,
          id,
          branchs: cur.branchs,
          children: res
        }
      } else {
        if (!index) {
          cur.id = id
          cur.type = type
          return cur
        }
        res.parentId = id
        res.parentType = type

        cur.id = id
        cur.type = type
        cur.children = res
        return cur
      }
    }, null)
  },
  submit = async () => {
    let resource = {}
    const nodes = JSON.parse(JSON.stringify(nodeData.value))
    nodes.splice(0, 0, {
      name: '发起人',
      type: 'ROOT',
      id: 'root'
    })
    resource = resource.children = JSON.parse(
      JSON.stringify(formatter(nodes))
    )
    const postData = {
      process: resource,
      formId: route.query.formId,
      groupId: 1
    }
    await systemProcessSave(postData)
    await systemProcessRelease(route.query.formId)
    proxy.$message.success('发布成功')
  }
onMounted(() => {
  getNodeData()
})
// 可以使得孙子组件也能调用父组件的这个方法，适用多层组件嵌套的时候
provide('showApprovalDialog', showApprovalDialog)
provide('showConditionDialog', showConditionDialog)
provide('showConcurrentDialog', showConcurrentDialog)
provide('addNode', addNode)
provide('removeNode', removeNode)
provide('addCondition', addCondition)
</script>

<template>
  <el-card shadow="never">
    <template #header>
      <div class="flex justify-between items-center">
        <span>{{ route.query.bizFormName }}</span>
        <div>
          <el-button @click="router.go(-1)">返回</el-button>
          <el-button
            type="primary"
            @click="submit"
          >发布</el-button>
        </div>
      </div>
    </template>
    <div class="overflow-x-auto flex">
      <div class="node flex flex-1 flex-col items-center justify-center">
        <div class="start_box node_box text-white flex items-center justify-center">
          开始
          <img :src="playCircle" />
        </div>
        <el-popover
          placement="right"
          :width="100"
          trigger="hover"
        >
          <template #reference>
            <el-icon class="add_icon mt-20 mb-20 cursor-pointer">
              <Plus />
            </el-icon>
          </template>
          <div class="flex flex-col">
            <p>
              <el-button
                class="mb-8 w-full"
                @click="addNode({ key: -1, type: 'SUB' })"
              >
                单位
              </el-button>
            </p>
            <p>
              <el-button
                class="ml-1 w-full mb-8"
                @click="addNode({ key: -1, type: 'CONDITIONS' })"
              >
                数据筛选
              </el-button>
            </p>
            <p>
              <el-button
                class="ml-1 w-full"
                @click="addNode({ key: -1, type: 'CONCURRENTS' })"
              >
                并行分支
              </el-button>
            </p>
          </div>
        </el-popover>
        <child-flow :node-data="nodeData" />
        <div class="end_box node_box text-white flex items-center justify-center">
          流程结束
        </div>
      </div>
    </div>
  </el-card>
  <approval-dialog
    :visible="approvalDialogData.visible"
    :data="approvalDialogData.data"
    @close="closeApproval"
    @update:data="updateApprovalData"
  />
  <condition-dialog
    :visible="conditionDialogData.visible"
    :data="conditionDialogData.data"
    @close="closeConditon"
    @update:data="updateConditionData"
  />
  <concurrent-dialog
    :visible="concurrentDialogData.visible"
    :data="concurrentDialogData.data"
    @close="closeConcurrent"
    @update:data="updateConcurrentData"
  />
</template>

<style lang="less">
.node{
  .add_icon{
    width: 24px;
    height: 24px;
    background: #ffffff;
    box-shadow: 0px 4px 8px 0px rgb(9 103 253 / 8%), 0px 6px 13px 0px rgb(9 103 253 / 8%);
    border: 1px solid rgba(9, 103, 253, 0.06);
    border-radius: 100%;
    color: #0967fd;
    z-index:2;
    &:after{
      width: 4px;
      height: 20px;
      background: #dcdee2;
      content: '';
      display: block;
      position: absolute;
      left: 50%;
      transform: translate(-50%, 100%);
      bottom: 0;
    }
    &:before{
      width: 4px;
      height: 20px;
      background: #dcdee2;
      content: '';
      display: block;
      position: absolute;
      left: 50%;
      transform: translate(-50%, 0);
      top: -20px;
    }
  }
  .node_box{
    position: relative;
    width: 160px;
    height: 56px;
    border-radius: 4px;
    font-size: 20px;
    &:not(.end_box):after{
      //width: 4px;
      //height: 20px;
      //background: #dcdee2;
      //content: '';
      //display: block;
      //position: absolute;
      //left: 50%;
      //transform: translate(-50%, 100%);
      //bottom: 0;
    }
    &.start_box{
      background: linear-gradient(270deg, #15a1ff 0%, #0967fd 100%);
      box-shadow: 0px 10px 12px -5px rgba(9, 103, 253, 0.2),
      0px 6px 12px 0px rgba(9, 103, 253, 0.2);
      img{
        width: 24px;
        height: 24px;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        right: 16px;
      }
    }
    &.end_box{
      background: linear-gradient(270deg, #54dc7d 0%, #29c458 100%);
      box-shadow: 0px 10px 12px -5px rgba(78, 203, 116, 0.2),
      0px 6px 12px 0px rgba(78, 203, 116, 0.2);
    }
  }
}
</style>

