<template>
	<div class="main main-association">
		<div class="left">
			<!-- ... 左侧代码保持不变 ... -->
			<AnalysisBox title="制裁历程">
				<div class="left-main">
					<div class="date-picker-box">
						<el-date-picker
							v-model="dateRange"
							type="daterange"
							range-separator="--"
							start-placeholder="开始日期"
							end-placeholder="结束日期"
							value-format="YYYY-MM-DD"
							style="width: 100%"
							:clearable="false"
							@change="handleDateChange"
						/>
					</div>
					<div class="list-header">
						<el-checkbox v-model="isAllSelected" :indeterminate="indeterminate" @change="handleCheckAllChange">
							全选
						</el-checkbox>
						<div class="count">共{{ sanctionList.length }}次制裁</div>
					</div>
					<div class="list-content" v-loading="loading">
						<div class="list-item" v-for="item in sanctionList" :key="item.id" @click="handleSanctionSelect(item.id)">
							<el-checkbox v-model="item.checked" @change="val => handleCheckOneChange(val, item)" @click.stop>
								<div class="item-label">
									<div class="item-left">
										{{ dayjs(item.date).format("YYYY年MM月DD日") }}-{{ "SDN清单更新" }}
									</div>
									<div class="item-right">{{ item.count }}{{ item.unit }}</div>
								</div>
							</el-checkbox>
						</div>
					</div>
					<el-button type="primary" @click="handleAssociationClick" style="height: 36px">
						多投融资限制举措关联分析
						<el-icon><Right /></el-icon>
					</el-button>
				</div>
			</AnalysisBox>
		</div>
		<div class="right">
			<AnalysisBox title="投融资限制举措关系图">
				<div class="right-main">
					<div class="relation-empty" v-if="selectedSanctionIds.length == 0">
						<el-empty :image="emptyImg" :image-size="200">
							<template #description>
								<div class="empty">请在左侧勾选多次投融资限制制裁后点击“开始分析”查看结果</div>
							</template>
						</el-empty>
					</div>
					<div class="relation-content" v-else>
						<!-- 绑定转换后的 graphNodes 和 graphLinks -->
						<GraphChart :nodes="graphNodes" :links="graphLinks" @handleClickNode="handleClickNode" />
					</div>
				</div>
			</AnalysisBox>
		</div>
		<el-dialog v-model="nodeVisible" :title="curNode?.data?.name || '制裁历程'" width="960">
			<div class="dialog-content">
				<div class="info-btn">
					<el-button type="primary" :style="{ borderRadius: '8px', paddingTop: '10px' }" @click="handleInfoClick">
						查看详情 >
					</el-button>
				</div>
				<div class="content-item">
					<div class="item-label">制裁标题：</div>
					<div class="item-desc item-label">
						{{ vertexInfo.name }}
					</div>
				</div>
				<div class="content-item">
					<div class="item-label">制裁领域：</div>
					<div class="item-desc">
						<AreaTag v-for="item in vertexInfo.domainList" :key="item" :tagName="item" />
					</div>
				</div>
				<div class="content-item">
					<div class="item-label">依托文件：</div>
					<div class="item-desc">
						<div class="item-file" v-for="item in vertexInfo.relyFileList" :key="item.id">
							<div class="item-file-name">
								{{ item.name }}
							</div>
							<img :src="openIcon" alt="文件" class="item-file-icon" />
						</div>
					</div>
				</div>
				<div class="content-item">
					<div class="item-label">依托制裁：</div>
					<div class="item-desc">
						<div class="item-file" v-for="item in vertexInfo.relySanList" :key="item.id">
							<div class="item-file-name">
								{{ item.title }}
							</div>
							<img :src="openIcon" alt="文件" class="item-file-icon" />
						</div>
					</div>
				</div>
				<div class="content-item">
					<div class="item-label">制裁原因：</div>
					<div class="item-desc-table">
						<div class="item-file" v-for="item in vertexInfo.sanReasonList" :key="item">
							<div class="dot"></div>
							<div class="item-file-name">{{ item }}</div>
						</div>
					</div>
				</div>
				<div class="content-item">
					<div class="item-label">制裁对象：</div>
					<div class="item-desc item-desc-table">
						<span class="item-table-desc" v-if="vertexInfo.addObjectList?.length || vertexInfo.delObjectList?.length">
							{{ formatChangeSummary(vertexInfo.addObjectList, vertexInfo.delObjectList) }}
						</span>
						<el-table :data="vertexInfo.sanList" stripe>
							<el-table-column property="entityNameZh" label="制裁对象" width="350" />
							<el-table-column property="domainNames" label="所属领域" width="400">
								<template #default="scope">
									<AreaTag v-for="item in scope.row.domainNames" :key="item" :tagName="item" />
								</template>
							</el-table-column>
						</el-table>
					</div>
				</div>
			</div>
		</el-dialog>

		<el-dialog :title="curLink.data?.relationType + '关系' || '关联关系'" v-model="relationVisible" width="960">
			<div class="dialog-content">
				<div class="hintWrap">
					<div class="icon1"></div>
					<div class="title">
						{{ tipsInfo }}
					</div>
					<div class="icon2Wrap">
						<div class="icon2"></div>
					</div>
				</div>
				<RelationChart :is-vertical-chart="true" :graph-data="graphData" />
			</div>
		</el-dialog>
	</div>
