<!--
 * @Author: donghao donghao@supervision.ltd
 * @Date: 2025-07-03 10:27:47
 * @LastEditors: donghao donghao@supervision.ltd
 * @LastEditTime: 2025-07-23 16:40:56
 * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\Workflow\logicFlowView.vue
 * @Description: 流程设计器面板
-->
<template>
  <div class="logic-flow-view-wrap">
    <!-- 流程节点控制面板 -->
    <ControlPanel class="design-panel-box" :lf="lf" />
    <div class="flex-1 w-full flow-editor-container">
      <!-- 新建流程 -->
      <div v-if="!showLf" class="flex flex-col items-center justify-center empty-canvas">
        <!-- // TODO 替换此图标 -->
        <img class="w-[63px] mb-[20px]" :src="CalibrateIcon" alt="" />
        <p>暂无流程配置，请添加流程</p>
        <DSButton type="primary" size="default" @click="handleNewFlow" class="my-[24px]"
          ><div class="flex items-center gap-[8px]">
            <el-icon class="text-[16px]"><Plus /></el-icon> <span>新建流程</span>
          </div></DSButton
        >
      </div>
      <!-- 画布区域 -->
      <div class="canvas-wrapper" v-else>
        <!-- 画布导航栏 -->
        <FlowControlBar class="flowCtrl-bar" :lf="lf" v-if="showTop" />
        <!-- LogicFlow 画布容器 -->
        <div id="lf-container" @dragover="handleDragOver" @drop="handleDrop"></div>
      </div>
    </div>

    <div class="attr-model-box" v-if="showAttribute">
      <FlowImageNodeModel v-model:value="isOpenFlowImage" />
      <FlowMultiImageNodeModel v-model:value="isOpenFlowMultiImage" />
    </div>
  </div>
</template>

<script setup lang="ts">
import LogicFlow, { RectNode } from '@logicflow/core'
import { Menu, Snapshot, MiniMap } from '@logicflow/extension'
import CalibrateIcon from '@/assets/images/panelBar/calibrate.png'
import { DSButton } from '@/components/Button'
import ControlPanel from '../Controls/panelCtrl.vue'
import FlowControlBar from '../Controls/flowCtrl.vue'
import { OperationNode, ImageNode } from '@/components/LogicFlowNodes'
import { useLogicFlow } from '@/hooks/useLogicFlow'
import { logicFlowConf, logicFlowThemeConf } from '@/config/designCanvas'
import { getNodeOutputCount, getNodeInputCount } from '@/utils/forData/arr'
import { FlowImageNodeModel, FlowMultiImageNodeModel } from '../FlowImagesCapture'

const showLf = ref<boolean>(false) // 是否显示画布
const showTop = ref<boolean>(false) // 是否显示顶部工具栏
const showAttribute = ref<boolean>(false) // 属性面板
const currNodeData = ref({}) // 节点数据

const { graphData } = useLogicFlow()
// 1. 初始化画布
const lf = ref<LogicFlow | null>(null)
const flowDetail = reactive({})

const isOpenFlowImage = ref<boolean>(false) // 是否打开图片源流程图节点
const isOpenFlowMultiImage = ref<boolean>(false) // 是否打开多图采集流程图节点
// 隐藏属性面板
const changeAttrPanelStatus = (isOpen) => {
  switch (currNodeData.value?.type) {
    case 'image-node':
      isOpenFlowImage.value = true
      break
    case 'multi-image-node':
      isOpenFlowMultiImage.value = true
      break
  }
  nextTick(() => {
    showAttribute.value = isOpen || !showAttribute.value
  })
}

// 控制器基础操作
const initDesignFlow = (record) => {
  console.log('initDesignFlow_record', record.type)
  if (!showLf.value) {
    ElMessage.error('请先创建新流程')
  }
  switch (record?.type) {
    case 'redo':
      lf.value.redo()
      break
    case 'undo':
      lf.value.undo()
      break
    case 'zoomIn':
      lf.value.zoom(0.1)
    default:
      break
  }
}

//设置边类型
const setEdgeType = (data) => {
  let sourceNode = lf.value.getGraphData().nodes.filter((i) => {
    return i.id === data.sourceNodeId
  })[0]
  if (sourceNode.type == 'start') {
    lf.value.setProperties(data.id, {
      edgeType: 'start'
    })
  } else if (sourceNode.type == 'assignment') {
    lf.value.setProperties(data.id, {
      edgeType: 'nextStep'
    })
  } else if (sourceNode.type == 'decision') {
    lf.value.setProperties(data.id, {
      type: 'decision', //边类型
      edgeType: ''
    })
  } else {
    lf.value.setProperties(data.id, {
      edgeType: 'nextStep'
    })
  }
}

