<template>
	<view class="captcha-container" ref="container">
		<view class="font-title">请通过滑块验证</view>
		<view class="captcha-image" style="position: relative; width: 100%; height: 400rpx; overflow: hidden;">
			<image :src="bgImage" class="bg-image" mode="widthFix" @load="init" />
			<view class="overlay" :style="{width: containerWidth + 'rpx', height: containerHeight + 'rpx'}">
				<view class="hole" :style="{
            top: originY + 'rpx',
            left: (originX +50 ) + 'rpx',
            width: pieceSize + 'rpx',
            height: pieceSize + 'rpx',
            clipPath: clipPath,
            transform: 'translate(-50%, -50%)',
            backgroundColor: 'rgba(0,0,0,0.6)'
          }"></view>

				<view class="piece" :style="{
            top: originY + 'rpx',
            left: (offsetX +50 )  + 'rpx',
            width: pieceSize + 'rpx',
            height: pieceSize + 'rpx',
            backgroundImage: `url(${bgImage})`,
            backgroundSize: containerWidth + 'rpx ' + containerHeight + 'rpx',
            backgroundPosition: `-${originX+10}rpx -${originY-20}rpx`,
            clipPath: clipPath,
            transform: 'translate(-50%, -50%)'
          }"></view>
			</view>
		</view>

		<view class="slider-bar">
			<view class="slider-bar-font">
				向右滑动滑块填充拼图
			</view>
			<view class="slider-button" ref="btn" @touchstart.prevent="onStart" @mousedown.prevent="onStart"
				:style="{ left: offsetX + 'rpx', maxWidth: (containerWidth - pieceSize) + 'rpx' }">
				<image src="/static/login/right.png" style="width: 50rpx;height: 50rpx;" mode="widthFix" />
			</view>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		onBeforeUnmount
	} from 'vue';
	import {
		onLoad
	} from '@dcloudio/uni-app';

	import img0 from '@/static/login/0.png'
	import img1 from '@/static/login/1.png'
	import img2 from '@/static/login/2.png'
	import img3 from '@/static/login/3.png'

	const emit = defineEmits(['success'])

	const pieceSizePx = 50;
	const pieceSize = pieceSizePx * 2;
	const tolerance = 20;

	const container = ref(null);
	const btn = ref(null);

	const containerWidthPx = 200;
	const containerHeightPx = 300;

	const containerWidth = ref(containerWidthPx * 2);
	const containerHeight = ref(containerHeightPx * 2);

	const originX = ref(0);
	const originY = ref(0);
	const offsetX = ref(0);
	const dragging = ref(false);
	const startX = ref(0);

	function getPuzzlePiecePath(size) {
		const s = size;
		return `
    M${10*2} 0
    h${s / 3 - 10*2}
    a${10*2} ${10*2} 0 0 1 0 ${20*2}
    h${s / 3}
    a${10*2} ${10*2} 0 0 0 0 -${20*2}
    h${s / 3 - 10*2}
    v${s / 3 - 10*2}
    a${10*2} ${10*2} 0 0 1 -${20*2} 0
    v${s / 3}
    a${10*2} ${10*2} 0 0 0 ${20*2} 0
    v${s / 3 - 10*2}
    h-${s / 3 - 10*2}
    a${10*2} ${10*2} 0 0 1 0 -${20*2}
    h-${s / 3}
    a${10*2} ${10*2} 0 0 0 0 ${20*2}
    h-${s / 3 - 10*2}
    z
  `;
	}

	const clipPath = `path('${getPuzzlePiecePath(pieceSize)}')`;

	function init() {
		uni.createSelectorQuery()
			.in(container.value)
			.select('.bg-image')
			.boundingClientRect(data => {
				if (!data) {
					console.error('无法获取.bg-image尺寸');
					return;
				}
				console.log('图片宽高：', data.width, data.height); // 加这个调试！

				containerWidth.value = data.width * 2;
				containerHeight.value = data.height * 2;

				originX.value = Math.random() * (containerWidth.value - pieceSize * 2) + pieceSize;
				// console.log("!!!!!",originX.value)
				if (originX.value < 100) {
					originX.value = 100;
				}
				originY.value = containerHeight.value / 2;
				offsetX.value = 0;

				console.log('originX:', originX.value, 'originY:', originY.value);
			})
			.exec();
	}

	function onStart(e) {
		dragging.value = true;
		startX.value = e.touches ? e.touches[0].clientX * 2 : e.clientX * 2;
		window.addEventListener('mousemove', onMove);
		window.addEventListener('mouseup', onEnd);
		window.addEventListener('touchmove', onMove);
		window.addEventListener('touchend', onEnd);
	}

	function onMove(e) {
		if (!dragging.value) return;
		const clientX = e.touches ? e.touches[0].clientX * 2 : e.clientX * 2;
		let dx = clientX - startX.value;
		dx = Math.max(0, Math.min(dx, containerWidth.value - pieceSize));
		offsetX.value = dx;
	}
	const uToast = ref(null)


	function onEnd() {
		dragging.value = false;
		window.removeEventListener('mousemove', onMove);
		window.removeEventListener('mouseup', onEnd);
		window.removeEventListener('touchmove', onMove);
		window.removeEventListener('touchend', onEnd);
		if (Math.abs(offsetX.value - originX.value) < tolerance) {
			// console.log('验证成功');
			
			uni.showToast({
				title: '验证成功',
				icon: 'none', // 不显示图标（提示信息）
				duration: 2000 // 显示时长（毫秒）
			})
			emit('success')
		} else {
			offsetX.value = 0;
			uni.showToast({
				title: '验证失败',
				icon: 'none', // 不显示图标（提示信息）
				duration: 2000 // 显示时长（毫秒）
			})
		}
	}

	const bgImage = ref("");
	onLoad(() => {
		let randomInt = Math.floor(Math.random() * 4);
		const bgImageMap = [img0, img1, img2, img3];
		bgImage.value = bgImageMap[randomInt];
	})

	onBeforeUnmount(() => {
		window.removeEventListener('mousemove', onMove);
		window.removeEventListener('mouseup', onEnd);
		window.removeEventListener('touchmove', onMove);
		window.removeEventListener('touchend', onEnd);
	});