</template>

<script setup>
import { ref, onMounted, computed } from "vue";
import GraphChart from "@/components/base/GraphChart/index.vue";
import RelationChart from "@/components/base/RelationChart/index.vue";
import emptyImg from "../assets/empty.png";
import markIcon from "../assets/icon-mark.png"; // 引入图标
import openIcon from "../../../../assets/icons/icon-open.png";
import { getSanRecord, getRecordRelation, getVertexInfo, getEdgeInfo } from "@/api/finance";
import { useRoute, useRouter } from "vue-router";
import dayjs from "dayjs";

const route = useRoute();
const router = useRouter();

// 定义颜色映射
const colors = {
	// 相似
	similarity: {
		fontColor: "rgba(5, 95, 194)",
		color: "rgb(231, 243, 255)", // 连线颜色 & 标签背景
		lineColor: "rgba(5, 95, 194)" // 专门用于连线的颜色，如果需要和背景色区分
	},
	// 继承
	inheritance: {
		fontColor: "rgba(19, 168, 168)",
		color: "rgba(230, 255, 251, 1)",
		lineColor: "rgba(19, 168, 168)"
	},
	// 冲突
	conflict: {
		fontColor: "rgb(206, 79, 81)",
		color: "rgba(255, 241, 240, 1)", // 修正：冲突背景通常偏红/浅红，这里沿用你提供的蓝色背景可能不太符合直觉，但我保留你的配置或微调
		lineColor: "rgb(206, 79, 81)"
	}
};

const handleInfoClick = () => {
	window.sessionStorage.setItem("curTabName", `${curNode.value.data.originDate}-《${curNode.value.data.originName}》`);

	const routeData = router.resolve({
		path: "/finance/singleSanction",
		query: {
			id: curNode.value.data.id,
			sanTypeId: sanTypeId.value
		}
	});
	// 打开新页面
	window.open(routeData.href, "_blank");
};
// 辅助函数：获取关系类型对应的颜色配置
const getRelationStyle = relationType => {
	switch (relationType) {
		case "相似":
			return colors.similarity;
		case "继承":
			return colors.inheritance;
		case "冲突":
			return colors.conflict;
		default:
			return {
				fontColor: "#666",
				color: "#f0f2f5",
				lineColor: "#AED6FF"
			};
	}
};

const selectedSanctionIds = ref([]);
const isAllSelected = computed({
	get() {
		return sanctionList.value.length > 0 && sanctionList.value.every(item => item.checked);
	}
});

const handleCheckAllChange = val => {
	sanctionList.value.forEach(item => {
		item.checked = val;
	});
	updateSelectedIds();
};

const handleCheckOneChange = (val, item) => {
	item.checked = val;
	updateSelectedIds();
};

