<template>
	<div class="wrap">
		<div class="box1">
			<AnalysisBox title="相关政令" :showAllBtn="false">
				<div class="box1-main" v-loading="isLoading">
					<el-empty v-if="!siderList?.length" style="padding: 60px 0;" 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 style="height: 100%; width: 100%;" v-loading="isLoading">
					<el-empty v-if="!siderList?.length" style="padding: 60px 0;" description="暂无数据" :image-size="100" />
					<div class="box2-main" v-if="graphData.nodes?.length">
						<GraphChart :nodes="graphData.nodes" :links="graphData.links" layoutType="force" @handleClickNode="handleClickNode" />
					</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, reactive } 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 GraphChart from "@/components/base/GraphChart/index.vue";

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

const route = useRoute();

// 关联关系
const dialogVisible = ref(false);

// 基本信息
const mainInfo = ref({ label: "", time: "", id: "" });
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;
		}
	} catch (error) {
		mainInfo.value = { label: "", time: "", id: "" };
		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 graphData = reactive({
	nodes: [],
	links: [],
})
// 节点点击处理
const handleClickNode = ({data}) => {
	if (data.target) {
		let node = siderList.value.find(item => item.id==data.target)
		if (node) handleClickSider(node)
	} else {
		let node = siderList.value.find(item => item.id==data.id)
		if (node) handleClickDecree(node)
	}
}
const isLoading = ref(false);
const initGraphChart = () => {
	isLoading.value = true;
	Promise.all([onDecreeSummaryData(), handleGetRelateOrder()]).then(() => {
		if (mainInfo.value.id && siderList.value.length) {
			graphData.links = siderList.value.map(onFormatLink)
			graphData.nodes = siderList.value.map(onFormatNode)
			graphData.nodes.unshift(onFormatNode(mainInfo.value))
		}
		isLoading.value = false;
	})
}
const onFormatLink = (item, index) => {
	return {
		id: `link-${index+1}`,
		source: route.query.id, target: item.id+'',
		label: { show: true, color: "#055fc2", backgroundColor: "#eef7ff", borderWidth: 0, offset: [0, 15], formatter: item.relation },
		lineStyle: { color: '#B9DCFF', type: "solid", opacity: 1 }
	}
}
const onFormatNode = (item) => {
	let leader = item.id == mainInfo.value.id;
	return {
		id: item.id+'',
		name: onWordWrap(item.label, 8),
		label: {
			show: true,
			color: leader ? "#055fc2" : "#3b414b",
			fontSize: leader ? 16 : 14,
			fontWeight: leader ? 700 : 400,
			fontFamily: 'Source Han Sans CN',
		},
		symbolSize: leader ? 60 : 40,
		symbol: `image://${leader ? icon1628 : icon1629}`
	}
}
// 文本插入换行符
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 handleClickDecree = decree => {
	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: ["", "#eef7ff", "#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(() => {
	initGraphChart()
});

onBeforeUnmount(() => {
	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;
		}
	}
}

// 修改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>
