<template>
	<div class="wrapper">
		<div class="box1">
			<AnalysisBox title="受影响实体" :showAllBtn="false">
				<div class="box1-main">
					<div class="data-filter">
						<div class="filter-select">
							<el-select v-model="areaInfo.id" :empty-values="[null, undefined]" @change="onDecreeEntities()" style="width:100%">
								<el-option label="全部领域" value="" />
								<el-option v-for="item in areaInfo.list" :key="item.id" :label="item.name" :value="item.id" />
							</el-select>
						</div>
						<div class="filter-input">
							<el-input v-model="entityInfo.keyword" @keyup.enter="onDecreeEntities()" :suffix-icon="Search" placeholder="搜索实体" />
						</div>
					</div>
					<div class="data-title">实体名称</div>
					<div style="height: 20px; flex: auto;">
						<el-empty v-if="!entityInfo.list?.length" style="padding: 60px 0;" description="暂无数据" :image-size="100" />
						<el-scrollbar height="100%" always>
							<div class="list-data">
								<div class="list-item" v-for="item in entityInfo.list" :key="item.id" :class="{ 'item-active': entityInfo.id==item.id }" @click="headerChartData(item)">
									<div class="item-icon">
										<img :src="defaultIcon2" alt="" class="item-img" />
									</div>
									<div class="item-name one-line-ellipsis">{{ item.companyName }}</div>
									<div class="item-icon item-icon-tag">
										<img :src="noticeIcon" alt="" class="item-img" />
									</div>
									<div class="item-tag">提及</div>
								</div>
							</div>
						</el-scrollbar>
					</div>
					<div class="pagination-info">
						<div class="pagination-left">{{ `共 ${entityInfo.total} 家企业` }}</div>
						<div class="pagination-right">
							<el-pagination
								@current-change="onDecreeEntities"
								:pageSize="entityInfo.pageSize"
								:current-page="entityInfo.pageNum"
								background
								layout="prev, pager, next"
								size="small"
								:total="entityInfo.total"
							/>
						</div>
					</div>
				</div>
			</AnalysisBox>
		</div>
		<div class="box2">
			<AnalysisBox :showAllBtn="false">
				<template #custom-title>
					<div class="custom-title">
						<div class="title-left">
							<div :class="['title-item', {'title-active': contentType==1}]" @click="headerContentType(1)">
								<div class="title-icon">
									<img :src="contentType==1 ? icon1620 : icon1621" alt="">
								</div>
								<div>产业链</div>
							</div>
							<div :class="['title-item', {'title-active': contentType==2}]" @click="headerContentType(2)">
								<div class="title-icon">
									<img :src="contentType==2 ? icon422 : icon423" alt="">
								</div>
								<div>实体关系</div>
							</div>
						</div>
						<div class="title-right" v-if="contentType==1">
							<el-select v-model="industryChain.id" style="width: 100%" @change="onDecreeChainNodes">
								<el-option v-for="item in industryChain.list" :key="item.id" :label="item.name" :value="item.id" />
							</el-select>
						</div>
					</div>
				</template>
				<div class="box2-main">
					<AiTips :tips="tips" />
					<div class="graph-box" v-if="contentType==1">
						<ChartChain :listData="fishbone.list" :baseData="fishbone.base" />
					</div>
					<div class="graph-box" v-if="contentType==2 && graphInfo.nodes.length">
						<GraphChart :nodes="graphInfo.nodes" :links="graphInfo.links" layoutType="force" />
					</div>
				</div>
			</AnalysisBox>
		</div>
	</div>
</template>

<script setup>
import { ref, onMounted, reactive } from "vue";
import { useRoute } from "vue-router";
import { Search } from '@element-plus/icons-vue'
import {
	getDecreehylyList,
	getDecreeEntities,
	getDecreeRelatedChain,
	getDecreeChainNodes,
	getDecreeRelatedEntitie
} from "@/api/decree/influence";
import ChartChain from "./com/ChartChain.vue";
import AiTips from "./com/AiTips.vue";
import GraphChart from "@/components/base/GraphChart/index.vue";
import defaultIcon2 from "@/assets/icons/default-icon2.png";
import noticeIcon from "./assets/images/notice-icon.png";
import icon422 from "./assets/images/icon422.png";
import icon423 from "./assets/images/icon423.png";
import icon1620 from "./assets/images/icon1620.png";
import icon1621 from "./assets/images/icon1621.png";
import company from "./assets/images/company.png";