</script>


<style scoped lang="scss">
	.captcha-container {
		/* margin: 20rpx auto; */
		user-select: none;
		background-color: #fff;
		width: 600rpx;
		height: 700rpx;
		margin: 0 auto;
		z-index: 999;
		border-radius: 30rpx;
		overflow: hidden;
		padding: 0 30rpx;
	}

	.captcha-image {
		position: relative;
		overflow: hidden;
	}

	.bg-image {
		position: relative;
		z-index: 1;
		display: block;
		/* margin-top: 30rpx; */
		width: 100%;
		height: 100%;
	}

	.overlay {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		z-index: 100;
		pointer-events: none;
	}

	.hole,
	.piece {
		position: absolute;
		z-index: 101;
		/* border-radius: 5rpx; */
		box-shadow: 0 0 6rpx rgba(0, 0, 0, 0.4);
	}

	.hole {
		background-color: rgba(0, 0, 0, 0.3);
	}

	.piece {
		background-repeat: no-repeat;
		background-size: cover;
		cursor: grab;
	}

	.slider-bar {
		position: relative;
		height: 100rpx;
		margin-top: 0rpx;
		background: rgb(245, 246, 252);
		/* border-radius: 80rpx; */
		width: 540rpx;
		display: flex;
		justify-content: center;
		align-items: center;

		.slider-bar-font {
			// z-index: -1;
			color: rgb(169, 169, 171);
			font-size: 28rpx;
		}
	}

	.slider-button {
		position: absolute;
		top: 0rpx;
		left: 0;
		width: 100rpx;
		height: 100rpx;
		background: #fff;
		/* border-radius: 60rpx; */
		box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.2);
		transition: background 0.3s;
		user-select: none;
		border-radius: 10rpx;
		border: 3rpx solid rgb(139, 218, 202);
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.slider-button.success {
		background: #4caf50;
	}

	.font-title {
		width: 100%;
		display: flex;
		justify-content: center;
		align-items: center;
		height: 100rpx;
		font-size: 35rpx;
		font-weight: 700;
	}
</style>