const updateSelectedIds = () => {
	selectedSanctionIds.value = sanctionList.value.filter(item => item.checked).map(item => item.id);
	if (selectedSanctionIds.value.length === 1) {
		currentSanctionId.value = selectedSanctionIds.value[0];
	}
};

const indeterminate = computed(() => {
	const checkedCount = sanctionList.value.filter(item => item.checked).length;
	return checkedCount > 0 && checkedCount < sanctionList.value.length;
});

const recordRelation = ref({ noRelationVertices: [], relationVoList: [] });

// 【修改】处理图表节点数据
const graphNodes = computed(() => {
	const nodesMap = new Map();

	// 定义统一的标签样式
	const labelStyle = {
		show: true,
		position: "bottom", // 标签位置，可根据需要调整为 'top', 'left', 'right', 'inside' 等
		fontSize: 14,
		fontWeight: 400,
		fontFamily: "Source Han Sans CN",
		lineHeight: 22,
		color: "#333" // 默认字体颜色，可根据需要调整
		// 如果标签背景需要透明或特定颜色，可以添加 backgroundColor
		// backgroundColor: 'rgba(255, 255, 255, 0.8)',
		// padding: [2, 4]
	};

	// 1. 处理无关联节点
	if (recordRelation.value.noRelationVertices) {
		recordRelation.value.noRelationVertices.forEach(node => {
			if (!nodesMap.has(node.id)) {
				nodesMap.set(node.id, {
					id: node.id,
					// name: node.name,
					originDate: node.date,
					originName: node.name,
					name: dayjs(node.date).format("YYYY年MM月DD日") + " " + "SDN清单更新",
					symbol: `image://${markIcon}`, // 设置自定义图标
					symbolSize: [50, 50], // 根据图标实际大小调整
					itemStyle: {
						color: "#91cc75"
					},
					label: { ...labelStyle } // 应用标签样式
				});
			}
		});
	}

	// 2. 处理关联节点
	if (recordRelation.value.relationVoList) {
		recordRelation.value.relationVoList.forEach(rel => {
			const from = rel.fromVertex;
			const to = rel.toVertex;

			if (from && !nodesMap.has(from.id)) {
				nodesMap.set(from.id, {
					id: from.id,
					// name: from.name,
					originDate: from.date,
					originName: from.name,
					name: dayjs(from.date).format("YYYY年MM月DD日") + " " + "SDN清单更新",
					symbol: `image://${markIcon}`, // 设置自定义图标
					symbolSize: [50, 50],
					itemStyle: {
						color: "#5470c6"
					},
					label: { ...labelStyle } // 应用标签样式
				});
			}

			if (to && !nodesMap.has(to.id)) {
				nodesMap.set(to.id, {
					id: to.id,
					// name: to.name,
					name: dayjs(to.date).format("YYYY年MM月DD日") + " " + "SDN清单更新",
					symbol: `image://${markIcon}`, // 设置自定义图标
					symbolSize: [50, 50],
					itemStyle: {
						color: "#5470c6"
					},
					label: { ...labelStyle } // 应用标签样式
				});
			}
		});
	}

	return Array.from(nodesMap.values());
});

// 【修改】处理图表连线数据
const graphLinks = computed(() => {
	if (!recordRelation.value.relationVoList) return [];

	return recordRelation.value.relationVoList.map(rel => {
		const relationType = rel.edgeInfo ? rel.edgeInfo.value : "";
		const style = getRelationStyle(relationType);

		return {
			source: rel.fromVertex.id,
			target: rel.toVertex.id,
			// 将样式信息挂载到 label 或 data 上，供 formatter 和 lineStyle 使用
			label: {
				formatter: relationType,
				show: true,
				color: style.fontColor, // 字体颜色
				backgroundColor: style.color, // 标签背景色
				borderColor: style.color, // 标签边框色
				padding: [4, 8],
				borderRadius: 4,
				fontSize: 12
			},
			lineStyle: {
				color: style.lineColor, // 连线颜色
				width: 1,
				type: "solid"
				// curveness: 0.1 // 稍微有点弧度可能更好看
			},
			// 额外存储原始数据，以备后用
			relationType: relationType,
			edgeInfo: rel.edgeInfo,
			originInfo: rel
		};
	});
});