const route = useRoute();

const tips = "这项政令标志着中美AI竞争进入一个新阶段，其核心特征是 “精准封锁”与“体系输出”相结合。它短期内无疑会给中国AI产业链带来压力，但长期看，这场竞争更可能是一场围绕技术路线、生态系统和治理规则的持久战。"

// 行业领域
const areaInfo = reactive({
	list: [],
	id: "",
})
const handleGetHylyList = async () => {
	try {
		const res = await getDecreehylyList();
		console.log("行业领域:", res);
		if (res.code === 200) {
			areaInfo.list = res.data || [];
		}
	} catch (error) {
		areaInfo.list = [];
	}
};

// 受影响实体
const entityInfo = reactive({
	keyword: "",
	pageSize: 10,
	pageNum: 1,
	total: 0,
	list: [],
	id: '',
	node: {id: '', companyName: ''},
})
const onDecreeEntities = async (page=1) => {
	entityInfo.pageNum = page;
	try {
		let params = {
			id: route.query.id,
			pageSize: entityInfo.pageSize,
			pageNum: entityInfo.pageNum - 1,
			keyword: entityInfo.keyword,
			domainId: areaInfo.id || undefined
		}
		const res = await getDecreeEntities(params);
		console.log("受影响实体:", res);
		if (res.code === 200) {
			entityInfo.list = res.data.companyInfos;
			entityInfo.total = res.data.total;
			if (entityInfo.total && entityInfo.list.every(item => item.id!=entityInfo.id)) {
				headerChartData(entityInfo.list[0])
			}
		}
	} catch (error) {
		console.log("获取受影响实体失败", error);
	}
};

const contentType = ref(1);
const headerContentType = (type) => {
	contentType.value = type;
	headerChartData(entityInfo.node)
};
const headerChartData = (row) => {
	entityInfo.id = row.id;
	entityInfo.node = row;

	industryChain.id = "";
	fishbone.list = []
	fishbone.base = []

	graphInfo.nodes = [];
	graphInfo.links = [];

	switch (contentType.value) {
		case 1:
			onDecreeRelatedChain(row.id)
		break;
		case 2:
			onDecreeRelatedEntitie(row.id)
		break;
	}
}

// 产业链
const industryChain = reactive({
	list: [],
	id: "",
})
const onDecreeRelatedChain = async (id) => {
	try {
		const res = await getDecreeRelatedChain({ id });
		console.log("产业链:", res);
		if (res.code === 200) {
			industryChain.list = res.data;
			if (industryChain.list.length) onDecreeChainNodes(industryChain.list[0].id)
		}
	} catch (error) {
		console.log("获取产业链失败", error);
	}
};

// 产业链鱼骨图
const fishbone = reactive({
	list: [],
	base: [],
})
const onDecreeChainNodes = async (id) => {
	industryChain.id = id;
	try {
		const res = await getDecreeChainNodes({ id });
		console.log("产业链鱼骨图:", res);
		if (res.code === 200) {
			let obj = res.data.chains.reduce((result, item) => {
				result['chain-'+item.id] = {...item, children: []};
				return result;
			}, {});
			res.data.children.forEach(item => {
				if (item.companyId== entityInfo.id) {
					obj['chain-'+item.chainId].children.push({ ...item, back:true})
				} else if (obj['chain-'+item.chainId]?.children?.length < 10) {
					obj['chain-'+item.chainId].children.push(item)
				}
			})
			fishbone.list = Object.values(obj);
			console.log("fishbone.list:", fishbone.list);
			fishbone.base = res.data.levelInfos.map((item, index) => {
				return {...item, name: ['上游', '中游', '下游'][index]}
			});
		}
	} catch (error) {
		console.log("获取产业链鱼骨图失败", error);
	}
};

// 实体关系
const graphInfo = reactive({
  nodes: [],
  links: [],
});
const onDecreeRelatedEntitie = async (id) => {
	try {
		const res = await getDecreeRelatedEntitie({ id });
		console.log("实体关系:", res);
		if (res.code === 200) {
			graphInfo.links = res.data.map(onFormatLink)
			graphInfo.nodes = res.data.map(onFormatNode)
			graphInfo.nodes.unshift(onFormatNode(entityInfo.node))
		}
	} catch (error) {
		console.log("获取实体关系失败", error);
	}
}
const onFormatLink = (item, index) => {
	return {
		id: `link-${index+1}`,
		source: item.id+'', target: entityInfo.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 == entityInfo.id;
	return {
		id: item.id+'',
		name: onWordWrap(item.companyName, 7),
		label: {
			show: true,
			color: "#3b414b",
			fontSize: leader ? 18 : 14,
			fontWeight: leader ? 700 : 400,
			fontFamily: 'Source Han Sans CN',
		},
		symbolSize: 40,
		symbol: `image://${company}`
	}
}
// 文本插入换行符
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;
}