// 注册自定义事件
const initEvents = () => {
  lf.value.on('node:click', ({ data }) => {
    // // currNodeData.value = data
    // console.log('node:click-currNodeData', currNodeData.value)
    // // changeAttrPanelStatus(true)
    currNodeData.value = data
    console.log('node:dbclick-currNodeData', currNodeData.value)
    changeAttrPanelStatus(true)
  })
  // lf.value.on('node:dbclick', ({ data }) => {
  //   currNodeData.value = data
  //   console.log('node:dbclick-currNodeData', currNodeData.value)
  //   changeAttrPanelStatus(true)
  // })
  // lf.value.on('edge:dbclick', ({ data }) => {
  //   currNodeData.value = data
  // })
  //来自边的事件中心发出的事件
  lf.value.on('edge:app-config', (res) => {
    currNodeData.value = res
    showAttribute.value = true
  })
  lf.value.on('element:click', () => {
    // hideAttrPanel() // 隐藏属性面板
    // console.log(lf.value.getGraphData(), 'getGraphData_click', JSON.stringify(lf.value.getGraphData()))
  })
  lf.value.on('blank:contextmenu', (e, position) => {
    console.log('blank_contextmenu', e, position)
    // hideAttrPanel() // 打开属性面板
  })
  lf.value.on('connection:not-allowed', (data) => {
    if (data.msg) {
      ElMessage({
        type: 'error',
        message: data.msg,
        duration: 8000
      })
    }
  })
}

// 注册自定义节点
const initRegisterNode = () => {
  console.log(ImageNode, 'initRegisterNode_ImageNode')
  lf.value.batchRegister([...OperationNode, ImageNode])
  showTop.value = true
  // lf.value.render() //回显
  initEvents()
}

// 2. 初始化流程图
const initializeLogicFlow = () => {
  lf.value = new LogicFlow({
    ...logicFlowConf,
    container: document.querySelector('#lf-container'),
    plugins: [Menu, MiniMap, Snapshot]
  })
  // 为菜单追加选项（必须在 lf.render() 之前设置）
  lf.value.extension.menu.addMenuConfig({
    nodeMenu: [],
    graphMenu: [
      {
        text: '粘贴',
        callback(graphEvent) {
          console.log('粘贴', graphEvent)
        }
      }
    ]
  })
  lf.value.setTheme({ ...logicFlowThemeConf })
  initRegisterNode()
  lf.value.render(graphData)
}

const handleNewFlow = () => {
  // lf && lf?.clearData()
  ElMessage.success('已创建新流程')
  showLf.value = true
  nextTick(() => initializeLogicFlow())
}

const handleDragOver = (e: DragEvent) => {
  e.preventDefault() // 必须阻止默认行为
  if (e.dataTransfer) {
    e.dataTransfer.dropEffect = 'copy'
  }
}

// 拖拽节点进入
const handleDrop = (e: DragEvent) => {
  e.preventDefault()
  // const nodeInfo = e.dataTransfer.getData('node-type')
  console.log(e, 'nodeInfo', JSON.parse(e.dataTransfer.getData('node-type')))
  const nodeInfo = JSON.parse(e.dataTransfer.getData('node-type'))
  if (!lf.value || !nodeInfo?.type) return
  // 转换坐标：浏览器坐标 -> 画布坐标
  const point = lf.value.getPointByClient({
    x: e.clientX,
    y: e.clientY
  })
  console.log(point, 'handleDrop_point', point.canvasOverlayPosition)

  // 添加节点
  lf.value.addNode({
    type: nodeInfo?.type,
    x: point?.canvasOverlayPosition?.x,
    y: point?.canvasOverlayPosition?.y,
    text: nodeInfo?.label
    // properties: dragData.value.properties || {}
  })
  // lf.value.render()
  // 重置拖拽数据
  // dragData.value = null
}

// TODO 待定操作
onMounted(() => {
  // initLogicFlow()
})

defineExpose({ initDesignFlow })
</script>

<style lang="scss" scoped>
@import url('./logicFlowView.scss');
</style>
