<template>
  <div class="workflow">
    <TeleportContainer />
    <div class="workflow-chart">
      <workflowChart
        :ID="ID"
        :data="state.workflowData"
        ref="ref_workflow"
        @save="onSave"
      />
    </div>
    <div class="operations">
      <div>
        <div
          class="__hover-bg"
          @click="WorkflowStore.$patch((s: any) => (s.envVars.show = true))"
        >
          <SvgIcon name="env" />
        </div>
      </div>
      <a-button type="primary" @click="onSave">保存配置</a-button>
    </div>
    <div class="panel">
      <workflowPanel />
      <envVarsPanel />
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  getCurrentInstance,
  onMounted,
  provide,
  reactive,
  ref,
  watch,
} from 'vue'
import workflowChart from './chart/index.vue'
import workflowPanel from './chart/panel-index.vue'
import envVarsPanel from './instance/component/vars/evn-index.vue'
import { getTeleport } from '@antv/x6-vue-shape'
import { useAppStore, useDictionaryStore, useWorkflowStore } from '@/stores'
import {
  workflowDraftDetail,
  workflowDraftSave,
} from '@/api/modules/workflow/chart'
import { ElLoading, ElMessage } from 'element-plus'
import { debounce } from 'lodash'
import { handleNodeSubmit } from '@/views/workflow/handle'

const DictionaryStore = useDictionaryStore()
const AppStore = useAppStore()
const TeleportContainer = getTeleport()
const WorkflowStore = useWorkflowStore()
const emit = defineEmits(['autoSave'])
const props = defineProps({
  ID: {},
})
const { proxy }: any = getCurrentInstance()
const state: any = reactive({
  workflowData: null,
  uniqueHash: '',
})
const ref_workflow = ref()

const autoSave = debounce(() => {
  onSave()
}, 5000)
watch(
  () => WorkflowStore.autoSaveFlag,
  () => {
    autoSave()
  },
)
const onSave = () => {
  const data = ref_workflow.value.toJSON()
  const offset = WorkflowStore.graph.translate()
  const res: any = {
    conversationVariables: [],
    environmentVariables: WorkflowStore.envVars.vars,
    hash: state.uniqueHash,
    graph: {
      nodes: [],
      edges: [],
      viewport: {
        zoom: WorkflowStore.graph.zoom(),
        x: offset.tx,
        y: offset.ty,
      },
    },
  }
  JSON.parse(JSON.stringify(data.cells)).forEach((cell: any) => {
    if (cell.shape === 'workflow-node') {
      const node: any = {
        id: cell.id,
        type: cell.data.workflowData.type,
        position: cell.position,
        data: handleNodeSubmit(cell.data.workflowData),
      }
      delete node.data.edgeSource
      delete node.data.inVars
      res.graph.nodes.push(node)
    } else if (cell.shape === 'edge') {
      const edge: any = {
        target: cell.target.cell,
        source: cell.source.cell,
      }
      if (!cell.source.port.includes('end')) {
        edge.sourceHandle = cell.source.port
      }
      res.graph.edges.push(edge)
    }
  })
  const loading = ElLoading.service({
    text: '自动保存中……',
    background: 'rgba(0, 0,0, 0.3)',
  })
  workflowDraftSave(props.ID, res)
    .then(({ data }: any) => {
      loading.close()
      state.uniqueHash = data.uniqueHash
      emit('autoSave', data.updateTime)
    })
    .catch(() => {})
    .finally(() => {})
}
const initData = () => {
  workflowDraftDetail(props.ID)
    .then(({ data }: any) => {
      emit('autoSave', data.updateTime)
      state.uniqueHash = data.uniqueHash
      WorkflowStore.$patch(
        (s: any) => (s.envVars.vars = data.environmentVariables || []),
      )
      if (data.graph.viewport) {
        const graph = {
          viewport: data.graph.viewport,
          nodes: formatNodes(data.graph.nodes),
          edges: formatEdges(data.graph.edges),
        }
        state.workflowData = graph
      } else {
        state.workflowData = {
          nodes: [],
          edges: [],
        }
      }
      // state.workflowData = {
      //   nodes: [],
      //   edges: [],
      // }
    })
    .catch(() => {})
    .finally(() => {})
  // const d = data0
  // WorkflowStore.$patch((s: any) => (s.envVars.vars = d.envVars || []))
  // state.workflowData = d.graph
}
const formatNodes = (arr) => {
  return arr.map((node: any) => {
    const obj = {
      id: node.id,
      x: node.position.x,
      y: node.position.y,
      data: node.data,
    }
    return obj
  })
}
const formatEdges = (arr) => {
  return arr.map((edge: any) => {
    const obj = {
      source: edge.source,
      target: edge.target,
      port: edge.sourceHandle || null,
    }
    return obj
  })
}
onMounted(() => {
  initData()
  initDictionary()
})
const initDictionary = () => {
  DictionaryStore.initKnowledges(AppStore.tenantInfo?.id)
}
</script>

<style lang="scss" scoped>
.workflow {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  position: relative;
  .workflow-chart {
    width: 100%;
    height: 100%;
    z-index: 1;
  }
  .operations {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 10px;
    > div {
      display: flex;
      align-items: center;
      background-color: rgba(255, 255, 255, 0.95);
      box-shadow: 0 0px 8px rgba(0, 0, 0, 0.1);
      border-radius: 6px;
      padding: 4px;
      > div {
        min-width: 24px;
        height: 24px;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
  }
  .panel {
    z-index: 2;
    position: absolute;
    right: 0;
    bottom: 0;
    display: flex;
    gap: 10px;
    height: calc(100% - 10px - 32px - 10px);
  }
}
</style>
