<template>
	<div class="view-box">
		<el-empty v-if="!listData?.length" style="height: 100%;" description="暂无数据" :image-size="100" />
		<div
			v-if="listData.length"
			class="main-content-main"
			@wheel.prevent="handleWheel"
			@mousedown="handleMouseDown"
			@mouseup="handleMouseUp"
			@mouseleave="handleMouseUp"
			@mousemove="handleMouseMove"
		>
			<div class="fishbone-container"
				:style="{ transform: `translate(${translateX}px, ${translateY}px) scale(${scale})` }"
			>
				<!-- 主轴上的标签 -->
				<div class="main-line" :style="{ width: listData.length * 200 + 300 + 'px' }">
					<div
						v-for="(item, index) in listData"
						:key="item.id"
						class="main-line-text"
						:class="getThemeClass(item.level)"
						:style="{ left: index * 200 + 220 + 'px' }"
					>
						{{ item.name }}
					</div>
				</div>
				<!-- 奇数索引的数据组放在上方 -->
				<div
					v-for="(causeGroup, groupIndex) in onFilterData(1)"
					:key="groupIndex"
					class="top-bone"
					:style="{ left: groupIndex * 400 + 510 + 'px', height: causeGroup.children?.length * 22 + 100 + 'px' }"
				>
					<div class="left-bone">
						<div
							class="bone-item-box bone-item-end bone-item-top"
							v-for="item in getLeftItems(causeGroup.children)"
							:key="item.id"
						>
							<div :class="['bone-item-word', { 'bone-item-back': item.back }]">
								<div class="bone-item-icon">
									<img :src="item.image || defaultIcon2" alt="" />
								</div>
								<div
									class="bone-item-text one-line-ellipsis"
									:style="{ color: item.isEntity == 1 ? '#ce4f51' : '#3b414b' }"
									:title="item.companyName"
								>
									{{ item.companyName }}
								</div>
							</div>
							<div class="bone-item-line"></div>
						</div>
					</div>
					<div class="right-bone">
						<div
							class="bone-item-box bone-item-start bone-item-top"
							v-for="item in getRightItems(causeGroup.children)"
							:key="item.id"
						>
							<div class="bone-item-line"></div>
							<div :class="['bone-item-word', { 'bone-item-back': item.back }]">
								<div class="bone-item-icon">
									<img :src="item.image || defaultIcon2" alt="" />
								</div>
								<div
									class="bone-item-text one-line-ellipsis"
									:style="{ color: item.isEntity == 1 ? '#ce4f51' : '#3b414b' }"
									:title="item.companyName"
								>
									{{ item.companyName }}
								</div>
							</div>
						</div>
					</div>
				</div>
				<!-- 偶数索引的数据组放在下方 -->
				<div
					v-for="(causeGroup, groupIndex) in onFilterData(0)"
					:key="groupIndex"
					class="bottom-bone"
					:style="{ left: groupIndex * 400 + 310 + 'px', height: causeGroup.children?.length * 22 + 100 + 'px' }"
				>
					<div class="left-bone">
						<div
							class="bone-item-box bone-item-end bone-item-down"
							v-for="item in getRightItems(causeGroup.children)"
							:key="item.id"
						>
							<div :class="['bone-item-word', { 'bone-item-back': item.back }]">
								<div class="bone-item-icon">
									<img :src="item.image || defaultIcon2" alt="" />
								</div>
								<div
									class="bone-item-text one-line-ellipsis"
									:style="{ color: item.isEntity == 1 ? '#ce4f51' : '#3b414b' }"
									:title="item.companyName"
								>
									{{ item.companyName }}
								</div>
							</div>
							<div class="bone-item-line"></div>
						</div>
					</div>
					<div class="right-bone">
						<div
							class="bone-item-box bone-item-start bone-item-down"
							v-for="item in getLeftItems(causeGroup.children)"
							:key="item.id"
						>
							<div class="bone-item-line"></div>
							<div :class="['bone-item-word', { 'bone-item-back': item.back }]">
								<div class="bone-item-icon">
									<img :src="item.image || defaultIcon2" alt="" />
								</div>
								<div
									class="bone-item-text one-line-ellipsis"
									:style="{ color: item.isEntity == 1 ? '#ce4f51' : '#3b414b' }"
									:title="item.companyName"
								>
									{{ item.companyName }}
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
		<div v-if="listData.length" class="main-content-footer">
			<div v-for="(item, index) in props.baseData" :key="index" class="footer-item">
				<div class="footer-item-bottom">
					<div class="icon">
						<img :src="noticeIcon" alt="" />
					</div>
					<div class="text">
						{{
							`中国企业${item.isChinaCount}家（${formatRate(item, "isChinaCount")}%），受制裁${
								item.sanCount
							}家（${formatRate(item, "sanCount")}%）`
						}}
					</div>
				</div>
				<div class="footer-item-top" :class="getThemeClass(item.name)">{{ item.name }}</div>
			</div>
		</div>
	</div>
