<template>
	<div class="FL-container getting-started">
		<!-- 辅助工具栏 -->
		<Control class="demo-control" v-if="lf.container" :lf="lf as LogicFlow" @catData="$_catData" @saveModel="$_saveModel"></Control>
		<!-- 画布 -->
		<div class="app-content" ref="logicFlowContainerRef"></div>
		<!-- 属性面板 -->
		<el-drawer :title="t('message.flowModel.setNodeProps')" v-model="dialogVisible" direction="rtl" size="900px" :before-close="closeDialog">
			<PropertyDialog v-if="dialogVisible" :nodeData="clickNode" :lf="lf as LogicFlow" @setPropertiesFinish="closeDialog"></PropertyDialog>
		</el-drawer>
		<!-- 数据查看面板 -->
		<el-dialog :title="t('message.flowModel.data')" v-model="dataVisible" width="50%">
			<DataDialog :graphData="graphData"></DataDialog>
		</el-dialog>
	</div>
</template>

<script setup lang="ts">
import LogicFlow from '@logicflow/core'
import { DndPanel, Menu, MiniMap, SelectionSelect, Snapshot } from '@logicflow/extension'
import '@logicflow/core/lib/style/index.css'
import '@logicflow/extension/lib/style/index.css'
import { onMounted, ref, watch } from 'vue'
import Control from '/@/components/gFlow/Control.vue'
import { setPatternItems, setTheme } from '/@/components/gFlow/config'

import {
	registerConcurrent,
	registerCondition,
	registerEnd,
	registerPush,
	registerStart,
	registerUserTask,
	registerWebHook,
} from '/@/components/gFlow/registerNode'
import PropertyDialog from '/@/components/gFlow/propertySetting/PropertyDialog.vue'
import DataDialog from '/@/components/gFlow/DataDialog.vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useI18n } from 'vue-i18n'
import { getNodeData, saveModeNode } from '/@/api/flow/flowModel'
import {
	FlowCheckRuleDept,
	FlowCheckRuleDeptLeader,
	FlowCheckRulePost,
	FlowCheckRuleRole,
	FlowCheckRuleUser
} from '/@/components/gFlow/consts'
import GraphConfigData = LogicFlow.GraphConfigData

const route = useRoute()
const { t,locale } = useI18n()
const modelId = ref(0)
const logicFlowContainerRef = ref()
const lf = ref<LogicFlow>({} as LogicFlow)
const dataVisible = ref(false)
const graphData = ref<GraphConfigData>()
const addPanelStyle = ref({
	top: '0',
	left: '0',
})
const showAddPanel = ref(false)
const addClickNode = ref<any>()
const clickNode = ref({})
const dialogVisible = ref(false)
const moveData = ref({})
onMounted(() => {
	if (route.query.id) {
		modelId.value = parseInt(route.query.id as string)
	} else {
		ElMessage.error(t('message.flowModel.paramError'))
		return
	}
	lf.value = new LogicFlow({
		container: logicFlowContainerRef.value,
		grid: true,
		plugins: [DndPanel, SelectionSelect, Snapshot, Menu, MiniMap],
		pluginsOptions: {
			miniMap: {
				isShowHeader: false,
				isShowCloseIcon: true,
				headerTitle: t('message.flowModel.miniMap'),
			},
		},
	})
	registerNode()
	initLF()
})
//注册节点信息
const registerNode = () => {
	const logicFlow = lf.value as LogicFlow
	registerStart(logicFlow)
	registerEnd(logicFlow)
	registerConcurrent(logicFlow)
	registerPush(logicFlow)
	registerCondition(logicFlow)
	registerUserTask(logicFlow)
	registerWebHook(logicFlow)
}

const initLF = () => {
	const logicFlow = lf.value as LogicFlow
	setPatternItems(logicFlow,t)
	setTheme(logicFlow)
	$_render()
	$_LfEvent()
}

