<template>
	<div class="wrap">
		<div class="box1">
			<AnalysisBox title="相关政令" :showAllBtn="false">
				<div class="box1-main">
					<el-empty v-if="siderList.length===0" style="padding-top: 30%" description="暂无数据" :image-size="100" />
					<el-scrollbar height="100%" always>
						<div class="left-item" :class="{ 'item-active': false }" v-for="(item, index) in siderList" :key="index" @click="handleClickDecree(item)">
							<div class="item-head">
								<div class="itme-name one-line-ellipsis">{{ item.label }}</div>
								<div class="item-tag">政令</div>
							</div>
							<div class="itme-time one-line-ellipsis">{{ item.time }} · {{ item.name }} </div>
						</div>
					</el-scrollbar>
				</div>
			</AnalysisBox>
		</div>
		<div class="box2">
			<AnalysisBox title="政令关系挖掘" :showAllBtn="false">
				<div class="box2-main">
					<div ref="containerRef" class="graph-container"></div>
				</div>
			</AnalysisBox>
		</div>

		<el-dialog v-model="dialogVisible" width="1000px" class="viewpoint-dialog">
			<template #header>
				<div class="viewpoint-header">
					<div class="viewpoint-title">冲突关系</div>
				</div>
			</template>
			<div class="viewpoint-body">
				<div class="graph-tag">
					<div class="icon1"></div>
          <div class="title">
						{{ `${mainInfo.time}-${mainInfo.label} ${nodeInfo.relation} ${nodeInfo.time}-${nodeInfo.label}, 属于${nodeInfo.relation}关系` }}
          </div>
          <div class="icon2Wrap">
            <div class="icon2"></div>
          </div>
				</div>
				<div ref="graphContainer" class="graph-container"></div>
			</div>
		</el-dialog>
	</div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import { useRoute } from "vue-router";
import router from "@/router";
import * as G6 from '@antv/g6';
import { getDecreeRelatedOrder } from "@/api/decree/deepdig";
import { getDecreeSummary } from "@/api/decree/introduction";

import icon1628 from "./assets/icons/icon1628.png";
import icon1629 from "./assets/icons/icon1629.png";

const route = useRoute();

// 冲突关系
const dialogVisible = ref(false);

// 基本信息
const mainInfo = ref({});
const nodeInfo = ref({});
const onDecreeSummaryData = async () => {
	try {
		const res = await getDecreeSummary({id: route.query.id});
		console.log("基本信息", res);
		if (res.code===200 && res.data) {
			mainInfo.value.label = res.data.name;
			mainInfo.value.time = res.data.postDate;
			mainInfo.value.id = route.query.id;
			mainInfo.value.isCenter = true
		}
	} catch (error) {
		mainInfo.value = {};
		console.log("获取基本信息数据失败:", error);
	}
};

// 相关政令
const siderList = ref([]);
const handleClickSider = async (item) => {
	dialogVisible.value = true;
	nodeInfo.value = item
	setTimeout(onRelationChart, 300)
};
const handleGetRelateOrder = async () => {
	try {
		const res = await getDecreeRelatedOrder({id: route.query.id});
		console.log("相关政令", res);
		if (res.code===200 && res.data?.length) {
			siderList.value = res.data
			siderList.value.forEach(item => {
				item.label = item.proposeOrgName;
				item.time = item.postDate;
			})
		} else {
			siderList.value = []
		}
	} catch (error) {
		siderList.value = [];
		console.log("获取相关政令数据失败:", error);
	}
};

