<template>
	<view class="container">
		<!-- 原生相机预览 -->
		<camera id="idCamera" class="camera-preview" device-position="back" flash="off" binderror="onCameraError" />
		<!-- 隐藏的裁剪 Canvas -->
		<canvas canvas-id="cropCanvas"
			style="width:100%;height:100%;position:absolute;top:0;left:0;display:none;"></canvas>
		<!-- 遮罩层 -->
		<view class="mask">
			<view class="mask-block top" />
			<view class="mask-block middle">
				<view class="side" />
				<view class="cutout">
					<text class="hint">请将身份证放入此框内</text>
				</view>
				<view class="side" />
			</view>
			<view class="mask-block bottom" />
		</view>

		<!-- 底部拍照按钮 -->
		<view class="controls">
			<button class="shutter" @tap="takePhoto">拍 照</button>
		</view>
	</view>
</template>

<script setup>
	import {
		onMounted,
		ref
	} from 'vue';

	let cameraContext;
	const sysInfo = uni.getSystemInfoSync(); // 获取屏幕宽高

	onMounted(() => {
		cameraContext = uni.createCameraContext();
	});

	function onCameraError(e) {
		console.error('Camera Error:', e);
	}

	function takePhoto() {
		cameraContext.takePhoto({
			quality: 'high',
			success: async (res) => {
				const src = res.tempImagePath;

				// 2.1 计算屏幕上 cutout 区域（px）
				const screenW = sysInfo.windowWidth;
				const screenH = sysInfo.windowHeight;
				const topMaskH = screenH * 0.25; // mask-block.top 高度
				const middleH = screenH * 0.50; // mask-block.middle 高度
				const cutoutH = middleH * 0.60; // cutout 高度
				const cutoutW = cutoutH * 1.586; // 按 aspect-ratio:1.586 计算宽度
				const cutoutX = (screenW - cutoutW) / 2; // 居中
				const cutoutY = topMaskH + (middleH - cutoutH) / 2;

				// 2.2 拿到原图真实尺寸，用于映射
				const info = await uni.getImageInfo({
					src
				});
				const origW = info.width;
				const origH = info.height;

				// 2.3 计算裁剪在原图上的参数
				const ratioW = origW / screenW;
				const ratioH = origH / screenH;
				const sx = cutoutX * ratioW;
				const sy = cutoutY * ratioH;
				const sWidth = cutoutW * ratioW;
				const sHeight = cutoutH * ratioH;
				// uni.authorize({
				//   scope: 'scope.camera',
				//   success: () => console.log('已授权相机'),
				//   fail: () => uni.showModal({ title: '权限不足', content: '请在设置里打开相机权限' })
				// });
				// 3. 在 Canvas 上裁切
				const ctx = uni.createCanvasContext('cropCanvas', {
					enableScroll: false
				});
				// 设置画布尺寸为裁剪区域的像素大小
				ctx.drawImage(src, sx, sy, sWidth, sHeight, 0, 0, sWidth, sHeight);
				ctx.draw(false, () => {
					uni.canvasToTempFilePath({
						canvasId: 'cropCanvas',
						x: 0,
						y: 0,
						width: sWidth,
						height: sHeight,
						destWidth: sWidth,
						destHeight: sHeight,
						success: (cropRes) => {
							// 裁切完成，存入缓存并返回
							uni.setStorageSync('idcardPhoto', cropRes.tempFilePath);
							uni.navigateBack({
								delta: 1
							});
						},
						fail: (err) => {
							console.error('Canvas to TempFile Fail:', err);
						}
					});
				});
			},
			fail: (err) => {
				console.error('Take Photo Fail:', err);
			}
		});
	}
</script>

<style scoped>
	.container {
		position: relative;
		width: 100%;
		height: 100vh;
		background: #000;
	}

	.camera-preview {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
	}

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

	.mask-block {
		width: 100%;
		background: rgba(0, 0, 0, 0.5);
	}

	.mask-block.top,
	.mask-block.bottom {
		height: 25%;
	}

	.mask-block.middle {
		display: flex;
		flex-direction: row;
		height: 50%;
	}

	.side {
		flex: 1;
		background: rgba(0, 0, 0, 0.5);
	}

	.cutout {
		width: 100%;
		height: 60%;
		aspect-ratio: 1.586;
		border: 2rpx dashed #fff;
		position: relative;
	}

	.hint {
		position: absolute;
		bottom: 20rpx;
		width: 100%;
		text-align: center;
		color: #fff;
		font-size: 24rpx;
	}

	.controls {
		position: absolute;
		bottom: 50rpx;
		width: 100%;
		display: flex;
		justify-content: center;
	}

	.shutter {
		width: 300rpx;
		height: 120rpx;
		border-radius: 60rpx;
		background: rgba(255, 255, 255, 0.7);
		display: flex;
		justify-content: center;
		align-items: center;
	}
</style>