<template>
	<div class="character-relationships">
		<div class="headerBox">
			<span
				v-for="(item, index) in list"
				:key="index"
				class="headerItem"
				:class="{ active: item === activeIndex }"
				@click="activeIndex = item"
				>{{ item }}</span
			>
		</div>
		<div class="headerBtnBox"><img src="./assets/下载按钮.png" alt="" /><img src="./assets/收藏按钮.png" alt="" /></div>
		<!-- 主要内容，人物关系图 -->
		<div class="mainBox">
			<div class="graph" id="relGraph"></div>
		</div>
	</div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts";
import {getCharacterGlobalInfo, getCharacterRelation } from "@/api/characterPage/characterPage.js";


import 'default-passive-events';

import { useRoute } from 'vue-router';
const route = useRoute();
const personId = ref(route.query.personId || "Y000064");



// const nodes = [
// 	{
// 		id: "c",
// 		name: "埃隆·马斯克",
// 		category: 0,
// 		symbolSize: 80,
// 		symbol: `image://${Center}`,
// 		label: {
// 			show: true,
// 			position: "bottom",
// 			formatter: "{n|{b}}",
// 			rich: {
// 				n: {
// 					color: "rgba(5,95,194,1)",
// 					fontSize: 24,
// 					fontWeight: 700,
// 					fontFamily: "Microsoft YaHei",
// 					lineHeight: 36
// 				}
// 			}
// 		}
// 	},
// 	// 从三点钟方向顺时针排序
// 	{ id: "n11", name: "贾斯汀・马斯克", category: 1, symbolSize: 80, symbol: `image://${P11}` },
// 	{ id: "n7", name: "杰弗里·凯斯勒", category: 1, symbolSize: 80, symbol: `image://${P7}`, r: 80 },
// 	{ id: "n6", name: "斯科特·贝森特", category: 1, symbolSize: 80, symbol: `image://${P6}` },
// 	{ id: "n9", name: "道格·伯格姆", category: 1, symbolSize: 80, symbol: `image://${P9}` },
// 	{ id: "n12", name: "史蒂夫・尤尔韦松", category: 1, symbolSize: 80, symbol: `image://${PS}` },
// 	{ id: "n5", name: "拉里・埃里森", category: 1, symbolSize: 80, symbol: `image://${P5}`, r: 80 },
// 	{ id: "n8", name: "马尔科·卢比奥", category: 1, symbolSize: 80, symbol: `image://${P8}` },
// 	{ id: "n10", name: "艾拉・埃伦普里斯", category: 1, symbolSize: 80, symbol: `image://${P10}`, r: 80 },
// 	{ id: "n2", name: "詹姆斯・默多克", category: 1, symbolSize: 80, symbol: `image://${P2}` },
// 	{ id: "n1", name: "唐纳德・特朗普", category: 1, symbolSize: 80, symbol: `image://${P1}` },
// 	{ id: "n4", name: "金博尔・马斯克", category: 1, symbolSize: 80, symbol: `image://${P4}` },
// 	{ id: "n3", name: "格温・肖特韦尔", category: 1, symbolSize: 80, symbol: `image://${P3}`, r: 80 }
// ];


// const links = [
// 	{ source: "n11", target: "c", label: { show: true, formatter: "第一任妻子" } },
// 	{ source: "n7", target: "c", label: { show: true, formatter: "风险投资家" } },
// 	{ source: "n6", target: "c", label: { show: true, formatter: "特斯拉董事" } },
// 	{ source: "n9", target: "c", label: { show: true, formatter: "特斯拉董事" } },
// 	{ source: "n12", target: "c", label: { show: true, formatter: "特斯拉董事" } },
// 	{ source: "n5", target: "c", label: { show: true, formatter: "早期重要投资人" } },
// 	{ source: "n8", target: "c", label: { show: true, formatter: "Boring Company 总裁" } },
// 	{ source: "n10", target: "c", label: { show: true, formatter: "特斯拉独立董事" } },
// 	{ source: "n2", target: "c", label: { show: true, formatter: "特斯拉董事" } },
// 	{ source: "n1", target: "c", label: { show: true, formatter: "美国总统" } },
// 	{ source: "n4", target: "c", label: { show: true, formatter: "马斯克弟弟" } },
// 	{ source: "n3", target: "c", label: { show: true, formatter: "SpaceX 总裁" } }
// ];