</template>

<script setup name="ChartChain">
import { onBeforeUnmount, ref, watch } from "vue";
import defaultIcon2 from "@/assets/icons/default-icon2.png";
import noticeIcon from "../assets/images/notice-icon.png";

const props = defineProps({
	baseData: {
		type: Array,
		default: () => ([])
	},
	listData: {
		type: Array,
		default: () => ([])
	}
});

const getThemeClass = name => {
	if (name == "上游") return "blue-theme";
	if (name == "中游") return "green-theme";
	if (name == "下游") return "purple-theme";
};

// #region 缩放功能处理
const scale = ref(1);
const minScale = 0.1;
const maxScale = 10;
const handleWheel = e => {
	if (e.deltaY < 0) {
		// 放大：不超过最大值
		scale.value = Math.min(scale.value + 0.1, maxScale);
	} else {
		// 缩小：不低于最小值
		scale.value = Math.max(scale.value - 0.1, minScale);
	}
};
// #endregion 缩放功能处理

// #region 移动功能处理
const translateX = ref(0); // X轴位移
const translateY = ref(0); // Y轴位移
let isDragging = false;
let startX = 0;
let startY = 0;
const handleMouseMove = e => {
	if (!isDragging) return;
	translateX.value = e.clientX - startX;
	translateY.value = e.clientY - startY;
};
const handleMouseDown = e => {
	// 排除右键/中键，只响应左键（e.button=0为左键）
	if (e.button !== 0) return;
	isDragging = true;
	startX = e.clientX - translateX.value;
	startY = e.clientY - translateY.value;
};
const handleMouseUp = () => {
	isDragging = false;
};
// #endregion 移动功能处理

// 初始化布局
const watchInfo = watch(() => props.listData, val => {
	scale.value = 1;
	translateX.value = 0;
	translateY.value = 0;
})

onBeforeUnmount(() => { watchInfo() });

// 奇数索引的数据组放在上方, 偶数索引的数据组放在下方
const onFilterData = num => {
	return props.listData.filter((_, index) => index % 2 === num);
};
// 获取左侧显示的项目（前半部分）
const getLeftItems = items => {
	const midpoint = Math.ceil(items.length / 2);
	return items.slice(0, midpoint);
};
// 获取右侧显示的项目（后半部分）
const getRightItems = items => {
	const midpoint = Math.ceil(items.length / 2);
	return items.slice(midpoint);
};
// 格式化比率
const formatRate = (item, key) => {
	if (!item[key] || !item.total) return "0.00";
	return ((item[key] * 100) / item.total).toFixed(2);
};
</script>

