<template>
	<div class="deep-mining" :class="{ deepMiningChartmode: isInChart }">
		<div class="side-nav">
			<div
				v-for="(item, index) in activeTab"
				:key="index"
				class="tab-item"
				:class="{ active: index === activeIndex }"
				@click="activeIndex = index"
			>
				{{ item }}
				<span v-if="index === activeIndex" class="arrow"></span>
			</div>
		</div>
		<div class="main" v-if="activeIndex === 0">
			<div class="left">
				<div class="title-com">
					<div class="box"></div>
					<div class="text">本次制裁实体清单列表</div>
					<div class="right-group">
						<div class="btn">
							<img src="../../assets/数据库按钮.png" alt="" />
							<img src="../../assets/下载按钮.png" alt="" />
							<img src="../../assets/收藏按钮.png" alt="" />
						</div>
					</div>
				</div>
				<div class="left-main">
					<div class="filter-bar">
						<el-select v-model="searchDomain" placeholder="全部领域" class="domain-select">
							<el-option label="全部领域" value="" />
							<el-option label="人工智能" value="1" />
							<el-option label="生物科技" value="2" />
							<el-option label="新一代信息技术" value="3" />
							<el-option label="量子科技" value="4" />
							<el-option label="新能源" value="5" />
							<el-option label="集成电路" value="6" />
							<el-option label="海洋" value="7" />
							<el-option label="先进制造" value="8" />
							<el-option label="新材料" value="9" />
							<el-option label="航空航天" value="10" />
							<el-option label="深海" value="11" />
							<el-option label="极地" value="12" />
							<el-option label="太空" value="13" />
							<el-option label="核" value="14" />
						</el-select>
						<el-input v-model="searchText" placeholder="搜索实体" class="search-input">
							<template #suffix>
								<el-icon class="el-input__icon"><Search /></el-icon>
							</template>
						</el-input>
					</div>
					<div class="entity-tree custom-scrollbar">
						<div class="tree-group" v-for="group in entityList" :key="group.id">
							<div class="group-header" @click="toggleGroup(group)">
								<el-icon class="arrow-icon" :class="{ expanded: group.expanded }">
									<CaretRight />
								</el-icon>
								<span class="group-name">{{ group.name }}</span>
								<span class="group-count">{{ group.count }}家</span>
							</div>
							<div class="group-children custom-scrollbar" v-show="group.expanded">
								<div
									class="entity-item"
									v-for="item in group.children"
									:key="item.id"
									:class="{ active: activeEntityId === item.id }"
									@click="selectEntity(item)"
								>
									<div class="item-icon">
										<img :src="defaultTitle" alt="" class="item-img" />
									</div>
									<span class="item-name">{{ item.name }}</span>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="right" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
				<div class="title-com custom-right-header">
					<div class="toggle-group">
						<div
							class="toggle-btn"
							:class="{ active: rightActiveTab === 'supplyChain' }"
							@click="rightActiveTab = 'supplyChain'"
						>
							<img :src="rightActiveTab === 'supplyChain' ? icon01Active : icon01" alt="" />
							<span>供应链</span>
						</div>
						<div
							class="toggle-btn"
							:class="{ active: rightActiveTab === 'equity' }"
							@click="rightActiveTab = 'equity'"
						>
							<img :src="rightActiveTab === 'equity' ? icon02Active : icon02" alt="" />
							<span>股权</span>
						</div>
					</div>
					<div class="right-group">
						<div class="rule-checkbox" v-if="rightActiveTab === 'equity'">
							<el-checkbox v-model="is50PercentRule" size="large">50%规则涉及实体</el-checkbox>
						</div>
						<!-- <el-select v-model="filterType" placeholder="全部类型" class="header-select">
							<el-option label="全部类型" value="" />
						</el-select>
						<el-select v-model="filterDomain" placeholder="全部领域" class="header-select last-select">
							<el-option label="全部领域" value="" />
							<el-option label="人工智能" value="1" />
							<el-option label="生物科技" value="2" />
							<el-option label="新一代信息技术" value="3" />
							<el-option label="量子科技" value="4" />
							<el-option label="新能源" value="5" />
							<el-option label="集成电路" value="6" />
							<el-option label="海洋" value="7" />
							<el-option label="先进制造" value="8" />
							<el-option label="新材料" value="9" />
							<el-option label="航空航天" value="10" />
							<el-option label="深海" value="11" />
							<el-option label="极地" value="12" />
							<el-option label="太空" value="13" />
							<el-option label="核" value="14" />
						</el-select> -->
						<div class="btn">
							<img src="../../assets/数据库按钮.png" alt="" />
							<img src="../../assets/下载按钮.png" alt="" />
							<img src="../../assets/收藏按钮.png" alt="" />
						</div>
					</div>
				</div>
				<div class="right-echarts">
					<div class="chart-wrapper">
						<div class="chart-controls">
							<div
								class="control-btn"
								:class="{ controlBtnActive: controlActive === 1 }"
								@click="handleClickControlBtn(1)"
							>
								<img :src="echartsIcon01" />
							</div>
							<div
								class="control-btn"
								:class="{ controlBtnActive: controlActive === 2 }"
								@click="handleClickControlBtn(2)"
							>
								<img :src="echartsIcon02" />
							</div>
							<div
								class="control-btn"
								:class="{ controlBtnActive: controlActive === 3 }"
								@click="handleClickControlBtn(3)"
							>
								<img :src="echartsIcon03" />
							</div>
						</div>
						<div class="chart-legend">
							<div class="legend-item"><span class="dot blue"></span>已被制裁实体</div>
							<div class="legend-item"><span class="dot grey"></span>未被制裁实体</div>
						</div>
						<div ref="chartRef" id="chartbox" class="chart-container"></div>

						<div class="node-popup" v-if="selectedNode">
							<div class="popup-header">
								<img :src="defaultTitle" class="popup-icon" />
								<span class="popup-title">{{ selectedNode.name.replace(/\n/g, "") }}</span>
								<el-icon class="close-icon" @click="selectedNode = null"><Close /></el-icon>
							</div>
							<div class="popup-body">
								<div class="tag-row">
									<span class="red-dot"></span>
									<span class="red-text">
										<!-- 2025年7月15日 《实体清单》 -->
										暂无数据
									</span>
								</div>
								<div class="desc">
									<!-- 因获取和试图获取美国原产物品以支持中国军事和国防相关空间领域活动以及中国量子技术能力而被列入。 -->
									暂无数据
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup>
import { ref, onMounted, nextTick, watch, onUnmounted } from "vue";
import { debounce } from "lodash";
import * as echarts from "echarts";
import { Search, CaretRight, Close } from "@element-plus/icons-vue";
import defaultTitle from "../../assets/default-icon2.png";
import icon01 from "./assets/icon01.png";
import icon02 from "./assets/icon02.png";
import icon01Active from "./assets/icon01-active.png";
import icon02Active from "./assets/icon02-active.png";
import echartsIcon01 from "./assets/echartsIcon01.png";
import echartsIcon02 from "./assets/echartsIcon02.png";
import echartsIcon03 from "./assets/echartsIcon03.png";
import company from "./assets/company.png";
import companyActive from "./assets/company-active.png";
import {
	getSingleSanctionEntityList,
	getSingleSanctionEntitySupplyChain,
	getSingleSanctionEntityEquity
} from "@/api/exportControlV2.0";
import getTreeChart from "./utils/treeChart";
import setChart from "@/utils/setChart";