const handleAssociationClick = () => {
	console.log("handleAssociationClick", selectedSanctionIds.value);
	fetchRecordRelation();
};

const fetchRecordRelation = async () => {
	if (selectedSanctionIds.value.length === 0) {
		return;
	}
	try {
		const res = await getRecordRelation(selectedSanctionIds.value);
		console.log("getRecordRelation", res);
		if (!!res) {
			recordRelation.value = res;
		} else {
			recordRelation.value = { noRelationVertices: [], relationVoList: [] };
		}
	} catch (error) {
		console.error("获取制裁记录关联信息失败:", error);
		recordRelation.value = { noRelationVertices: [], relationVoList: [] };
	}
};
const vertexInfo = ref({});
const curNode = ref({});
const curLink = ref({});
const nodeVisible = ref(false);
const relationVisible = ref(false);
const tipsInfo = ref("");
const graphData = ref({});
const getTipsInfo = (relationType, reason) => {
	switch (relationType) {
		case "继承":
			return `${dayjs(curLink.value.data.originInfo.fromVertex.date).format("YYYY年MM月DD日")}-SDN清单更新依托于${dayjs(curLink.value.data.originInfo.toVertex.date).format("YYYY年MM月DD日")}-SDN清单更新，两次制裁存在继承关系。`;
		case "冲突":
			return `${dayjs(curLink.value.data.originInfo.toVertex.date).format("YYYY年MM月DD日")}-SDN清单更新中制裁的实体在${dayjs(curLink.value.data.originInfo.fromVertex.date).format("YYYY年MM月DD日")}-SDN清单更新中被移除，存在冲突关系。`;
		default:
			return `${dayjs(curLink.value.data.originInfo.fromVertex.date).format("YYYY年MM月DD日")}-SDN清单更新与${dayjs(curLink.value.data.originInfo.toVertex.date).format("YYYY年MM月DD日")}-SDN清单更新存在相同${reason}，属于相似关系。`;
	}
};
const handleClickNode = node => {
	console.log("节点点击", node);
	if (node.dataType == "node") {
		nodeVisible.value = true;
		curNode.value = node;
		getVertexInfo(node.data.id).then(res => {
			console.log("getVertexInfo", res);
			if (!!res) {
				vertexInfo.value = res;
				nodeVisible.value = true;
			} else {
				vertexInfo.value = {};
			}
		});
	} else {
		relationVisible.value = true;
		curLink.value = node;
		const relationType = node.data.relationType;
		// 继承 - 2025年10月1日-SDN清单更新依托于2024年2月08日-SDN清单更新，两次制裁存在继承关系。
		// 冲突 - 2025年2月19日-SDN清单更新中制裁的实体在2024年2月08日-SDN清单更新中被移除，属于冲突关系。
		// 相似 - 2025年2月19日-SDN清单更新与2024年2月08日-SDN清单更新存在相同制裁原因，属于相似关系。
		// 相似 - 2025年2月19日-SDN清单更新与2024年2月08日-SDN清单更新存在同领域制裁实体，属于相似关系。
		// 相似 - 2025年2月19日-SDN清单更新与2024年2月08日-SDN清单更新存在相同依托文件，属于相似关系。

		getEdgeInfo(node.data.edgeInfo.key).then(res => {
			if (!!res) {
				// recordRelation.value = res;
				console.log("制裁之间的关系 =>", res);
				let reason = "";
				if (relationType == "相似") {
					reason = res[0].edgeReasonList[0].reason;
				}
				tipsInfo.value = getTipsInfo(relationType, reason);
			} else {
				// recordRelation.value = { noRelationVertices: [], relationVoList: [] };
			}
		});
	}
};