<style scoped lang="scss">
.view-box {
	width: 100%;
	height: 100%;
	display: flex;
	flex-direction: column;

	.main-content-main {
		position: relative;
		height: 20px;
		flex: auto;
		display: flex;
		align-items: center;
		justify-content: center;
		overflow: hidden;
		-webkit-user-select: none; /* Safari/Chrome */
		-moz-user-select: none;    /* Firefox */
		-ms-user-select: none;     /* IE/Edge */
		user-select: none;         /* 标准语法 */

		.fishbone-container {
			position: relative;
			transform-origin: center center;

			.main-line {
				height: 3px;
				background: rgb(230, 231, 232);
				display: flex;
				justify-content: space-between;

				// 添加中间的文字块
				.main-line-text {
					top: -16px;
					position: absolute;
					font-size: 16px;
					font-weight: bold;
					padding: 0 10px;
					z-index: 2;
					// 箭头背景
					height: 32px;
					line-height: 32px;
					width: 160px;
					text-align: center;
					clip-path: polygon(0% 0%, 90% 0%, 100% 50%, 90% 100%, 0% 100%, 10% 50%);
				}
			}
		}

		.top-bone {
			position: absolute;
			bottom: 0px;
			width: 3px;
			background: rgb(230, 231, 232);
			transform-origin: bottom center;
			transform: skew(30deg);
			z-index: 1;

			.left-bone {
				color: #777;
				position: absolute;
				top: -20px;
				right: 0;
				width: 180px;
				height: 100%;
				display: flex;
				flex-direction: column;
				justify-content: flex-end;
			}

			.right-bone {
				color: #777;
				position: absolute;
				top: -44px;
				left: 0;
				width: 180px;
				height: 100%;
				display: flex;
				flex-direction: column;
				justify-content: flex-end;
			}
		}

		.bottom-bone {
			position: absolute;
			top: 0px;
			width: 3px;
			background: rgb(230, 231, 232);
			transform-origin: top center;
			transform: skew(-30deg);
			z-index: 1;

			.left-bone {
				color: #777;
				position: absolute;
				bottom: -44px;
				right: 0;
				width: 180px;
				height: 100%;
				display: flex;
				flex-direction: column;
				justify-content: flex-start;
			}

			.right-bone {
				color: #777;
				position: absolute;
				bottom: -20px;
				left: 0;
				width: 180px;
				height: 100%;
				display: flex;
				flex-direction: column;
				justify-content: flex-start;
			}
		}

		.bone-item-box {
			transform: skew(30deg);
			height: 40px;
			margin: 4px 0;
			display: flex;
			align-items: center;
			.bone-item-line {
				width: 30px;
				height: 2px;
				background: rgb(230, 231, 232);
			}
			.bone-item-word {
				display: flex;
				align-items: center;
				height: 30px;
				display: flex;
				align-items: center;
				gap: 8px;
				padding: 0 8px;
				.bone-item-icon {
					width: 16px;
					height: 16px;
					font-size: 0px;
					position: relative;
					&::after {
						content: "";
						position: absolute;
						top: 0px;
						left: 0px;
						width: 100%;
						height: 100%;
					}
					img {
						width: 100%;
						height: 100%;
						object-fit: contain;
					}
				}
				.bone-item-text {
					max-width: 100px;
					line-height: 14px;
					font-size: 14px;
				}
			}
		}
		.bone-item-back {
			background-color: #fff1f0;
			border: 1px solid var(--color-red-100);
			border-radius: 4px;
		}
		.bone-item-start {
			justify-content: flex-start;
		}
		.bone-item-end {
			justify-content: flex-end;
		}
		.bone-item-top {
			transform: skew(-30deg);
		}
		.bone-item-down {
			transform: skew(30deg);
		}
	}

	.main-content-footer {
		margin-top: 16px;
		display: flex;
		justify-content: space-between;

		.footer-item {
			flex: 1;
			display: flex;
			flex-direction: column;
			justify-content: flex-end;
		}

		.footer-item {
			.footer-item-top {
				height: 28px;
				text-align: center;
				line-height: 28px;
				font-family: Microsoft YaHei;
				font-size: 16px;
				font-weight: 700;
				margin-top: 10px;
				position: relative;
				z-index: 1;
			}
			.footer-item-bottom {
				display: flex;
				justify-content: center;
				align-items: center;

				.text {
					color: rgba(206, 79, 81, 1);
					font-size: 14px;
					line-height: 14px;
					margin-left: 6px;
				}
				.icon {
					width: 16px;
					height: 16px;
					font-size: 0;

					img {
						width: 100%;
						height: 100%;
					}
				}
			}
		}
	}

	.blue-theme {
		background: rgba(231, 243, 255, 1);
		color: rgba(22, 119, 255, 1);
	}
	.green-theme {
		background: rgba(225, 255, 251, 1);
		color: rgba(19, 168, 168, 1);
	}
	.purple-theme {
		background: rgba(246, 235, 255, 1);
		color: rgba(146, 84, 222, 1);
	}
}
</style>