const controlActive = ref(1);

const treeData = ref([{}]);
const handleClickControlBtn = btn => {
	controlActive.value = btn;
	if (btn === 1 || btn === 3) {
		isInChart.value = true;
		initChart();
	} else if (btn === 2) {
		isInChart.value = false;
		if (chartInstance.value) {
			chartInstance.value.dispose();
		}
		console.log("treeData", treeData.value);

		let treeChart = getTreeChart(treeData.value);
		setChart(treeChart, "chartbox");
	}
};

const isInChart = ref(false);
const handleMouseEnter = () => {
	if (controlActive.value !== 2) {
		isInChart.value = true;
	} else {
		isInChart.value = false;
	}
};

const handleMouseLeave = () => {
	isInChart.value = false;
};

// 单次制裁-深度挖掘-制裁实体股权信息-列表
const singleSanctionEntityEquityData = ref(null);
// 单次制裁-深度挖掘-制裁实体股权信息-请求
const getSingleSanctionEntityEquityRequest = async () => {
	try {
		const res = await getSingleSanctionEntityEquity({
			orgId: activeEntityId.value,
			rule: is50PercentRule.value
		});
		if (res.code === 200) {
			singleSanctionEntityEquityData.value = res.data || null;
			initChart();
		}
	} catch (error) {
		console.log(error);
	}
};