// 【新增/修改】格式化变动 summary 的函数
const formatChangeSummary = (addList, delList) => {
	const parts = [];

	// 处理新增列表
	if (addList && addList.length > 0) {
		// 将每个对象转换为 "value个实体" 或 "value名个人" 的形式
		const addItems = addList.map(item => {
			let unit = "个";
			let noun = "实体";
			if (item.key === "人物") {
				unit = "名";
				noun = "个人";
			} else if (item.key === "机构") {
				// 默认机构对应实体，也可以根据需求调整
				unit = "个";
				noun = "实体";
			}
			return `${item.value}${unit}${noun}`;
		});

		// 拼接：新增 + item1 + ， + item2 ...
		parts.push(`新增${addItems.join("，")}`);
	}

	// 处理移除列表
	if (delList && delList.length > 0) {
		// 将每个对象转换为 "value个实体" 或 "value名个人" 的形式
		const delItems = delList.map(item => {
			let unit = "个";
			let noun = "实体";
			if (item.key === "人物") {
				unit = "名";
				noun = "个人";
			} else if (item.key === "机构") {
				unit = "个";
				noun = "实体";
			}
			return `${item.value}${unit}${noun}`;
		});

		// 拼接：移除 + item1 + ， + item2 ...
		// 注意：题目要求“删除”，但之前代码用的是“移除”，这里统一使用“移除”或“删除”。
		// 根据题目描述“展示样本为：新增12个实体，3名个人，移除1个实体”，这里使用“移除”更贴切上下文，
		// 如果必须用“删除”，请将下面的 '移除' 改为 '删除'。
		parts.push(`移除${delItems.join("，")}`);
	}

	return parts.length > 0 ? parts.join("，") : "无变动";
};

const loading = ref(false);
const sanctionList = ref([]);
const currentSanctionId = ref(5);
const dateRange = ref(["2025-01-01", "2025-12-31"]);
const sanTypeId = ref("");

const fetchSanRecord = async () => {
	loading.value = true;
	const params = {
		startDate: dateRange.value && dateRange.value[0] ? dateRange.value[0] : "",
		endDate: dateRange.value && dateRange.value[1] ? dateRange.value[1] : "",
		sanTypeId: sanTypeId.value || 1
	};
	try {
		const res = await getSanRecord(params);
		if (res && res.length > 0) {
			sanctionList.value = res.map(item => ({
				id: item.sanRecordId,
				date: item.sanRecordDate,
				title: item.sanRecordName,
				count: item.cnEntitiesNum,
				unit: "家中国实体"
			}));

			if (sanctionList.value.length > 0) {
				currentSanctionId.value = sanctionList.value[0].id;
			}
		} else {
			sanctionList.value = [];
		}
	} catch (error) {
		console.error("获取选择制裁数据失败:", error);
		sanctionList.value = [];
	} finally {
		loading.value = false;
	}
};

const handleDateChange = () => {
	fetchSanRecord();
};

const handleSanctionSelect = id => {
	currentSanctionId.value = id;
};

onMounted(() => {
	sanTypeId.value = route.query.sanTypeId || "";
	fetchSanRecord();
});
</script>

