<template lang="">
	<div class="vueFlow">
		<div id="container"></div>
		<div id="stencil"></div>
		<div id="graph-container"></div>
	</div>
	<el-button @click="submitAll" type="primary">保存</el-button>
	<el-dialog
		title="节点信息配置"
		v-model="dialogVisible"
		width="500"
		v-loading="loading"
	>
		<byForm
			:formConfig="formConfig"
			:formOption="formOption"
			v-model="formData.data"
			:rules="rules"
			ref="byform"
		>
		</byForm>
		<template #footer>
			<el-button @click="dialogVisible = false" size="large"
				>取 消</el-button
			>
			<el-button
				type="danger"
				@click="deleteFlowDefinitionNodeObj()"
				size="large"
				:loading="submitLoading"
			>
				删 除
			</el-button>
			<el-button
				type="primary"
				@click="submitForm('byform')"
				size="large"
				:loading="submitLoading"
			>
				确 定
			</el-button>
		</template>
	</el-dialog>
</template>
<script lang="ts" setup>
import {
	defineComponent,
	ref,
	onMounted,
	onUnmounted,
	watch,
	reactive,
	toRefs,
	computed,
	nextTick,
	getCurrentInstance,
} from 'vue'
import byForm from '@/components/byForm/index'
import { Graph, Shape } from '@antv/x6'
import { Stencil } from '@antv/x6-plugin-stencil'
import { Transform } from '@antv/x6-plugin-transform'
import { Selection } from '@antv/x6-plugin-selection'
import { Snapline } from '@antv/x6-plugin-snapline'
import { Keyboard } from '@antv/x6-plugin-keyboard'
import { Clipboard } from '@antv/x6-plugin-clipboard'
import { register } from '@antv/x6-vue-shape'
import { History } from '@antv/x6-plugin-history'
import Cookies from 'js-cookie'
import { ElMessage, ElMessageBox } from 'element-plus'
import startBtn from './startBtn.vue'
import endBtn from './endBtn.vue'
import handleBtn from './handleBtn.vue'

defineProps({
	title: {
		type: Object,
		default: '',
	},
})
const { proxy } = getCurrentInstance()
const internalInstance = getCurrentInstance()
const dialogVisible = ref(false)
const modalType = ref('add')
const loading = ref(false)
const submitLoading = ref(false)
const formData = reactive({
	data: {
		userName: '',
		password: '',
	},
})
const byform = ref(null)
const flowDefinitionNodeObj = ref({})
const rules = reactive({
	nodeName: [
		{
			required: true,
			message: '请输入节点名称',
			trigger: 'blur',
		},
	],
	handleObjectType: [
		{
			required: true,
			message: '办理人类型不能为空',
			trigger: 'blur',
		},
	],
	handleObjectId: [
		{
			required: true,
			message: '办理人不能为空',
			trigger: 'blur',
		},
	],
})
const formConfig = computed(() => {
	return [
		{
			type: 'input',
			prop: 'nodeName',
			label: '节点名称',
			required: true,
			itemType: 'text',
		},

		{
			type: 'select',
			prop: 'handleObjectType',
			label: '办理人',
			placeholder: '请选择办理人类型',
			required: true,
			itemWidth: 30,
			fn: (e) => {
				console.log(e)
				gethandleObjectList(e)
			},
			//1用户 2部门负责人 3部门总监 4岗位 5角色
			data: [
				{
					label: '用户',
					value: 1,
				},
				{
					label: '部门负责人',
					value: 2,
				},
				{
					label: '部门总监',
					value: 3,
				},
				{
					label: '岗位',
					value: 4,
				},
				{
					label: '角色',
					value: 5,
				},
			],
		},
		// {
		// 	type: "treeSelect",
		// 	prop: "handleObjectId",
		// 	label: "请选择办理人",
		// 	itemWidth: 30,
		// 	data: [],
		// },
		{
			type: 'select',

			label: '  ',
			itemWidth: 30,
			prop: 'handleObjectId',
			placeholder: '请选择办理人',
			data: [],
		},
		{
			type: 'input',
			prop: 'handlingMethod',
			label: '节点后置执行方法',
			required: true,
			itemType: 'text',
		},
		{
			type: 'input',
			prop: 'jumpCondition',
			label: '条件表达式',
			required: true,
			itemType: 'text',
		},
		{
			type: 'checkbox',
			prop: 'nodeButtonSet',
			label: '节点按钮',
			//1通过 2驳回 3返回上一步 4退回到发起人
			data: [
				{
					label: '通过',
					value: 1,
					disabled:true,
				},
				{
					label: '驳回',
					value: 2,
				},
				{
					label: '返回上一步',
					value: 3,
				},
				{
					label: '退回到发起人',
					value: 4,
				},
			],
		},
		{
			type: 'radio',
			prop: 'jobNumber11',
			label: '审批意见必填',
			data: [
				{
					label: '是',
					value: 1,
				},
				{
					label: '否',
					value: 0,
				},
			],
		},
	]
})
const formOption = reactive({
	inline: true,
	labelWidth: 100,
	itemWidth: 100,
})
let graph
const submitForm = () => {
	byform.value.handleSubmit((valid) => {
		
		flowDefinitionNodeObj.value[formData.data.id] = formData.data
		console.log(flowDefinitionNodeObj.value)
		dialogVisible.value = false
		formData.data.cell.setData({
			title: formData.data.nodeName,
		});
	})
}