// 单次制裁-深度挖掘-制裁实体供应链信息-列表
const singleSanctionEntitySupplyChainData = ref(null);
// 单次制裁-深度挖掘-制裁实体供应链信息-请求
const getSingleSanctionEntitySupplyChainRequest = async () => {
	try {
		const res = await getSingleSanctionEntitySupplyChain({
			orgId: activeEntityId.value
		});
		if (res.code === 200) {
			singleSanctionEntitySupplyChainData.value = res.data || null;
			initChart();

			treeData.value[0].id = res.data.orgId;
			treeData.value[0].name = res.data.orgName;
			treeData.value[0].symbol = "image://" + companyActive;
			treeData.value[0].symbolSize = 50;
			treeData.value[0].value = 10;
			treeData.value[0].children = res.data.parentOrgList.map(item => {
				return {
					id: item.id,
					name: item.name,
					symbolSize: 30,
					value: 10,
					symbol: `image://${company}`
				};
			});
			console.log("treeData0", treeData.value);
		}
	} catch (error) {
		console.log(error);
	}
};

// 单次制裁-深度挖掘-本次制裁实体清单列表
const singleSanctionEntityList = ref([]);
// 单次制裁-深度挖掘-本次制裁实体清单列表-请求
const getSingleSanctionEntityListRequest = async () => {
	try {
		const res = await getSingleSanctionEntityList({
			sanRecordId: sanRecordId.value,
			isOnlyCn: false,
			domainId: searchDomain.value || undefined,
			searchText: searchText.value || undefined
		});
		if (res.code === 200) {
			entityList.value = (res.data || []).map((group, index) => ({
				id: `group-${index}`,
				name: group.orgType,
				count: group.orgInfoList ? group.orgInfoList.length : 0,
				expanded: index === 0, // 默认展开第一个分组
				children: (group.orgInfoList || []).map(org => ({
					id: org.id,
					name: org.orgNameZh
				}))
			}));

			// 如果有数据，且当前没有选中的实体，默认选中第一个分组的第一个实体
			if (entityList.value.length > 0 && entityList.value[0].children && entityList.value[0].children.length > 0) {
				const firstEntity = entityList.value[0].children[0];
				if (!activeEntityId.value) {
					activeEntityId.value = firstEntity.id;
					currentEntityName.value = firstEntity.name;
				}
			}
		}
	} catch (error) {
		console.log(error);
	}
};

const sanRecordId = ref("");
const getUrlParams = () => {
	const urlParams = new URLSearchParams(window.location.search);
	sanRecordId.value = urlParams.get("id") || "";
};

// const activeTab = ref(["实体穿透分析", "重点实体识别"]);
const activeTab = ref(["实体穿透分析"]);
const activeIndex = ref(0);
const rightActiveTab = ref("supplyChain");

const searchDomain = ref("");
const searchText = ref("");
const filterType = ref("");
const filterDomain = ref("");
const activeEntityId = ref("");
const currentEntityName = ref("");
const is50PercentRule = ref(false);

const entityList = ref([]);

const toggleGroup = group => {
	group.expanded = !group.expanded;
};

const selectEntity = item => {
	activeEntityId.value = item.id;
	currentEntityName.value = item.name;
};

const chartRef = ref(null);
const chartInstance = ref(null);
const selectedNode = ref(null);

const initChart = () => {
	if (!chartRef.value) return;

	if (chartInstance.value) {
		chartInstance.value.dispose();
	}

	chartInstance.value = echarts.init(chartRef.value);

	let option = {};

	if (rightActiveTab.value === "supplyChain") {
		option = getSupplyChainOption();
	} else {
		option = getEquityOption();
	}

	chartInstance.value.setOption(option);

	chartInstance.value.on("click", params => {
		if (params.dataType === "node") {
			selectedNode.value = params.data;
		} else {
			selectedNode.value = null;
		}
	});

	chartInstance.value.getZr().on("click", params => {
		if (!params.target) {
			selectedNode.value = null;
		}
	});
};