onMounted(() => {
	onDecreeEntities();
	handleGetHylyList();
});
</script>

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

	.box1 {
		width: 480px;

		.box1-main {
			height: 100%;
			padding: 10px 16px;
			display: flex;
			flex-direction: column;

			.data-filter {
				display: flex;
				align-items: center;
				gap: 16px;
				margin-bottom: 10px;

				.filter-select {
					width: 150px;
				}
				.filter-input {
					width: 20px;
					flex: auto;
					background-color: var(--el-fill-color-blank);
					border-radius: var(--el-border-radius-base);
					box-shadow: 0 0 0 1px var(--el-border-color) inset;
					box-sizing: border-box;
					height: 32px;

					:deep(.el-input) {
						height: 100%;
						width: 100%;
					}
				}
			}

			.data-title {
				border-top: 1px solid rgba(240, 242, 244, 1);
				padding: 12px;
				font-weight: bold;
			}

			.list-data {
				width: 446px;

				.list-item {
					display: flex;
					align-items: center;
					border: 1px solid transparent;
					border-bottom: 1px solid rgba(240, 242, 244, 1);
					padding: 12px;
					cursor: pointer;
					&:first-child {
						border-top: 1px solid rgba(240, 242, 244, 1);
					}
					&:hover {
						background-color: #f7f8fa;
					}

					.item-icon {
						width: 24px;
						height: 24px;
						font-size: 0px;

						.item-img {
							width: 100%;
							height: 100%;
							object-fit: contain;
						}
					}

					.item-icon-tag {
						width: 20px;
						height: 20px;
					}

					.item-tag {
						color: rgb(206, 79, 81);
						font-size: 14px;
						line-height: 14px;
					}

					.item-name {
						width: 20px;
						flex: auto;
						padding: 0 10px;
						font-size: 16px;
						color: rgb(59, 65, 75);
						font-weight: 400;
						font-family: "Microsoft YaHei";
					}
				}

				.list-item.item-active {
					background-color: rgba(5, 95, 194, 0.05);
					border-color: rgba(174, 214, 255, 1);

					.item-name {
						color: rgb(5, 95, 194);
						font-weight: bold;
					}
				}
			}
			.pagination-info {
				height: 65px;
				width: 446px;
				margin: 0 auto;
				display: flex;
				justify-content: space-between;
				box-sizing: border-box;
				.pagination-left {
					margin-top: 25px;
					height: 18px;
					color: rgba(95, 101, 108, 1);
					font-family: Microsoft YaHei;
					font-size: 14px;
					font-weight: 400;
					line-height: 18px;
				}
				.pagination-right {
					margin-top: 23px;
				}
			}
		}
	}
	
	.box2 {
		width: 20px;
		flex: auto;
		:deep(.header-icon) {
			display: none;
		}
		.custom-title {
			display: flex;
			justify-content: space-between;
			align-items: flex-end;
			width: 100%;
			height: 100%;
			padding: 0 20px;
			.title-left {
				display: flex;
				border: 1px solid rgb(5, 95, 194);
				color: rgb(5, 95, 194);
				border-radius: 16px;
				width: 240px;
				height: 32px;
				overflow: hidden;
				cursor: pointer;
				.title-item {
					display: flex;
					align-items: center;
					justify-content: center;
					gap: 6px;
					width: 50%;
					font-size: 16px;
					line-height: 16px;
					font-family: "Microsoft YaHei";
					.title-icon {
						width: 14px;
						height: 14px;
						font-size: 0;
						img {
							width: 100%;
							height: 100%;
						}
					}
				}
				.title-active {
					background-color: rgb(5, 95, 194);
					color: white;
				}
			}
			.title-right {
				width: 180px;
			}
		}
		.box2-main {
			width: 100%;
			height: 100%;
			display: flex;
			flex-direction: column;
			padding: 16px 20px;
			.graph-box {
				height: 20px;
				flex: auto;
				margin-top: 16px;
			}
		}
	}
}
</style>