const submitFormData = {
	flowInfoId: null,
	titleTemplate: null,
	tenantId: Cookies.get('tenantId'),
	nodeObject: '',
	lineObject: '',
	flowDefinitionNodeList: [],
}
const submitAll = () => {
	if (proxy.title == '') {
		ElMessage({
			message: '请输入流程标题',
			type: 'warning',
		})
		return
	}
	submitFormData.titleTemplate = proxy.title
	const nodeList = graph.toJSON().cells
	console.log(nodeList)
	const isStart = false
	for (let i = 0; i < nodeList.length; i++) {
		const element = nodeList[i]
		console.log(element)
		console.log(flowDefinitionNodeObj)
		//是办理节点
		if (element.shape != "start-btn" && element.shape != 'edge' && element.shape != 'end-btn'  ) {
			
			if (!flowDefinitionNodeObj.value[element.id]) {
				ElMessage({
					message: '有节点未配置，请检查节点',
					type: 'warning',
				})
				return
			}
			submitFormData.flowDefinitionNodeList.push({
				...flowDefinitionNodeObj.value[element.id],
				nodeType: 2,
			})
		}
		if(element.shape == 'end-btn') {
			submitFormData.flowDefinitionNodeList.push({
				...flowDefinitionNodeObj.value[element.id],
			})
		}
		if (element.shape == "start-btn") {
			submitFormData.flowDefinitionNodeList.push({
				nodeName: '开始',
				nodeType: 1,
				id: 1,
				nodeButtonSet: '',
				parentId: 0,
			})
		}
		//说明是线
		if (element.shape == 'edge') {
			
			if (!flowDefinitionNodeObj.value[element.target.cell]) {
				ElMessage({
					message: '有节点未配置，请检查节点',
					type: 'warning',
				})
				return
			}
			flowDefinitionNodeObj.value[element.target.cell].id =
				element.target.cell
			flowDefinitionNodeObj.value[element.target.cell].parentId =
				element.source.cell
			submitFormData.flowDefinitionNodeList = []
		}
	}
	addVersion()
	console.log(flowDefinitionNodeObj.value)
}

//选取一个随机不重复的正整数id
const randomId = () => {
	const id = Math.floor(Math.random() * 100000000000000000)
	if (flowDefinitionNodeObj.value[id]) {
		randomId()
	} else {
		return id
	}
}