const getSupplyChainOption = () => {
	if (!singleSanctionEntitySupplyChainData.value) return {};
	const data = singleSanctionEntitySupplyChainData.value;

	const nodes = [];
	const links = [];
	const centerX = 550;
	const centerY = 400;

	// 中心节点
	nodes.push({
		id: "0",
		name: data.orgName,
		category: 0, // 强制为制裁中
		symbol: "image://" + companyActive, // 强制使用制裁中图标
		x: centerX,
		y: centerY,
		symbolSize: 50,
		label: {
			fontSize: 16,
			fontWeight: "bold",
			color: "#055FC2", // 使用制裁蓝，在图标下方更清晰
			position: "bottom",
			distance: 10,
			width: 150,
			overflow: "break"
		}
	});

	// 父级节点 (供应商)
	const parentList = data.parentOrgList || [];
	parentList.forEach((item, index) => {
		// 使用 (index + 0.5) 使节点在半圆弧内居中分布
		const angle = -Math.PI + ((index + 0.5) / parentList.length) * Math.PI;
		// 交错半径：偶数索引使用 340，奇数索引使用 440，拉开垂直距离
		const radius = index % 2 === 0 ? 340 : 440;
		const x = centerX + radius * Math.cos(angle);
		const y = centerY + radius * Math.sin(angle);

		// 动态计算标签位置：根据余弦值判断左右，根据正弦值判断上下
		let position = "right";
		let align = "left";
		const cosA = Math.cos(angle);
		const sinA = Math.sin(angle);

		if (Math.abs(cosA) < 0.3) {
			// 顶部区域
			position = "top";
			align = "center";
		} else if (cosA < 0) {
			// 左侧区域
			position = "left";
			align = "right";
		}

		nodes.push({
			id: `p-${item.id}`,
			name: item.name,
			category: item.isSanctioned ? 0 : 1,
			symbol: "image://" + (item.isSanctioned ? companyActive : company),
			x: x,
			y: y,
			isSanctioned: item.isSanctioned,
			label: {
				position: position,
				align: align,
				distance: 8,
				width: 110,
				overflow: "break",
				lineHeight: 14,
				fontSize: 11
			}
		});

		links.push({
			source: `p-${item.id}`,
			target: "0",
			value: "供应商",
			isSanctioned: item.isSanctioned && data.isSanctioned
		});
	});

	// 子级节点 (客户)
	const childList = data.childrenOrgList || [];
	childList.forEach((item, index) => {
		const angle = ((index + 0.5) / childList.length) * Math.PI;
		// 交错半径
		const radius = index % 2 === 0 ? 340 : 440;
		const x = centerX + radius * Math.cos(angle);
		const y = centerY + radius * Math.sin(angle);

		// 动态计算标签位置
		let position = "right";
		let align = "left";
		const cosA = Math.cos(angle);
		const sinA = Math.sin(angle);

		if (Math.abs(cosA) < 0.3) {
			// 底部区域
			position = "bottom";
			align = "center";
		} else if (cosA < 0) {
			// 左侧区域
			position = "left";
			align = "right";
		}

		nodes.push({
			id: `c-${item.id}`,
			name: item.name,
			category: item.isSanctioned ? 0 : 1,
			symbol: "image://" + (item.isSanctioned ? companyActive : company),
			x: x,
			y: y,
			isSanctioned: item.isSanctioned,
			label: {
				position: position,
				align: align,
				distance: 8,
				width: 110,
				overflow: "break",
				lineHeight: 14,
				fontSize: 11
			}
		});

		links.push({
			source: "0",
			target: `c-${item.id}`,
			value: "客户",
			isSanctioned: item.isSanctioned && data.isSanctioned
		});
	});

	return {
		tooltip: {
			show: true,
			formatter: params => {
				if (params.dataType === "node") {
					return `<div style="padding: 8px; max-width: 300px; white-space: normal; word-break: break-all;">${params.data.name}</div>`;
				}
				return "";
			}
		},
		series: [
			{
				type: "graph",
				layout: "none",
				symbolSize: 36,
				roam: true,
				label: {
					show: true,
					formatter: "{b}",
					fontSize: 12,
					hideOverlap: true
				},
				edgeSymbol: ["none", "arrow"],
				edgeSymbolSize: [4, 8],
				edgeLabel: {
					position: "middle",
					offset: [0, 13],
					fontSize: 12,
					fontWeight: 400,
					fontFamily: "Microsoft YaHei",
					lineHeight: 16,
					show: true,
					formatter: "{c}",
					color: "rgba(170, 173, 177, 1)",
					backgroundColor: "rgba(234, 236, 238, 1)",
					padding: [4, 8],
					borderRadius: 20
				},
				data: nodes.map(node => ({
					...node,
					label: {
						color: node.category === 0 ? "#055FC2" : "#5F656C",
						...node.label
					}
				})),
				links: links.map(link => {
					return {
						...link,
						lineStyle: {
							color: link.isSanctioned ? "rgba(100, 180, 255, 1)" : "rgb(180, 181, 182)",
							width: 1,
							curveness: 0
						},
						label: link.isSanctioned
							? {
									show: true,
									formatter: "{c}",
									backgroundColor: "rgba(231, 243, 255, 1)",
									color: "rgba(50, 150, 250, 1)",
									borderRadius: 20,
									padding: [4, 8],
									fontSize: 12,
									fontWeight: 400,
									fontFamily: "Microsoft YaHei",
									lineHeight: 16
							  }
							: undefined
					};
				})
			}
		]
	};
};