// 政令关系挖掘
const containerRef = ref();
let graphInstance = null;
// 文本插入换行符
const onWordWrap = (word, num) => {
	const list = word.split('');
	let label = "";
	for (let i = 0; i < list.length; i++) {
		if (i % num === 0 && i !== 0) {
			label += "\n";
		}
		label += list[i];
	}
	return label;
}
const onFormatNode = (item) => {
	let isCenter = item.isCenter || false
	return {
		id: item.id+'', label:onWordWrap(item.label, 15), isCenter,
		img: isCenter ? icon1628 : icon1629,
		clipCfg: { r: isCenter ? 40 : 30 },
		labelCfg: {
			style: { 
				fill: isCenter ? "#1459BB" : "#333333",
				fontSize: isCenter ? 13 : 13,
				fontWeight: isCenter ? "bold" : "normal"
			}
		}
	}
}
const onFormatEdge = (item, index) => {
	return {
		id: `edge-${index+1}`,
		target: item.id+'',
		source: route.query.id,
		// label: ["", "相似", "继承", "冲突"][1],
		label: item.relation,
		style: {
			stroke: ["", "#B9DCFF", "#87E8DE", "#FFCCC7"][1],
		},
		labelCfg: {
			style: {
				fill: ["", "#055FC2", "#13A8A8", "#CE4F51"][1],
				background: {
					fill: ["", "#E7F3FF", "#E6FFFB", "#FFE0E0"][1],
				}
			}
		}
	}
}
const initChart = () => {
	let edgeList = siderList.value.map(onFormatEdge)
	let nodeList = siderList.value.map(onFormatNode)
	nodeList.unshift(onFormatNode(mainInfo.value))
	console.log(nodeList)

	const width = containerRef.value.offsetWidth || 800
	const height = containerRef.value.offsetHeight || 600
  const centerX = width / 2
  const centerY = height / 2
  const radius = Math.min(width, height) / 2 - 120

	const otherNodes = nodeList.filter(n => !n.isCenter)
  const nodeCount = otherNodes.length
  otherNodes.forEach((node, index) => {
    const angle = (2 * Math.PI * index) / nodeCount - Math.PI / 2
    node.x = centerX + radius * Math.cos(angle)
    node.y = centerY + radius * Math.sin(angle)
  })
  const centerNode = nodeList.find(n => n.isCenter)
  if (centerNode) {
    centerNode.x = centerX
    centerNode.y = centerY
    centerNode.fx = centerX
    centerNode.fy = centerY
  }

	graphInstance = new G6.Graph({
		container: containerRef.value,
		width,
		height,
		fitView: false,
		fitCenter: false,
		animate: true,
		animateCfg: {
			duration: 300,
			easing: 'easeLinear'
		},
		minZoom: 0.1,
		maxZoom: 10,
		modes: {
			default: [ 'drag-canvas', 'zoom-canvas', 'drag-node' ]
		},
		defaultNode: {
			type: 'image',
			size: 50,
			style: { cursor: "pointer" },
			clipCfg: { show: true, type: 'circle' },
			labelCfg: {
				position: "bottom", offset: 12,
				style: {
					fill: '#333',
					fontSize: 11,
					fontFamily: 'Microsoft YaHei',
					textAlign: 'center',
					background: {
						fill: 'rgba(255, 255, 255, 0.95)',
						padding: [4, 6, 4, 6],
						radius: 4
					}
				}
			}
		},
		defaultEdge: {
			type: "line",
			style: { lineWidth: 1, endArrow: true },
			labelCfg: {
				autoRotate: true,
				style: {
					cursor: "pointer",
					fontSize: 12,
					fontFamily: 'Microsoft YaHei',
					background: { padding: [4, 4, 4, 4] }
				}
			}
		}
	})

	// 节点点击处理
	graphInstance.on('node:click', (evt) => {
		let node = siderList.value.find(item => item.id==evt.item._cfg.model.id)
		if (node) handleClickDecree(node)
	});
	graphInstance.on('edge:click', (evt) => {
		let node = siderList.value.find(item => item.id==evt.item._cfg.model.target)
		if (node) handleClickSider(node)
	});

	graphInstance.data({nodes: nodeList, edges: edgeList})
  graphInstance.render()
}

const handleClickDecree = decree => {
	window.sessionStorage.setItem("curTabName", decree.name);
	const route = router.resolve({
		path: "/decreeLayout",
		query: {
			id: decree.id
		}
	});
	window.open(route.href, "_blank");
};

// 冲突关系
const graphContainer = ref(null);
let graph = null;
const onRelationChart = () => {
    const container = graphContainer.value;
		const nodeWidth = 180;
    const width = container.clientWidth;
    const height = container.clientHeight;
		const centerX = width / 2
		const centerY = height / 2 - 40
		const leftNodeX = centerX - nodeWidth;
    const rightNodeX = centerX + nodeWidth;

    const data = {
      nodes: [
				{
					id: mainInfo.value.id+'', label: `${mainInfo.value.time}\n${onWordWrap(mainInfo.value.label, 15)}`,
					size: [250, 80], x: leftNodeX, y: centerY,
				},
				{
					id: nodeInfo.value.id+'', label: `${nodeInfo.value.time}\n${onWordWrap(nodeInfo.value.label, 15)}`,
					size: [250, 80], x: rightNodeX, y: centerY,
				},
      ],
      edges: [
				{
					id: `edge-1`, target: nodeInfo.value.id+'', source: mainInfo.value.id+'', label: nodeInfo.value.relation,
					style: {
						stroke: ["", "#B9DCFF", "#87E8DE", "#FFCCC7"][1],
					},
					labelCfg: {
						style: {
							fill: ["", "#055FC2", "#13A8A8", "#CE4F51"][1],
							background: {
								fill: ["", "#E7F3FF", "#E6FFFB", "#FFE0E0"][1],
							}
						}
					}
				}
      ]
    };

    // 创建图实例
		if (!graph) {
			graph = new G6.Graph({
				container: container,
				width,
				height,
				defaultNode: {
					type: 'rect',
					anchorPoints: [[0, 0.5], [1, 0.5]],
					style: {
						cursor: "pointer",
						radius: 4,
						fill: '#f6faff',
						stroke: '#B9DCFF',
					},
					labelCfg: {
						style: { 
							cursor: "pointer",
							fill: "#333333",
							fontSize: 15,
							fontWeight: "bold",
							fontFamily: "Microsoft YaHei",
							textAlign: "center",
						}
					}
				},
				defaultEdge: {
					type: "line",
					style: {
						lineWidth: 1,
						endArrow: true,
					},
					labelCfg: {
						autoRotate: true,
						style: {
							fontSize: 14,
							fontFamily: 'Microsoft YaHei',
							background: {
								padding: [6, 4, 4, 4],
							}
						}
					}
				},
				layout: null,
				modes: { default: [] },
				fitView: false,
			});

			graph.on('node:click', (evt) => {
				let node = siderList.value.find(item => item.id==evt.item._cfg.model.id)
				if (node) handleClickDecree(node)
			});
		}

    // 加载数据并渲染
    graph.data(data);
    graph.render();
}

