<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="modalType == 'add' ? '新增' : '编辑'"
		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 { History } from '@antv/x6-plugin-history'
import Cookies from 'js-cookie'
import { ElMessage, ElMessageBox } from "element-plus";
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,
				},
				{
					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)
	})
}

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];
		//是办理节点
		if(element.id != 1 && element.shape != "edge") {
			console.log(element)
			if(!flowDefinitionNodeObj.value[element.id]) {
				ElMessage({
					message: '有节点未配置，请检查节点123123123',
					type: 'warning',
				})
				return
			}
			submitFormData.flowDefinitionNodeList.push({...flowDefinitionNodeObj.value[element.id],nodeType:2})
		}
		if(element.id == "1") {
			submitFormData.flowDefinitionNodeList.push({
				nodeName:'开始',
				nodeType:1,
				id:1,
				nodeButtonSet:'',
				parentId:0,
			})
		}
		//说明是线
		if(element.shape == "edge") {
			console.log(flowDefinitionNodeObj)
			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];
		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=' + Cookies.get('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=' + Cookies.get('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=' + Cookies.get('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.label == '结束') {
		flowDefinitionNodeObj.value[port.node.id] = {
			nodeName:'结束',
			nodeType:99,
			id:port.id,
			nodeButtonSet:'',
		}
	}
	console.log(flowDefinitionNodeObj.value)
}
//用于存储流程定义节点数据

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: {
			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: 200,
		stencilGraphHeight: 180,
		collapsable: true,
		groups: [
			{
				title: '基础流程图',
				name: 'group1',
			},
		],
		layoutOptions: {
			columns: 2,
			columnWidth: 80,
			rowHeight: 55,
		},
	})
	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 }) => {
		console.log(cell)
		if (cell.label === '开始' || cell.label === '结束' || cell.shape === 'edge') {
			return
		}
		if (flowDefinitionNodeObj.value[cell.id]) {
			formData.data = flowDefinitionNodeObj.value[cell.id]
		} else {
			formData.data = {
				id: cell.id,
				cell: cell,
			}
		}

		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
	)

	Graph.registerNode(
		'custom-polygon',
		{
			inherit: 'polygon',
			width: 66,
			height: 36,
			attrs: {
				body: {
					strokeWidth: 1,
					stroke: '#5F95FF',
					fill: '#EFF4FF',
				},
				text: {
					fontSize: 12,
					fill: '#262626',
				},
			},
			ports: {
				...ports,
				items: [
					{
						group: 'top',
					},
					{
						group: 'bottom',
					},
				],
			},
		},
		true
	)

	Graph.registerNode(
		'custom-circle',
		{
			inherit: 'circle',
			width: 45,
			height: 45,
			attrs: {
				body: {
					strokeWidth: 1,
					stroke: '#5F95FF',
					fill: '#EFF4FF',
				},
				text: {
					fontSize: 12,
					fill: '#262626',
				},
			},
			ports: { ...ports },
		},
		true
	)

	Graph.registerNode(
		'custom-image',
		{
			inherit: 'rect',
			width: 52,
			height: 52,
			markup: [
				{
					tagName: 'rect',
					selector: 'body',
				},
				{
					tagName: 'image',
				},
				{
					tagName: 'text',
					selector: 'label',
				},
			],
			attrs: {
				body: {
					stroke: '#5F95FF',
					fill: '#5F95FF',
				},
				image: {
					width: 26,
					height: 26,
					refX: 13,
					refY: 16,
				},
				label: {
					refX: 3,
					refY: 2,
					textAnchor: 'left',
					textVerticalAnchor: 'top',
					fontSize: 12,
					fill: '#fff',
				},
			},
			ports: { ...ports },
		},
		true
	)
	let firstLi = document.createElement('li')
	firstLi.innerText = '指标详情'
	console.log(firstLi)
	const r1 = graph.createNode({
		shape: 'custom-rect',
		label: '开始',
		zIndex: 100,
		attrs: {
			body: {
				rx: 20,
				ry: 26,
			},
		},
		tools: [
			{
				name: 'button',
				args: {
					firstLi,
				},
			},
		],
	})
	const r2 = graph.createNode({
		shape: 'custom-rect',
		label: '办理',
	})
	const r3 = graph.createNode({
		shape: 'custom-rect',
		attrs: {
			body: {
				rx: 6,
				ry: 6,
			},
		},
		label: '分支',
	})
	const r4 = graph.createNode({
		shape: 'custom-polygon',
		attrs: {
			body: {
				refPoints: '0,10 10,0 20,10 10,20',
			},
		},
		label: '结束',
	})
	stencil.load([ r2,  r4], 'group1')
	graph.addNode({
		shape: 'custom-rect',
		label: '开始',
		id: 1,
		x: 500,
		y: 100,
	})
}
onMounted(() => {
	antvInit()
	//获取url router参数
	const router = useRouter();
	submitFormData.flowInfoId = router.currentRoute.value.query.id
})
</script>
<style lang="scss">
.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;
	#stencil {
		position: absolute;
		top: 0;
		left: 0;
		z-index: 100;
		width: 200px;
		height: 500px;
		background: #fff;
		border-right: 1px solid #e8e8e8;
	}
	#container {
	}
	#graph-container {
		width: 100%;
		position: absolute;
		right: 0;
		top: 0;
	}
}
</style>