const getEquityOption = () => {
	if (!singleSanctionEntityEquityData.value) return {};
	const data = singleSanctionEntityEquityData.value;

	const nodes = [];
	const links = [];
	const centerX = 550;
	const centerY = 400;

	// 中心节点
	nodes.push({
		id: "0",
		name: data.orgName,
		category: 0, // 强制为制裁中
		symbol: "image://" + companyActive, // 强制使用制裁中图标
		x: centerX,
		y: centerY,
		symbolSize: 50,
		label: {
			fontSize: 16,
			fontWeight: "bold",
			color: "#055FC2", // 使用制裁蓝，在图标下方更清晰
			position: "bottom",
			distance: 10,
			width: 150,
			overflow: "break"
		}
	});

	// 父级节点 (股东)
	const parentList = data.parentOrgList || [];
	parentList.forEach((item, index) => {
		// 在顶部水平排列
		const total = parentList.length;
		const gap = 200;
		const startX = centerX - ((total - 1) * gap) / 2;
		const x = startX + index * gap;
		const y = centerY - 250; // 向上偏移

		nodes.push({
			id: `p-${index}`,
			name: item.name,
			category: item.isSanctioned ? 0 : 1,
			symbol: "image://" + (item.isSanctioned ? companyActive : company),
			x: x,
			y: y,
			isSanctioned: item.isSanctioned,
			label: {
				position: "top",
				distance: 8,
				width: 110,
				overflow: "break",
				lineHeight: 14,
				fontSize: 11
			}
		});

		links.push({
			source: `p-${index}`,
			target: "0",
			value: item.type || "持股", // 使用 type 字段
			isSanctioned: item.isSanctioned // 中心节点强制制裁，高亮取决于对方
		});
	});

	// 子级节点 (对外投资)
	const childList = data.childrenOrgList || [];
	childList.forEach((item, index) => {
		// 在底部水平排列
		const total = childList.length;
		const gap = 240; // 稍微拉开一点间距
		const startX = centerX - ((total - 1) * gap) / 2;
		const x = startX + index * gap;
		const y = centerY + 250; // 向下偏移

		nodes.push({
			id: `c-${index}`,
			name: item.name,
			category: item.isSanctioned ? 0 : 1,
			symbol: "image://" + (item.isSanctioned ? companyActive : company),
			x: x,
			y: y,
			isSanctioned: item.isSanctioned,
			label: {
				position: "bottom",
				distance: 8,
				width: 110,
				overflow: "break",
				lineHeight: 14,
				fontSize: 11
			}
		});

		links.push({
			source: "0",
			target: `c-${index}`,
			value: item.type || "持股", // 使用 type 字段
			isSanctioned: item.isSanctioned // 中心节点强制制裁，高亮取决于对方
		});
	});

	return {
		tooltip: {
			show: true,
			formatter: params => {
				if (params.dataType === "node") {
					return `<div style="padding: 8px; max-width: 300px; white-space: normal; word-break: break-all;">${params.data.name}</div>`;
				}
				return "";
			}
		},
		series: [
			{
				type: "graph",
				layout: "none",
				symbolSize: 36,
				roam: true,
				label: {
					show: true,
					formatter: "{b}",
					fontSize: 12,
					hideOverlap: true
				},
				edgeSymbol: ["none", "arrow"],
				edgeSymbolSize: [4, 8],
				edgeLabel: {
					position: "middle",
					offset: [0, 13],
					fontSize: 12,
					fontWeight: 400,
					fontFamily: "Microsoft YaHei",
					lineHeight: 16,
					show: true,
					formatter: "{c}",
					color: "rgba(170, 173, 177, 1)",
					backgroundColor: "rgba(234, 236, 238, 1)",
					padding: [4, 8],
					borderRadius: 20
				},
				data: nodes.map(node => ({
					...node,
					label: {
						color: node.category === 0 ? "#055FC2" : "#5F656C",
						...node.label
					}
				})),
				links: links.map(link => {
					return {
						...link,
						lineStyle: {
							color: link.isSanctioned ? "rgba(100, 180, 255, 1)" : "rgb(180, 181, 182)",
							width: 1,
							curveness: 0
						},
						label: link.isSanctioned
							? {
									show: true,
									formatter: "{c}",
									backgroundColor: "rgba(231, 243, 255, 1)",
									color: "rgba(50, 150, 250, 1)",
									borderRadius: 20,
									padding: [4, 8],
									fontSize: 12,
									fontWeight: 400,
									fontFamily: "Microsoft YaHei",
									lineHeight: 16
							  }
							: undefined
					};
				})
			}
		]
	};
};