const addVersion = () => {
	const idObg = {}
	for (let i = 0; i < submitFormData.flowDefinitionNodeList.length; i++) {
		const element = submitFormData.flowDefinitionNodeList[i]
		console.log(element)
		if (element.parentId == null && element.nodeName == '结束') {
			ElMessage({
				message: '有结束节点未连线，请配置',
				type: 'warning',
			})
			return
		}
		if (isNaN(element.id)) {
			if (idObg[element.id]) {
				element.id = idObg[element.id]
			} else {
				const id = randomId()
				idObg[element.id] = id
				element.id = id
			}
		}
		if (isNaN(element.parentId) && element.nodeName != '开始') {
			if (idObg[element.parentId]) {
				element.parentId = idObg[element.parentId]
			} else {
				const id = randomId()
				idObg[element.parentId] = id
				element.parentId = id
			}
		}
		//nodeButtonSet转成字符串类型，用逗号隔开
		if (element.nodeButtonSet) {
			element.nodeButtonSet = element.nodeButtonSet.join(',')
		}
	}
	console.log(submitFormData)

	proxy.post('/flowDefinition/addVersion', submitFormData).then((res) => {
		console.log(res)
		ElMessage({
			message: '保存成功',
			type: 'success',
		})
	})
}

//将组数里的id和parentId转换成整正整数类型
const changeId = (arr) => {
	for (let i = 0; i < arr.length; i++) {
		const element = arr[i]
		element.id = parseInt(element.id)
		element.parentId = parseInt(element.parentId)
	}
}

const deleteFlowDefinitionNodeObj = (id) => {
	graph.removeNode(formData.data.id)
	delete flowDefinitionNodeObj.value[id]
	dialogVisible.value = false
}

const gethandleObjectList = (e) => {
	formData.data.handleObjectId = ''
	if (e === 1) {
		proxy
			.get(
				'/tenantUser/list?pageNum=1&pageSize=1000&tenantId=' +
					submitFormData.tenantId,
				{}
			)
			.then((res) => {
				formConfig.value[2].data = res.rows.map((item) => {
					return {
						label: item.nickName,
						value: item.userId,
					}
				})
			})
	}
	if (e === 3 || e === 2) {
		proxy
			.get(
				'/tenantDept/list?pageNum=1&pageSize=1000&tenantId=' +
					submitFormData.tenantId,
				{}
			)
			.then((res) => {
				formConfig.value[2].data = res.data.map((item) => {
					return {
						label: item.deptName,
						value: item.deptId,
					}
				})
			})
	}
	if (e === 4) {
	}
	if (e === 5) {
		proxy
			.get(
				'/tenantRole/list?pageNum=1&pageSize=1000&tenantId=' +
					submitFormData.tenantId,
				{}
			)
			.then((res) => {
				formConfig.value[2].data = res.rows.map((item) => {
					return {
						label: item.roleName,
						value: item.roleId,
					}
				})
			})
	}
}

const getTenantDept = () => {}
getTenantDept()

const recursive = (data) => {
	data.map((item) => {
		item.label = item.deptName
		item.id = item.deptId
		if (item.children) {
			recursive(item.children)
		} else {
			item.children = []
		}
	})
}

const pushRoom = (port: any) => {
	console.log(port)
	if (port.node.shape == 'end-btn') {
		flowDefinitionNodeObj.value[port.node.id] = {
			nodeName: '结束',
			nodeType: 99,
			id: port.id,
			nodeButtonSet: '',
			parentId: null,
		}
	}
}
//用于存储流程定义节点数据