onMounted(() => {
	Promise.all([onDecreeSummaryData(), handleGetRelateOrder()]).then(() => {
		if (mainInfo.value.id && siderList.value.length) initChart()
	})
});

onBeforeUnmount(() => {
	graphInstance?.destroy()
	graph?.destroy()
})
</script>

<style lang="scss" scoped>
.wrap {
	height: 100%;
	width: 1600px;
	padding: 16px 0;
	display: flex;
	gap: 16px;
	margin: 0 auto;

	.box1 {
		width: 480px;

		.box1-main {
			padding: 10px 16px;
			height: 100%;
				
			.left-item {
				color: rgba(59, 65, 75, 1);
				font-family: Microsoft YaHei;
				border-bottom: 1px solid rgba(240, 242, 244, 1);
				padding: 10px;
				cursor: pointer;
				&:first-child {
					border-top: 1px solid rgba(240, 242, 244, 1);
				}
				&:hover {
					background: rgba(246, 250, 255, 1);
				}
				.item-head {
					display: flex;
					align-items: center;
					margin-bottom: 6px;
				}
				.itme-name {
					width: 20px;
					flex: auto;
					color: rgba(59, 65, 75, 1);
					font-family: Microsoft YaHei;
					font-size: 16px;
					font-weight: 600;
					letter-spacing: 0px;
				}
				.item-tag{
					height: 24px;
					line-height: 24px;
					text-align: center;
					padding: 0 8px;
					border-radius: 12px;
					background: rgba(231, 243, 255, 1);
					color: var(--color-main-active);
					font-family: Microsoft YaHei;
					font-size: 14px;
					font-weight: 400;
					letter-spacing: 0px;
					margin-left: 6px;
				}
				.itme-time {
					color: rgb(95, 101, 108);
					font-family: "Source Han Sans CN";
					font-size: 16px;
					font-weight: 400;
					letter-spacing: 0px;
				}
			}

			.item-active {
				background: rgba(246, 250, 255, 1);
				position: relative;

				&::after {
					position: absolute;
					content: "";
					width: 5px;
					height: 100%;
					background: var(--color-main-active);
					right: 0px;
					top: 0px;
				}
			}
		}
	}

	.box2 {
		width: 20px;
		flex: auto;
		.box2-main {
			height: 100%;
			padding: 10px;
			.graph-container {
				width: 100%;
				height: 600px;
			}
		}
	}
}

// 修改element-plus弹出框样式
:deep(.viewpoint-dialog) {
	padding: 0;
	border-radius: 4px;
	.el-dialog__body {
		padding: 0;
	}
	.el-dialog__header {
		padding: 0;
		margin: 0;
		position: relative;
		height: 48px;
	}
	.el-dialog__headerbtn {
		top: 50%;
		transform: translateY(-50%);
		right: 12px;
	}
	.viewpoint-header {
		height: 48px;
		display: flex;
		align-items: center;
		padding: 0 24px;
		border-bottom: 1px solid rgb(234, 236, 238);
	}
	.viewpoint-title {
		font-size: 16px;
		font-weight: 700;
		font-family: "Microsoft YaHei";
		line-height: 24px;
	}
	.viewpoint-body {
		padding: 16px;
		height: 560px;
		overflow: hidden;
		display: flex;
		flex-direction: column;
		.graph-tag {
      display: flex;
      align-items: center;
      padding: 7px 12px;
      border: 1px solid rgba(231, 243, 255, 1);
      border-radius: 4px;
      background: rgba(246, 250, 255, 1);
      margin-bottom: 9px;

      .icon1 {
        width: 19px;
        height: 20px;
        background-image: url("../assets/icons/ai.png");
        background-size: 100% 100%;
        flex-shrink: 0;
      }

      .title {
        color: rgb(5, 95, 194);
        font-size: 16px;
        font-weight: 400;
        line-height: 24px;
        margin-left: 13px;
        flex: 1;
      }

      .icon2Wrap {
        width: 24px;
        height: 24px;
        background-color: rgba(231, 243, 255, 1);
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 12px;
        margin-left: 20px;
        flex-shrink: 0;

        .icon2 {
          width: 24px;
          height: 24px;
          background-image: url("../assets/icons/right.png");
          background-size: 100% 100%;
        }
      }
    }
		.graph-container {
			width: 100%;
			height: 20px;
			flex: auto;
		}
	}
}

// 修改element-plus滚动条样式
:deep(.el-scrollbar__bar.is-vertical) {
	right: 0px;
	width: 4px;
	background: transparent;
	border-radius: 2px;
	&>div {
		background: #c5c7c9;
		opacity: 1;
	}
	&>div:hover {
		background: #505357;
	}
}
</style>