const debouncedGetList = debounce(() => {
	getSingleSanctionEntityListRequest();
}, 1000);

watch(searchText, () => {
	debouncedGetList();
});

watch(searchDomain, () => {
	getSingleSanctionEntityListRequest();
});

watch(activeIndex, val => {
	if (val === 0) {
		nextTick(() => {
			if (activeEntityId.value) {
				if (rightActiveTab.value === "supplyChain") {
					getSingleSanctionEntitySupplyChainRequest();
				} else {
					getSingleSanctionEntityEquityRequest();
				}
			}
			initChart();
		});
	}
});

watch(activeEntityId, val => {
	if (val) {
		if (rightActiveTab.value === "supplyChain") {
			getSingleSanctionEntitySupplyChainRequest();
		} else {
			getSingleSanctionEntityEquityRequest();
		}
		initChart();
	}
});

watch(is50PercentRule, () => {
	if (rightActiveTab.value === "equity" && activeEntityId.value) {
		getSingleSanctionEntityEquityRequest();
	}
});

watch(
	rightActiveTab,
	val => {
		if (activeEntityId.value) {
			if (val === "supplyChain") {
				getSingleSanctionEntitySupplyChainRequest();
			} else {
				getSingleSanctionEntityEquityRequest();
			}
		}
		nextTick(() => {
			initChart();
		});
	},
	{ immediate: true }
);

onMounted(() => {
	// 获取URL参数
	getUrlParams();
	// 单次制裁-深度挖掘-本次制裁实体清单列表-请求
	getSingleSanctionEntityListRequest();

	window.addEventListener("resize", handleResize);
});

onUnmounted(() => {
	if (chartInstance.value) {
		chartInstance.value.dispose();
	}
	if (debouncedGetList && debouncedGetList.cancel) {
		debouncedGetList.cancel();
	}
	window.removeEventListener("resize", handleResize);
});

const handleResize = () => {
	if (chartInstance.value) {
		chartInstance.value.resize();
	}
};
</script>