watch(locale,()=> {
	setPatternItems(lf.value as LogicFlow,t)
})
const $_render = () => {
	//获取节点数据
	getNodeData(modelId.value).then((res: any) => {
		const nodes = (res.nodes ?? []).map((item: any) => {
			const node = {
				id: item.nodeId,
				type: item.nodeType,
				x: item.nodePosition.x,
				y: item.nodePosition.y,
				text: item.nodeText ?? {},
				properties: {
					text: item.nodeText?.value,
					actionRule: item.nodeActionRule,
					approveRule: item.nodeRule,
					notice: item.notice ?? [],
					rollback: item.rollback,
					nodeExt: item.nodeExt ?? [],
					deptProv: item.deptProv ?? 1,
					// WebHook 配置 - 从后端数据构建 webhook 对象
					webhook: JSON.parse(item.ext ?? '{}'),

					// 动态判断配置
					dynamicJudge: JSON.parse(item.ext ?? '{}')?.userId,
				},
			}
			setReceiver(node, item.nodeReceiver)
			return node
		})
		const edges = (res.edges ?? []).map((item: any) => {
			return {
				id: item.id,
				type: item.lineType,
				sourceNodeId: item.sourceNodeId,
				targetNodeId: item.targetNodeId,
				startPoint: item.startPoint,
				endPoint: item.endPoint,
				properties: item.properties,
				pointsList: item.pointsList,
				text: item.text,
			}
		})
		lf.value.render({ nodes, edges })
		$_LfEvent()
	})
}
const setReceiver = (node: any, receivers: Array<string>) => {
	switch (node.properties.actionRule) {
		case FlowCheckRuleRole: //角色
			node.properties.roleIds = receivers
			break
		case FlowCheckRuleDept: //部门
		case FlowCheckRuleDeptLeader: //部门负责人
			node.properties.deptIds = receivers
			break
		case FlowCheckRuleUser: //指定人员
			node.properties.userIds = receivers
			break
		case FlowCheckRulePost: //岗位
			node.properties.postIds = receivers
	}
}
const $_catData = () => {
	graphData.value = lf.value.getGraphData() as GraphConfigData
	dataVisible.value = true
}
const $_saveModel = () => {
	const data = lf.value.getGraphData() as any
	const nodes = data.nodes.map((item: any) => {
		return {
			nodeId: item.id,
			modelId: modelId.value,
			nodeType: item.type,
			nodePosition: { x: item.x, y: item.y },
			nodeText: item.text,
			nodeActionRule: item.properties?.actionRule,
			nodeReceiver: getNodeReceiver(item.properties?.actionRule, item),
			nodeRule: item.properties?.approveRule,
			notice: item.properties?.notice,
			rollback: item.properties?.rollback,
			nodeExt: item.properties?.nodeExt,
			deptProv: item.properties?.deptProv,

			ext: JSON.stringify({
				// WebHook 相关配置 - 整合到 webhook 对象中
				...item.properties?.webhook,
				userId: item.properties?.dynamicJudge,
			}),
		}
	})
	const edges = data.edges.map((item: any) => {
		return {
			modelId: modelId.value,
			lineType: item.type,
			sourceNodeId: item.sourceNodeId,
			targetNodeId: item.targetNodeId,
			startPoint: item.startPoint,
			endPoint: item.endPoint,
			properties: item.properties,
			text: item.text,
			pointsList: item.pointsList,
		}
	})
	const postData = {
		modelId: modelId.value,
		nodes: nodes,
		edges: edges,
	}
	saveModeNode(postData)
		.then(() => {
			ElMessage.success(t('message.flowModel.saveSuccess'))
		})
		.catch(() => ElMessage.error(t('message.flowModel.exportFailed')))
}
const $_LfEvent = () => {
	const logicFlow = lf.value as LogicFlow
	logicFlow.on('node:click', (data) => {
		console.log('node:click', data)
		clickNode.value = data.data
		dialogVisible.value = true
	})
	logicFlow.on('edge:click', ({ data }) => {
		console.log('edge:click', data)
		//this.$data.clickNode = data;
		//this.$data.dialogVisible = true;
	})
	logicFlow.on('element:click', () => {
		hideAddPanel()
	})
	logicFlow.on('edge:add', ({ data }) => {
		console.log('edge:add', data)
	})
	logicFlow.on('node:mousemove', ({ data }) => {
		console.log('node:mousemove')
		moveData.value = data
	})
	logicFlow.on('blank:click', () => {
		hideAddPanel()
	})
	logicFlow.on('connection:not-allowed', (data) => {
		console.log('connection:not-allowed', data)
	})
	logicFlow.on('node:mousemove', () => {
		console.log('on mousemove')
	})
}
const hideAddPanel = () => {
	showAddPanel.value = false
	addPanelStyle.value.top = '0'
	addPanelStyle.value.left = '0'
	addClickNode.value = null
}
const closeDialog = () => {
	dialogVisible.value = false
}
const getNodeReceiver = (rule: number, item: any) => {
	switch (rule) {
		case FlowCheckRuleRole: //角色
			return item.properties.roleIds
		case FlowCheckRuleDept: //部门
		case FlowCheckRuleDeptLeader: //部门负责人
			return item.properties.deptIds
		case FlowCheckRuleUser: //指定人员
			return item.properties.userIds
		case FlowCheckRulePost: //岗位
			return item.properties.postIds
	}
	return []
}
</script>

<style scoped lang="scss">
.FL-container {
	width: 100%;
	overflow: hidden;
	.app-content {
		height: calc(100vh - 120px);
	}
}
.demo-control {
	position: absolute;
	top: 20px;
	right: 50px;
	z-index: 2;
}
</style>