<style lang="scss" scoped>
/* 样式保持不变 */
.main {
	width: 100%;
	padding-top: 12px;
	padding-bottom: 50px;
	display: flex;
	justify-content: space-between;

	.left {
		width: 480px;
		height: 828px;

		.left-main {
			margin-top: 11px;
			padding: 0 22px 0 23px;
			display: flex;
			flex-direction: column;
			height: calc(100% - 25px);

			.date-picker-box {
				margin-bottom: 16px;
			}

			.list-header {
				display: flex;
				justify-content: space-between;
				align-items: center;
				margin-bottom: 16px;
				font-size: 14px;
				color: #666;

				.count {
					font-size: 16px;
					font-weight: 400;
					font-family: "Microsoft YaHei";
					color: rgb(95, 101, 108);
				}
			}

			.list-content {
				flex: 1;
				overflow-y: auto;
				padding-bottom: 20px;

				&::-webkit-scrollbar {
					width: 6px;
				}

				&::-webkit-scrollbar-thumb {
					background: #ccc;
					border-radius: 3px;
				}

				.list-item {
					border: 1px solid rgb(234, 236, 238);
					border-radius: 4px;
					margin-bottom: 8px;
					display: flex;
					align-items: center;
					justify-content: space-between;
					padding: 15px 16px;
					cursor: pointer;
					transition: all 0.3s;
					position: relative;
					background: #fff;
					.item-label {
						display: flex;
						justify-content: space-between;
						align-items: center;
					}

					.item-left {
						width: 260px;
						font-weight: 700;
						color: rgb(59, 65, 75);
						font-size: 16px;
						font-family: "Microsoft YaHei";
						white-space: nowrap;
						overflow: hidden;
						text-overflow: ellipsis;
						margin-right: 10px;
					}

					.item-right {
						color: rgb(132, 136, 142);
						font-size: 16px;
						font-weight: 400;
						font-family: "Microsoft YaHei";
						flex-shrink: 0;
					}

					&:hover {
						border-color: #055fc2;
					}

					&.active {
						border-color: rgb(5, 95, 194);
						background-color: rgba(246, 250, 255, 1);

						.item-left,
						.item-right {
							color: rgb(5, 95, 194);
						}

						&::after {
							content: "";
							position: absolute;
							right: 0;
							top: 10px;
							bottom: 10px;
							width: 4px;
							background-color: rgb(5, 95, 194);
						}
					}
				}
			}
		}
	}

	.right {
		width: 1105px;
		height: 828px;

		.right-main {
			margin-top: 11px;
			height: calc(100% - 10px);
			padding: 0 16px 16px 16px;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			.relation-empty {
				display: flex;
				justify-content: center;
				align-items: center;
				height: 300px;
				width: 300px;
				.empty {
					font-size: 16px;
					font-weight: 400;
					font-family: Source Han Sans CN;
					color: rgb(132, 136, 142);
					line-height: 30px;
				}
			}
			.relation-content {
				width: 100%;
				height: 100%;
			}
		}
	}
}
.main-association {
	padding-top: 12px !important;
	justify-content: flex-start !important;
	gap: 16px;
}
.dialog-content {
	position: relative;
	padding: 20px;
	display: flex;
	flex-direction: column;
	gap: 16px;
	border-top: 1px solid rgb(238, 238, 238);
	.hintWrap {
		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/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/right.png");
				background-size: 100% 100%;
			}
		}
	}
	.info-btn {
		position: absolute;
		top: 20px;
		right: 20px;
	}
	.content-item {
		display: flex;
		justify-content: flex-start;
		align-items: flex-start;
		gap: 8px;
		.item-label {
			min-width: 75px;
			font-size: 14px;
			font-weight: 700;
			font-family: Source Han Sans CN;
			color: rgba(59, 65, 75, 1);
			line-height: 24px;
		}
		.item-desc-table {
			display: flex;
			flex-direction: column;
			padding-top: 3px;
			.dot {
				width: 4px;
				height: 4px;
				border-radius: 50%;
				background-color: rgb(59, 65, 75);
			}
			.item-file {
				display: flex;
				justify-content: flex-start;
				align-items: center;
				gap: 8px;
				// background: rgb(231, 243, 255);
				// border-radius: 20px;
				// border: 1px solid rgb(231, 243, 255);
				padding: 4px 0px;
				font-family: Source Han Sans CN;
				font-size: 16px;
				font-weight: 400;
			}
		}
		.item-desc {
			font-size: 14px;
			font-family: Source Han Sans CN;
			margin-top: 1px;
			display: flex;
			gap: 15px;

			.item-file {
				display: flex;
				justify-content: flex-start;
				align-items: center;
				gap: 8px;
				background: rgb(231, 243, 255);
				border-radius: 20px;
				border: 1px solid rgb(231, 243, 255);
				padding: 5px 15px;
				cursor: pointer;
				.item-file-name {
					font-size: 16px;
					font-weight: 400;
					font-family: Source Han Sans CN;
					color: rgb(5, 95, 194);
					line-height: 24px;
				}
				.item-file-icon {
					width: 16px;
					height: 16px;
					margin-top: 1px;
				}
			}
		}
	}
}
</style>