<style scoped lang="scss">
* {
	margin: 0;
	padding: 0;
}
.deepMiningChartmode {
	height: calc(100vh - 220px) !important;
	// overflow: hidden;
}
.deep-mining {
	overflow: hidden;
	width: 1601px;
	margin: 0 auto;
	position: relative;
	// min-height: 800px;
	.side-nav {
		position: absolute;
		top: 27px;
		right: 100%;
		margin-right: 12px;
		display: flex;
		flex-direction: column;
		gap: 16px;
		.tab-item {
			cursor: pointer;
			padding: 4px 20px;
			border-radius: 22px;
			font-size: 16px;
			font-weight: 400;
			font-family: "Microsoft YaHei";
			line-height: 24px;
			color: rgb(95, 101, 108);
			white-space: nowrap;
			display: flex;
			align-items: center;

			&.active {
				background-color: rgb(5, 95, 194);
				color: #fff;

				.arrow {
					display: inline-block;
					width: 0;
					height: 0;
					border-top: 5px solid transparent;
					border-bottom: 5px solid transparent;
					border-left: 6px solid #fff;
					margin-left: 8px;
				}
			}
		}
	}
	.main {
		width: 100%;
		padding-top: 16px;
		padding-bottom: 50px;
		display: flex;
		justify-content: space-between;
		.left {
			width: 480px;
			height: 828px;
			background-color: #fff;
			box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
			border-radius: 10px;
			.left-main {
				padding: 0 17px 14px 17px;
				height: calc(100% - 56px);
				display: flex;
				flex-direction: column;
				box-sizing: border-box;

				.filter-bar {
					display: flex;
					gap: 12px;
					margin-bottom: 16px;

					.domain-select {
						width: 140px;
					}
					.search-input {
						flex: 1;
					}
				}

				.entity-tree {
					flex: 1;
					overflow-y: auto;
					padding-right: 4px;

					.tree-group {
						// margin-bottom: 16px;
						border: 1px solid rgb(234, 236, 238);
						border-radius: 4px;
						overflow: hidden;

						.group-header {
							height: 48px;
							padding: 0 12px;
							display: flex;
							align-items: center;
							cursor: pointer;
							user-select: none;
							background-color: #fff;
							border-bottom: 1px solid rgb(234, 236, 238);

							&:hover {
								background-color: #f2f3f5;
							}

							.arrow-icon {
								margin-right: 8px;
								font-size: 14px;
								color: #86909c;
								transition: transform 0.3s;

								&.expanded {
									transform: rotate(90deg);
								}
							}

							.group-name {
								flex: 1;
								font-size: 14px;
								font-weight: 700;
								color: #1d2129;
								font-family: "Microsoft YaHei";
							}

							.group-count {
								font-size: 14px;
								color: #4e5969;
							}
						}

						.group-children {
							.entity-item {
								display: flex;
								align-items: center;
								height: 48px;
								padding: 0 12px 0 29px;
								cursor: pointer;
								margin-bottom: 0;
								transition: all 0.2s;
								box-sizing: border-box;

								&:hover {
									background-color: #f7f8fa;
								}

								&.active {
									background-color: rgba(5, 95, 194, 0.05);
									border-top: 1px solid rgba(174, 214, 255, 1);
									border-bottom: 1px solid rgba(174, 214, 255, 1);

									.item-name {
										color: rgb(5, 95, 194);
										font-weight: 700;
									}
								}

								.item-icon {
									margin-right: 10px;
									display: flex;
									align-items: center;
									flex-shrink: 0;

									.item-img {
										width: 24px;
										height: 24px;
										object-fit: contain;
									}
								}

								.item-name {
									font-size: 16px;
									color: rgb(59, 65, 75);
									font-weight: 400;
									font-family: "Microsoft YaHei";
									line-height: 24px;
									word-break: break-all;
								}
							}
						}
					}
				}
			}
		}
		.right {
			width: 1105px;
			height: 828px;
			background-color: #fff;
			box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
			border-radius: 10px;
			.right-echarts {
				width: 100%;
				height: calc(100% - 56px);
				position: relative;

				.chart-wrapper {
					width: 100%;
					height: 100%;
					position: relative;
				}

				.chart-container {
					width: 100%;
					height: 100%;
				}

				.chart-controls {
					position: absolute;
					top: 0px;
					left: 16px;
					display: flex;
					align-items: center;
					justify-content: space-between;
					z-index: 10;
					width: 96px;
					height: 32px;
					padding: 8px 10px;
					background: #fff;
					border-radius: 4px;
					box-shadow: 0 0px 8px rgba(0, 0, 0, 0.1);

					.control-btn {
						width: 24px;
						height: 24px;
						box-sizing: border-box;
						padding: 5px;
						cursor: pointer;
						&:hover {
							background: var(--color-bg-hover);
						}

						img {
							width: 14px;
							height: 14px;
						}
					}
					.controlBtnActive {
						background: var(--color-bg-hover);
					}
				}

				.chart-legend {
					position: absolute;
					top: 4px;
					right: 23px;
					display: flex;
					gap: 20px;
					z-index: 10;

					.legend-item {
						display: flex;
						align-items: center;
						font-size: 16px;
						font-weight: 400;
						font-family: "Microsoft YaHei";
						line-height: 24px;
						color: #5f656c;

						&:first-child {
							color: #055fc2;
						}

						.dot {
							width: 12px;
							height: 12px;
							border-radius: 50%;
							margin-right: 8px;

							&.blue {
								background: #055fc2;
							}

							&.grey {
								background: rgb(95, 101, 108);
							}
						}
					}
				}

				.node-popup {
					position: absolute;
					right: 20px;
					top: 200px;
					width: 320px;
					background: #fff;
					border-radius: 10px;
					box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
					padding: 16px;
					z-index: 20;

					.popup-header {
						display: flex;
						align-items: center;
						margin-bottom: 12px;
						padding-bottom: 12px;
						border-bottom: 1px solid rgb(234, 236, 238);
						position: relative;

						.popup-icon {
							width: 24px;
							height: 24px;
							margin-right: 8px;
						}

						.popup-title {
							font-size: 16px;
							font-weight: 700;
							font-family: "Microsoft YaHei";
							color: rgb(59, 65, 75);
							padding-right: 20px;
						}

						.close-icon {
							cursor: pointer;
							font-size: 16px;
							color: #86909c;
							position: absolute;
							right: 0;
							top: 0;
						}
					}

					.popup-body {
						.tag-row {
							display: flex;
							align-items: center;
							margin-bottom: 8px;

							.red-dot {
								width: 8px;
								height: 8px;
								background: rgb(206, 79, 81);
								border-radius: 50%;
								margin-right: 23px;
							}

							.red-text {
								color: rgb(206, 79, 81);
								font-size: 16px;
								font-weight: 400;
								font-family: "Microsoft YaHei";
							}
						}

						.desc {
							padding-left: 31px;
							font-size: 16px;
							font-weight: 400;
							font-family: "Microsoft YaHei";
							color: rgb(95, 101, 108);
							line-height: 24px;
							text-align: justify;
						}
					}
				}
			}
		}
	}
}

