<script setup>
import { nextTick, onMounted, ref, toRefs, watch } from "vue";

const props = defineProps({
	value: {
		type: Boolean,
		default: false,
	},
	isThumb: {
		type: Boolean,
		default: false,
	},
	list: {
		type: Array,
		default: () => [],
	},
	initialIndex: {
		type: Number,
		default: 0,
	},
	clickHide: {
		type: Boolean,
		default: true,
	},
});

const isShow = ref(false);
const { value, initialIndex } = toRefs(props);
isShow.value = value.value;
const pIndex = ref(0);
pIndex.value = initialIndex.value;
let elWidth = 0; // 预览图片宽度
let elHeight = 0; // 预览图片高度
let elPosition = { x: 0, y: 0 }; // 预览图片当前的位置
let elScale = { x: 1, y: 1 }; // 预览图片的缩放旋转
let elRotate = 0;
let screenWidth = 0; // 显示区域宽度
let screenHeight = 0; // 显示区域高度
const tempMove = { x: 0, y: 0 };
let isDrag = false;

watch(
	() => props.value,
	() => {
		isShow.value = props.value;
		if (isShow.value) {
			nextTick(() => {
				initialPreview();
			});
		}
	},
);

const emit = defineEmits(["update:value"]);
watch(isShow, () => {
	emit("update:value", isShow.value);
});

watch(
	() => props.initialIndex,
	() => {
		pIndex.value = props.initialIndex;
	},
);

watch(pIndex, () => {
	if (props.isThumb) {
		nextTick(() => {
			const prevThumbBox = HbPrevThumbBox.value;
			if (prevThumbBox) {
				prevThumbBox.scrollLeft = (pIndex.value - 1) * 100;
			}
		});
	}
});

function getElementPos(el) {
	const pos = [parseInt(el.style.left + 0), parseInt(el.style.top + 0)];
	return { x: pos[0], y: pos[1] };
}

function initialImage(el, type = "fit") {
	const image = new Image();
	image.src = props.list[pIndex.value];
	if (image.complete) {
		setImage(image, el, type);
	} else {
		image.onload = () => {
			setImage(image, el, type);
		};
	}
}

function setImage(image, el, type) {
	const imgWidth = image.naturalWidth;
	const imgHeight = image.naturalHeight;
	const imgRatio = imgWidth / imgHeight;
	if (type === "fit") {
		elWidth = Math.ceil((screenHeight * imgRatio) / 2);
		elHeight = Math.ceil(screenHeight / 2);
	} else if (type === "original") {
		elWidth = imgWidth;
		elHeight = imgHeight;
	}
	// 设置预览图的初始宽高度
	el.style.width = elWidth + "px";
	el.style.height = elHeight + "px";
	// 设置预览图的初始位置
	el.style.left = Math.ceil((screenWidth - elWidth) / 2) + "px";
	el.style.top = Math.ceil((screenHeight - elHeight) / 2) + "px";

	elScale = { x: 1, y: 1 };
	elRotate = 0;
	el.style.transform = "scale(1) rotate(0deg)";
}

function initialPreview() {
	if (props.list.length > 0) {
		const prevImg = HbPrevImg.value;
		if (prevImg) {
			screenWidth = prevImg.parentNode.offsetWidth;
			screenHeight = prevImg.parentNode.offsetHeight;
			initialImage(prevImg);

			if (props.isThumb) {
				const prevThumb = HbPrevThumb.value;
				prevThumb.style.width = props.list.length * 100 + "px";
			}

			prevImg.addEventListener("mousedown", (e) => {
				e.preventDefault();
				elPosition = getElementPos(prevImg);
				tempMove.x = e.clientX;
				tempMove.y = e.clientY;
				isDrag = true;
			});
			prevImg.addEventListener("mousemove", (e) => {
				e.preventDefault();
				if (isDrag) {
					document.body.style.cursor = "move";
					const left = elPosition.x + e.clientX - tempMove.x;
					const top = elPosition.y + e.clientY - tempMove.y;

					prevImg.style.transition = "none";
					prevImg.style.left = left + "px";
					prevImg.style.top = top + "px";

					tempMove.x = e.clientX;
					tempMove.y = e.clientY;
					elPosition = getElementPos(prevImg);
				}
			});
			prevImg.addEventListener("mouseup", (e) => {
				e.preventDefault();
				document.body.style.cursor = "default";
				isDrag = false;
				prevImg.style.transition = "all .3s";
			});
			HbPrevWrap.value.addEventListener("wheel", (e) => {
				// 前面是谷歌的，后面是火狐的
				if (e.wheelDelta > 0 || e.detail > 0) {
					if (elScale.x < 1.9) {
						elScale.x += 0.1;
						elScale.y += 0.1;
					}
				}
				if (e.wheelDelta < 0 || e.detail < 0) {
					if (elScale.x > 0.4) {
						elScale.x -= 0.1;
						elScale.y -= 0.1;
					}
				}

				// 设置缩放
				prevImg.style.transform = `scale(${elScale.x},${elScale.y}) rotate(${elRotate}deg)`;
				elPosition = getElementPos(prevImg);
			});
		}
	} else {
		isShow.value = false;
	}
}

function handlePrevIndex(index) {
	const prevImg = HbPrevImg.value;
	prevImg.style.transition = "none";
	pIndex.value = index;
	elScale = { x: 1, y: 1 };
	elRotate = 0;
	HbPrevImg.value.style.transform = "scale(1) rotate(0deg)";
	setTimeout(() => {
		prevImg.style.transition = "all .3s";
	}, 30);
}