const antvInit = () => {
	graph = new Graph({
		height: 600,
		container: document.getElementById('graph-container')!,
		grid: true,
		onPortRendered: pushRoom,
		mousewheel: {
			enabled: true,
			zoomAtMousePosition: true,
			modifiers: 'ctrl',
			minScale: 0.5,
			maxScale: 3,
		},
		
		connecting: { 
			allowLoop:false,
			// router: 'manhattan',
			connector: {
				name: 'rounded',
				args: {
					radius: 8,
				},
			},
			anchor: 'center',
			connectionPoint: 'anchor',
			allowBlank: false,
			snap: {
				radius: 20,
			},
			createEdge() {
				return new Shape.Edge({
					attrs: {
						line: {
							stroke: '#A2B1C3',
							strokeWidth: 2,
							targetMarker: {
								name: 'block',
								width: 12,
								height: 8,
							},
						},
					},
					zIndex: 0,
				})
			},
			validateConnection({ targetMagnet }) {
				return !!targetMagnet
			},
		},
		highlighting: {
			magnetAdsorbed: {
				name: 'stroke',
				args: {
					attrs: {
						fill: '#5F95FF',
						stroke: '#5F95FF',
					},
				},
			},
		},
	})
	const stencil = new Stencil({
		title: '流程图',
		target: graph,
		stencilGraphWidth: 360,
		stencilGraphHeight: 180,
		collapsable: true,
		groups: [
			{
				title: '基础流程图',
				name: 'group1',
			}, 
		],
		layoutOptions: {
			columns: 2,
			columnWidth: 170,
			rowHeight: 100,
		},
	})
	document.getElementById('stencil')!.appendChild(stencil.container)
	// #region 使用插件
	graph
		.use(
			new Transform({
				resizing: true,
				rotating: true,
			})
		)
		.use(
			new Selection({
				enabled: true,
				rubberband: true,
				showNodeSelectionBox: true,
			})
		)
		.use(
			new Snapline({
				enabled: true,
			})
		)
		.use(
			new Keyboard({
				enabled: true,
			})
		)
		.use(
			new Clipboard({
				enabled: true,
			})
		)
		.use(
			new History({
				enabled: true,
			})
		)

	// 控制连接桩显示/隐藏
	const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
		for (let i = 0, len = ports.length; i < len; i += 1) {
			ports[i].style.visibility = show ? 'visible' : 'hidden'
		}
	}
	graph.on('node:mouseenter', () => {
		const container = document.getElementById('graph-container')!
		const ports = container.querySelectorAll(
			'.x6-port-body'
		) as NodeListOf<SVGElement>
		showPorts(ports, true)
	})
	graph.on('node:mouseleave', () => {
		const container = document.getElementById('graph-container')!
		const ports = container.querySelectorAll(
			'.x6-port-body'
		) as NodeListOf<SVGElement>
		showPorts(ports, false)
	})
	// #endregion
	graph.on('cell:click', ({ e, x, y, cell, view }) => {
		if (cell.shape === 'start-btn') return
		if(cell.shape === 'end-btn' || cell.shape === 'edge') {
			ElMessageBox.confirm("是否删除", "提示", {
				confirmButtonText: "确定",
				cancelButtonText: "取消",
				type: "warning",
			}).then(() => {
				console.log(cell)
				graph.removeNode(cell.id)
				// delete flowDefinitionNodeObj.value[id]
			});
			return
		}
		if (flowDefinitionNodeObj.value[cell.id]) {
			formData.data = flowDefinitionNodeObj.value[cell.id]
		} else {
			formData.data = {
				id: cell.id,
				cell: cell,
				nodeButtonSet: [1],
			}
		}

		dialogVisible.value = true
	})
	// #region 初始化图形
	const ports = {
		groups: {
			top: {
				position: 'top',
				attrs: {
					circle: {
						r: 4,
						magnet: true,
						stroke: '#5F95FF',
						strokeWidth: 1,
						fill: '#fff',
						style: {
							visibility: 'hidden',
						},
					},
				},
			},
			right: {
				position: 'right',
				attrs: {
					circle: {
						r: 4,
						magnet: true,
						stroke: '#5F95FF',
						strokeWidth: 1,
						fill: '#fff',
						style: {
							visibility: 'hidden',
						},
					},
				},
			},
			bottom: {
				position: 'bottom',
				attrs: {
					circle: {
						r: 4,
						magnet: true,
						stroke: '#5F95FF',
						strokeWidth: 1,
						fill: '#fff',
						style: {
							visibility: 'hidden',
						},
					},
				},
			},
			left: {
				position: 'left',
				attrs: {
					circle: {
						r: 4,
						magnet: true,
						stroke: '#5F95FF',
						strokeWidth: 1,
						fill: '#fff',
						style: {
							visibility: 'hidden',
						},
					},
				},
			},
		},
		items: [
			{
				group: 'top',
			},
			{
				group: 'right',
			},
			{
				group: 'bottom',
			},
			{
				group: 'left',
			},
		],
	}
	Graph.registerNode(
		'custom-rect',
		{
			inherit: 'rect',
			width: 66,
			height: 36,
			attrs: {
				body: {
					strokeWidth: 1,
					stroke: '#5F95FF',
					fill: '#EFF4FF',
				},
				text: {
					fontSize: 12,
					fill: '#262626',
				},
			},
			ports: { ...ports },
		},
		true
	)
	register({
		shape: 'start-btn',
		width: 150,
		height: 90,
		component: startBtn,
		effect: ["title"],
		ports: { ...ports },
		data: {
			title: 80,
		},
	})
	register({
		shape: 'handle-btn',
		width: 150,
		height: 90,
		effect: ["title"],
		component: handleBtn,
		ports: { ...ports },
	})
	register({
		shape: 'end-btn',
		width: 150,
		height: 90,
		effect: ["title"],
		component: endBtn,
		ports: { ...ports },
	})
	const r1 = graph.createNode({
		shape: 'start-btn',
		label: '开始',
		zIndex: 100,
		attrs: {
			body: {
				rx: 20,
				ry: 26,
			},
		},
		data: {
			title: 80,
		},
	
	})
	const r2 = graph.createNode({
		shape: 'handle-btn',
		label: '办理',
		zIndex: 100,
		attrs: {
			body: {
				rx: 40,
				ry: 46,
			},
		},
	})
	const r3 = graph.createNode({
		shape: 'end-btn',
		label: '结束',
		zIndex: 100,
		attrs: {
			body: {
				rx: 20,
				ry: 26,
			},
		},
	})
	stencil.load([r2, r3], 'group1')
	// const startNode = graph.addNode({
	// 	shape: 'custom-rect',
	// 	label: '开始',
	// 	id: 1,
	// 	x: 500,
	// 	y: 100,
	// })
	
	graph.addNode({
		shape: 'start-btn',
		x: 500,
		y: 20,
		label: '开始',
		id:1,
		attrs: {
			
		},
	})
	
}
onMounted(() => {
	antvInit()
	//获取url router参数
	const router = useRouter()
	submitFormData.flowInfoId = router.currentRoute.value.query.id
	submitFormData.tenantId = router.currentRoute.value.query.tenantId
})
</script>
<style lang="scss">

.x6-widget-stencil-group-title {
	display: none !important;
}
.x6-widget-stencil-title {
	display: none;
}
.x6-widget-stencil-content {
	top: 0 !important;
}
.vueFlow {
	position: relative;
	display: flex;
	justify-content: space-between;
	overflow: hidden;
	height: 600px;
	.x6-graph{
		width: 100%!important;
	}
	#stencil {
		position: fixed;
		top: 250px;
		left: 40px;
		z-index: 100;
		width: 360px;
		height: 500px;
		background: #fff;
		overflow: hidden;
		background: #eee;
		border-radius: 20px;
	}
	#container {
	}
	#graph-container {
		width: 100%;
		position: absolute;
		right: 0;
		top: 0;
	}
}
</style>