.title-com {
	width: 100%;
	height: 56px;
	display: flex;
	align-items: center;
	padding: 14px 12px 16px 0;
	.box {
		width: 8px;
		height: 20px;
		background-color: rgb(5, 95, 194);
		border-bottom-right-radius: 4px;
		border-top-right-radius: 4px;
		margin-right: 14px;
	}
	.text {
		font-size: 20px;
		font-weight: 700;
		font-family: "Microsoft YaHei";
		line-height: 26px;
		color: rgb(5, 95, 194);
	}
	.right-group {
		margin-left: auto;
		display: flex;
		align-items: center;

		.rule-checkbox {
			margin-right: 20px;

			:deep(.el-checkbox__label) {
				font-size: 16px;
				color: #5f656c;
				font-family: "Microsoft YaHei";
			}

			:deep(.el-checkbox__inner) {
				border-color: #c9cdd4;
			}

			:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
				background-color: #055fc2;
				border-color: #055fc2;
			}

			:deep(.el-checkbox__input.is-checked + .el-checkbox__label) {
				color: #5f656c;
			}
		}

		.toggle-btns {
			display: flex;
			gap: 8px;
			margin-right: 20px;
			.t-btn {
				height: 28px;
				padding: 1px 8px;
				border: 1px solid transparent;
				border-radius: 4px;
				font-size: 16px;
				font-weight: 400;
				line-height: 24px;
				font-family: "Microsoft YaHei";
				color: rgb(59, 65, 75);
				cursor: pointer;
				box-sizing: border-box;
				border: 1px solid rgb(230, 231, 232);
				&.active {
					color: rgb(5, 95, 194);
					background-color: rgba(246, 250, 255, 1);
					border-color: rgb(5, 95, 194);
				}
			}
		}
		.btn {
			margin-left: 0;
		}
		.time-select {
			width: 120px;
			height: 28px;
			margin-right: 14px;
			:deep(.el-input__wrapper) {
				height: 28px;
				min-height: 28px;
				padding: 0 8px;
				box-shadow: 0 0 0 1px #dcdfe6 inset;
			}
			:deep(.el-input__inner) {
				height: 28px;
				line-height: 28px;
				font-size: 14px;
			}
		}
	}
	.btn {
		width: 92px;
		height: 28px;
		margin-left: auto;
		img {
			width: 28px;
			height: 28px;
			cursor: pointer;
		}
		img:first-child {
			margin-right: 4px;
		}
	}
}

.custom-scrollbar::-webkit-scrollbar {
	width: 6px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
	background: #dcdfe6;
	border-radius: 3px;
}
.custom-scrollbar::-webkit-scrollbar-track {
	background: transparent;
}

.title-com.custom-right-header {
	.box,
	.text {
		display: none;
	}

	.toggle-group {
		display: flex;
		background: #fff;
		border: 1px solid #055fc2;
		border-radius: 20px;
		height: 32px;
		overflow: hidden;
		margin-left: 16px;

		.toggle-btn {
			height: 100%;
			padding: 4px 16px;
			display: flex;
			align-items: center;
			cursor: pointer;
			transition: all 0.3s;
			font-size: 18px;
			color: rgb(5, 95, 194);
			background: #fff;
			font-weight: 400;
			font-family: "Microsoft YaHei";
			line-height: 24px;
			img {
				width: 14px;
				height: 14px;
				margin-right: 8px;
			}

			&.active {
				background: rgb(5, 95, 194);
				color: #fff;
			}
		}
	}

	.right-group {
		.header-select {
			width: 120px;
			height: 32px;
			margin-right: 12px;

			&.last-select {
				margin-right: 19px;
			}

			:deep(.el-input__wrapper) {
				height: 32px;
				min-height: 32px;
				box-shadow: 0 0 0 1px #dcdfe6 inset;
				padding: 0 11px;
			}

			:deep(.el-input__inner) {
				height: 32px;
				line-height: 32px;
			}
		}
	}
}
</style>