function prevLeft() {
	if (pIndex.value > 0) {
		pIndex.value--;
	} else {
		pIndex.value = props.list.length - 1;
	}
	const prevImg = HbPrevImg.value;

	prevImg.style.transition = "none";
	initialImage(prevImg);
	setTimeout(() => {
		prevImg.style.transition = "all .3s";
	}, 30);
}

function prevRight() {
	if (pIndex.value < props.list.length - 1) {
		pIndex.value++;
	} else {
		pIndex.value = 0;
	}
	const prevImg = HbPrevImg.value;
	prevImg.style.transition = "none";
	initialImage(prevImg);
	setTimeout(() => {
		prevImg.style.transition = "all .3s";
	}, 30);
}

function prevOriginal() {
	const prevImg = HbPrevImg.value;
	initialImage(prevImg, "original");
	prevImg.style.transform = `scale(${elScale.x},${elScale.y}) rotate(${elRotate}deg)`;
}

function prevRotateLeft() {
	const prevImg = HbPrevImg.value;
	prevImg.style.transform = `scale(${elScale.x},${elScale.y}) rotate(${(elRotate -= 90)}deg)`;
}

function prevRotateRight() {
	const prevImg = HbPrevImg.value;
	prevImg.style.transform = `scale(${elScale.x},${elScale.y}) rotate(${(elRotate += 90)}deg)`;
}

function handleClose() {
	if (props.clickHide) {
		isShow.value = false;
	}
}

onMounted(() => {
	initialPreview();
});

const HbPrevWrap = ref();
const HbPrevImg = ref();
const HbPrevThumbBox = ref();
const HbPrevThumb = ref();
</script>
<template>
	<div v-if="isShow" ref="HbPrevWrap" class="hb-prev-wrap">
		<div class="hb-prev-mask" @click="handleClose" />
		<img ref="HbPrevImg" class="hb-prev-img" alt="预览图" :src="list[pIndex]" />
		<div v-if="props.isThumb" ref="HbPrevThumbBox" class="hb-prev-thumb-box">
			<div ref="HbPrevThumb" class="hb-prev-thumb-list">
				<div v-for="(item, i) in props.list" :key="i" class="hb-prev-thumb-item"
					:class="pIndex === i ? 'hb-prev-thumb-item-active' : ''" @click="handlePrevIndex(i)">
					<img class="hb-prev-thumb-img" :src="item" />
				</div>
			</div>
		</div>
		<div class="hb-prev-bar">
			<div class="hb-prev-btn" title="向左旋转" @click="prevRotateLeft">
				<i class="ri-anticlockwise-line" />
			</div>
			<div class="hb-prev-btn" title="前一张" @click="prevLeft">
				<i class="ri-arrow-left-s-line" />
			</div>
			<div class="hb-prev-btn" title="图片原始大小" @click="prevOriginal">
				<i class="ri-aspect-ratio-line" />
			</div>
			<div class="hb-prev-btn" title="后一张" @click="prevRight">
				<i class="ri-arrow-right-s-line" />
			</div>
			<div class="hb-prev-btn" title="向右旋转" @click="prevRotateRight">
				<i class="ri-clockwise-line" />
			</div>
		</div>
		<div class="hb-prev-close" @click="isShow = false">
			<i class="ri-close-line" />
		</div>
	</div>
</template>

<style scoped>
.hb-prev-wrap {
	position: fixed;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 99999;
}

.hb-prev-mask {
	height: 100%;
	width: 100%;
	background-color: rgba(0, 0, 0, 0.5);
}

.hb-prev-img {
	position: fixed;
	transition: all 0.3s;
}

.hb-prev-bar {
	position: fixed;
	left: 50%;
	bottom: 30px;
	transform: translateX(-50%);
	width: 250px;
	height: 50px;
	background-color: rgba(96, 98, 102, 0.71);
	border-radius: 25px;
	padding: 0 25px;
	box-sizing: border-box;
	display: flex;
	justify-content: space-between;
	align-items: center;
	user-select: none;
}

.hb-prev-btn {
	width: 30px;
	height: 30px;
	border-radius: 60px;
	background-color: #999999;
	color: #ffffff;
	display: flex;
	justify-content: center;
	align-items: center;
	cursor: pointer;
}

.hb-prev-btn:hover {
	background-color: #aaaaaa;
}

.hb-prev-close {
	width: 50px;
	height: 50px;
	position: fixed;
	top: 50px;
	right: 50px;
	font-size: 36px;
	color: #f2f3f5;
	cursor: pointer;
	background-color: #999999;
	display: flex;
	justify-content: center;
	align-items: center;
	border-radius: 50px;
	padding: 5px;
}

.hb-prev-close:hover {
	background-color: #aaaaaa;
}

.hb-prev-thumb-box {
	max-width: 50%;
	overflow-x: scroll;
	position: fixed;
	left: 50%;
	bottom: 90px;
	transform: translateX(-50%);
	padding: 5px;
	box-sizing: border-box;
	background-color: rgba(96, 98, 102, 0.71);
}

.hb-prev-thumb-box::-webkit-scrollbar {
	display: none;
}

.hb-prev-thumb-list {
	display: flex;
}

.hb-prev-thumb-item {
	height: 100px;
	width: 100px;
	margin: 0 5px;
	padding: 5px 10px;
	box-sizing: border-box;
	cursor: pointer;
	transition: all 0.3s;
}

.hb-prev-thumb-item:hover {
	background-color: #888888;
}

.hb-prev-thumb-item-active {
	padding: 0;
	background-color: #888888;
	border: 1px solid #ffffff;
}

.hb-prev-thumb-img {
	height: 100%;
	width: 100%;
	object-fit: scale-down;
}
</style>