// 处理图片代理
const getProxyUrl = (url) => {
	if (!url) return "";
	const urlStr = String(url);
	// 排除非 http 开头（相对路径）、已经是代理链接、或者是本地链接
	if (!urlStr.startsWith('http') || urlStr.includes('images.weserv.nl') || urlStr.includes('localhost') || urlStr.includes('127.0.0.1')) {
		return url;
	}
	// 移除协议头 http:// 或 https://
	const cleanUrl = urlStr.replace(/^https?:\/\//i, '');
	return `https://images.weserv.nl/?url=${encodeURIComponent(cleanUrl)}`;
};

const nodes = ref([]);
const links = ref([]);

// 人物全局信息
const characterInfo = ref({});
	// 人物关系
const CharacterRelation = ref([]);

const getCharacterGlobalInfoFn = async () => {
	const params = {
		personId: personId.value
	};

	
	

	try{
		const res = await getCharacterGlobalInfo(params);
		
		if (res.code === 200) {
			console.log("人物全局信息", res);
			if (res.data) {
				characterInfo.value = res.data;
			}
			
		}
		

	}catch(error){

	}
	
};



const getCharacterRelationFn = async () => {
	const params = {
		personId: personId.value
	};
	try{
		const res = await getCharacterRelation(params);
		if (res.code === 200) {
			console.log("人物关系", res);
			if (res.data) {
				CharacterRelation.value = res.data;
			}
		}
		
		if(CharacterRelation.value.length > 0){
			const centerNode = {
				id: "c",
				name: characterInfo.value.name,
				category: 0,
				symbolSize: 80,
				symbol: `image://${characterInfo.value.imageUrl}`,
				label: {
					show: true,
					position: "bottom",
					formatter: "{n|{b}}",
					rich: {
						n: {
							color: "rgba(5,95,194,1)",
							fontSize: 24,
							fontWeight: 700,
							fontFamily: "Microsoft YaHei",
							lineHeight: 36
						}
					}
				}
			}

			const newNodes = CharacterRelation.value.map((item,index) => {
				return{
					id: index,
					name: item.name,
					category: 1,
					symbolSize: 80,
					symbol: `image://${getProxyUrl(item.imageUrl)}`
				}
			});

			newNodes.push(centerNode);

			const newLinks = CharacterRelation.value.map((item,index) =>({
				source:index,
				target:"c",
				label: { 
					show: true, 
					formatter: item.relation }
			}));

			nodes.value = newNodes;
			links.value = newLinks;
			
		}else{
			nodes.value = [{
				id: "c",
				name: characterInfo.value.name,
				category: 0,
				symbolSize: 80,
				symbol: `image://${characterInfo.value.imageUrl}`,
				label: {
					show: true,
					position: "bottom",
					formatter: "{n|{b}}",
					rich: {
						n: {
							color: "rgba(5,95,194,1)",
							fontSize: 24,
							fontWeight: 700,
							fontFamily: "Microsoft YaHei",
							lineHeight: 36
						}
					}
				}
			}];
			links.value = [];
		}
		const el = document.getElementById("relGraph");
	if (!el) return;
	chart = echarts.init(el);
	
	const setOption = () => {
		const rect = el.getBoundingClientRect();
		const cx = rect.width / 2;
		const cy = rect.height / 2;
		const radius = Math.min(cx, cy) - 140;

		const dataNodes = nodes.value.map((n, i) => {
			if (n.id === "c") {
				return { ...n, x: cx, y: cy, fixed: true };
			}
			// 均匀环形分布
			const idx = i - 1;
			const angle = (idx / (nodes.value.length - 1)) * Math.PI * 2;
			const rLocal = radius + (n.r || 0);
			const x = cx + rLocal * Math.cos(angle);
			const y = cy + rLocal * Math.sin(angle);
			return { ...n, x, y };
		});

		chart.setOption({
			tooltip: {},
			series: [
				{
					type: "graph",
					layout: activeIndex.value === "圆形布局" ? "none" : "force",
					circular: { rotateLabel: true },
					force: { repulsion: 800, edgeLength: [80, 160] },
					roam: true,
					data: activeIndex.value === "圆形布局" ? dataNodes : nodes.value,
					links: links.value,
					edgeSymbol: ["none", "arrow"],
					edgeSymbolSize: [4, 10],
					lineStyle: { color: "rgba(174,214,255,1)", width: 2, opacity: 0.8 },
					edgeLabel: {
						show: true,
						position: "middle",
						distance: -18,
						formatter: ({ data }) => data?.label?.formatter || "",
						color: "rgb(5, 95, 194)",
						fontSize: 12,
						fontWeight: 400,
						fontFamily: "Microsoft YaHei",
						lineHeight: 24,
						backgroundColor: "rgba(231, 243, 255, 1)",
						borderRadius: 24,
						padding: [0, 12]
					},
					label: { show: true, position: "bottom", color: "rgb(59,65,75)", fontSize: 16 },
					itemStyle: { color: "rgba(5,95,194,1)" },
					emphasis: { focus: "adjacency" }
				}
			]
		});
	};
	setOption();
	

	}catch(error){

	}
	
};



const list = ref(["圆形布局", "力导向布局", "树形布局"]);
const activeIndex = ref("圆形布局");




let chart;




onMounted(() => {
	getCharacterGlobalInfoFn();
	getCharacterRelationFn();
	const el = document.getElementById("relGraph");
	if (!el) return;
	chart = echarts.init(el);
	
	const setOption = () => {
		const rect = el.getBoundingClientRect();
		const cx = rect.width / 2;
		const cy = rect.height / 2;
		const radius = Math.min(cx, cy) - 140;

		const dataNodes = nodes.value.map((n, i) => {
			if (n.id === "c") {
				return { ...n, x: cx, y: cy, fixed: true };
			}
			// 均匀环形分布
			const idx = i - 1;
			const angle = (idx / (nodes.value.length - 1)) * Math.PI * 2;
			const rLocal = radius + (n.r || 0);
			const x = cx + rLocal * Math.cos(angle);
			const y = cy + rLocal * Math.sin(angle);
			return { ...n, x, y };
		});

		chart.setOption({
			tooltip: {},
			series: [
				{
					type: "graph",
					layout: activeIndex.value === "圆形布局" ? "none" : "force",
					circular: { rotateLabel: true },
					force: { repulsion: 800, edgeLength: [80, 160] },
					roam: true,
					data: activeIndex.value === "圆形布局" ? dataNodes : nodes.value,
					links: links.value,
					edgeSymbol: ["none", "arrow"],
					edgeSymbolSize: [4, 10],
					lineStyle: { color: "rgba(174,214,255,1)", width: 2, opacity: 0.8 },
					edgeLabel: {
						show: true,
						position: "middle",
						distance: -18,
						formatter: ({ data }) => data?.label?.formatter || "",
						color: "rgb(5, 95, 194)",
						fontSize: 12,
						fontWeight: 400,
						fontFamily: "Microsoft YaHei",
						lineHeight: 24,
						backgroundColor: "rgba(231, 243, 255, 1)",
						borderRadius: 24,
						padding: [0, 12]
					},
					label: { show: true, position: "bottom", color: "rgb(59,65,75)", fontSize: 16 },
					itemStyle: { color: "rgba(5,95,194,1)" },
					emphasis: { focus: "adjacency" }
				}
			]
		});
	};
	setOption();
	console.log("node1", nodes);
	const onResize = () => chart && chart.resize();
	window.addEventListener("resize", onResize);
	watch(activeIndex, () => setOption());
	onBeforeUnmount(() => {
		window.removeEventListener("resize", onResize);
		chart && chart.dispose();
	});
});
</script>

<style lang="scss" scoped>
* {
	padding: 0;
	margin: 0;
}
.character-relationships {
	width: 1600px;
	height: 688px;
	background-color: #fff;
	margin: 0 auto;
	position: relative;
	border-radius: 4px;
	box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
	.headerBox {
		position: absolute;
		top: 14px;
		right: 96px;
		.headerItem {
			padding: 1px 8px;
			border-radius: 4px;
			font-size: 16px;
			font-weight: 400;
			line-height: 30px;
			cursor: pointer;
			color: rgb(59, 65, 75);
			font-family: "Microsoft YaHei";
			margin-right: 8px;
			border: 1px solid rgb(230, 231, 232);
		}
		.active {
			background-color: rgba(246, 250, 255, 1);
			border-color: rgb(5, 95, 194);
			color: rgb(5, 95, 194);
		}
	}
	.headerBtnBox {
		position: absolute;
		top: 14px;
		right: 12px;
		img {
			width: 28px;
			height: 28px;
			margin-right: 4px;
			cursor: pointer;
		}
	}
	.mainBox {
		width: 100%;
		height: 100%;
		padding-top: 42px;
		.graph {
			width: 100%;
			height: 100%;
		}
	}
}
</style>
