<template>
	<view :class="{ 'camera-page': true, 'safety-zone-bottom': phoneSafeArea }" :style="dynamicStyle"
		style="background-color: #333;">
		<canvas v-if="canvasH" class="camera-canvas" canvas-id="myCanvas"
			:style="{ width: canvasW + 'px', height: canvasH + 'px' }"></canvas>

		<view v-show="!cameraSrc">
			<camera class="camera-box" mode="normal" :device-position="devicePosition" resolution="high"
				style="width: 390px;height: 390px; top: 180rpx;" aspect="1:1" frame-size="medium" output-dimension="max"
				flash="off" @error="onChangeError">
				<!-- 取景框 -->
				<cover-view class="camera-aperture" id="frameDom"></cover-view>
				<!-- <cover-view class="camera-aperture-line camera-aperture-top"></cover-view>
				<cover-view class="camera-aperture-line camera-aperture-right"></cover-view>
				<cover-view class="camera-aperture-line camera-aperture-bottom"></cover-view>
				<cover-view class="camera-aperture-line camera-aperture-left"></cover-view>
				<cover-view v-if="tipsText" class="camera-aperture-tips">{{ tipsText }}</cover-view> -->
			</camera>
			<!-- 预览区域 -->
			<view class="preview-area" v-if="previewImages.length > 0">
				<scroll-view scroll-x class="preview-scroll">
					<view class="preview-grid">
						<view v-for="(image, index) in previewImages" :key="index" class="preview-item">
							<image :src="image" mode="aspectFill" />
							<view class="delete-icon" @click.stop="deletePreviewImage(index)">×</view>
						</view>
					</view>
				</scroll-view>
			</view>

			<!-- 操作栏 -->
			<view class="camera-control" style="z-index: 999; background-color: #333;">
				<view class="right-item">
					<view v-if="tipsText" style="color: #fff; font-size: 28rpx;">{{ tipsText }}</view>
				</view>

				<view class="center-item">
					<view class="photo-btn" @click="takePhoto"
						style="background: rgba(255, 255, 126, 0.8); padding: 15px; border-radius: 50%; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);">
						<view class="photo" style="color: #333; font-size: 16px;"></view>
					</view>
				</view>
				<view class="left-item">
					<view class="back-btn" @click="onConfirm" style="color: #fff !important;font-size: 26px;">确认
					</view>
				</view>
				<!-- <view class="right-item"> -->
				<!-- style="background: rgba(255, 255, 255, 0.8); padding: 10px; border-radius: 8px; display: flex; align-items: center; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);" -->
				<!-- 		<image class="device-pos" src="../../image/switch_icon.png" @click="onDevicePosition"
						style="width: 24px; height: 24px; margin-right: 4px;" />
					<text style="color: #333; font-size: 14px;"></text>
				</view> -->
			</view>
		</view>

		<!-- 图片预览 -->
		<view v-show="cameraSrc" class="camera-img">
			<view class="preview-box">
				<image class="preview" :src="cameraSrc" mode="widthFix" />
			</view>
			<view class="preview-edit">
				<view class="preview-edit-btn" @click="onCancel">取消</view>
				<view class="preview-edit-btn" @click="onUpload">继续上传</view>
				<!-- <view class="preview-edit-btn submit-btn" @click="onConfirm">确认</view> -->
			</view>
		</view>

		<!-- 安全区 -->
		<view v-if="phoneSafeArea" class="safety-zone"></view>

		<!-- 添加提示文字 -->
		<view class="photo-tip">
			<text>拍照后ISBN与书名不可修改</text>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			// 提示语句
			tipsText: {
				type: String,
				default: '请靠近取景框'
			},

			// 颜色
			color: {
				type: String,
				default: 'rgba(36, 64, 135, 0.8)'
			},
			currentCount: {
				type: Number,
				default: 0
			},
			maxCount: {
				type: Number,
				default: 9
			},
			fileList: {
				type: Array,
				default: () => []
			}
		},

		data() {
			return {
				// devicePosition: 'front', // 默认前置
				devicePosition: 'back',
				cameraSrc: '',
				canvasW: 0,
				canvasH: 0,
				pageWidth: 0,
				frameOptions: {}, // 取景框配置信息
				phoneSafeArea: false, // 设备安全区
				previewImages: [] // 预览图片数组
			}
		},

		mounted() {
			uni.getSystemInfo({
				success: res => {
					// 安全区判断
					if (res.safeAreaInsets.bottom) this.phoneSafeArea = true
				}
			})

			this.$nextTick(() => {
				const query = uni.createSelectorQuery().in(this)
				query
					.select('#frameDom')
					.boundingClientRect(data => {
						this.frameOptions = data
						console.log('得到布局位置信息' + JSON.stringify(data))
					})
					.exec()

				// 系统信息
				const winInfo = uni.getSystemInfoSync()
				this.pageWidth = winInfo.windowWidth
			})
		},

		methods: {
			// 取消
			onCancel() {
				const currentSrc = this.cameraSrc;
				this.$emit('onCancel', {
					url: currentSrc || ''
				});
				this.cameraSrc = '';
			},
			// 继续上传
			onUpload() {
				if (this.previewImages.length < 9) {
					this.previewImages.push(this.cameraSrc);
					console.log("上传预览图片", this.previewImages);
					this.$emit('onUpload', {
						url: this.cameraSrc,
						count: this.currentCount + 1
					});
					this.cameraSrc = '';
				} else {
					uni.showToast({
						title: '最多只能上传9张图片',
						icon: 'none'
					});
				}
			},
			// 删除预览图片
			deletePreviewImage(index) {
				// 删除预览图片
				this.previewImages.splice(index, 1);

				// 通知父组件删除对应的实际图片
				this.$emit('onDeleteImage', {
					index: index
				});

				console.log("删除图片后的预览图片", this.previewImages);
			},
			// 确认照片
			onConfirm() {
				this.$emit('onConfirm', {
					url: this.cameraSrc
				})
			},

			// 拍照
			takePhoto() {
				// 打印当前数量
				console.log('fileList.length:', this.fileList?.length || 0, 'previewImages.length:', this.previewImages
					.length, 'currentCount', this.currentCount);
				// 限制总照片数：fileList.length >= 9
				if (this.fileList?.length >= 9) {
					uni.showToast({
						title: '最多只能上传9张图片',
						icon: 'none'
					});
					return;
				}
				// 拍照音效
				// const audio = uni.createInnerAudioContext();
				// audio.src = '/static/camera-shutter.mp3';
				// audio.play();
				const ctx = uni.createCameraContext()
				ctx.takePhoto({
					quality: 'high',
					selfieMirror: true, // 是否开启镜像 默认true
					success: async res => {
						// 拍照震动反馈
						// uni.vibrateShort && uni.vibrateShort();
						this.cameraSrc = await this.cropImage(res.tempImagePath)
						// 拍照后直接上传，不显示预览
						this.onUpload();
						this.cameraSrc = '';
					}
				})
			},

			// 裁剪图片
			cropImage(imgUrl) {
				return new Promise((resolve, reject) => {
					uni.getImageInfo({
						src: imgUrl,
						success: file => {
							// 取景框信息
							const options = {
								width: this.frameOptions.width,
								height: this.frameOptions.height,
								y: this.frameOptions.top,
								x: this.frameOptions.left
							}

							const ctx = uni.createCanvasContext('myCanvas', this)

							// 使用原图尺寸作为canvas尺寸
							this.canvasW = file.width
							this.canvasH = file.height

							// 计算裁剪区域在原图中的实际位置和尺寸
							const scale = file.width / this.pageWidth
							const cropX = options.x * scale
							const cropY = options.y * scale
							const cropWidth = options.width * scale
							const cropHeight = options.height * scale

							// 使用高质量的图片绘制方式
							ctx.save()
							ctx.drawImage(file.path, 0, 0, file.width, file.height)
							ctx.restore()

							// 导出canvas为图片
							ctx.draw(true, () => {
								setTimeout(() => {
									// canvas 转 图片，使用原图分辨率
									uni.canvasToTempFilePath({
											x: 0,
											y: 0,
											width: file.width,
											height: file.width,
											destWidth: 800,
											destHeight: 800,
											canvasId: 'myCanvas',
											fileType: 'jpg',
											quality: 0.7,
											success: res => {
												resolve(res.tempFilePath)
											},
											fail(err) {
												reject(err)
											}
										},
										this
									)
								}, 0)
							})
						},
						fail(err) {
							reject(err)
						}
					})
				})
			},

			// 保存图片到手机相册
			saveImageToPhone(filePath) {
				uni.saveImageToPhotosAlbum({
					filePath,
					success: () => {
						uni.showToast({
							icon: 'none',
							title: '拍照成功'
						})
					}
				})
			},

			// 切换摄像头
			onDevicePosition() {
				this.devicePosition = this.devicePosition == 'back' ? 'front' : 'back'
			},

			// 监听报错
			onChangeError(e) {
				console.error('camera报错：', e.detail)
			}
		},
		computed: {
			dynamicStyle() {
				return {
					'--theme-color': this.color
				};
			}
		}
	}
</script>

<style lang="scss" scoped>
	.camera-page {
		--control-h: 150rpx;
		--preview-h: 160rpx;

		position: fixed;
		top: 0;
		left: 0;
		z-index: 99;
		width: 100vw;
		height: 100vh;
		overflow: hidden;
		background-color: #000000;

		.camera-box {
			--aperture-t: 10vh;
			--aperture-w: 560rpx;
			--aperture-line: 4rpx;
			--aperture-line-style: 4rpx dashed #fff;
			--edit-padding: 64rpx;

			position: relative;
			width: 100vw;
			height: calc(100vh - var(--control-h) - var(--preview-h));

			.camera-aperture {
				position: absolute;
				top: 10vh;
				left: 0;
				right: 0;
				width: var(--aperture-w);
				height: var(--aperture-w);
				border-style: dashed;
				border-width: 4rpx;
				border-color: #f9f9f9;
				margin: 0 auto;
				pointer-events: none;
				opacity: 0;
			}

			.camera-aperture-line {
				position: absolute;
				background-color: #fff;
				z-index: 2;
			}

			.camera-aperture-top {
				top: var(--aperture-t);
				left: calc((100vw - var(--aperture-w)) / 2);
				width: var(--aperture-w);
				height: var(--aperture-line);
			}

			.camera-aperture-right {
				top: var(--aperture-t);
				left: calc(var(--aperture-w) + (100vw - var(--aperture-w)) / 2);
				width: var(--aperture-line);
				height: var(--aperture-w);
			}

			.camera-aperture-bottom {
				top: calc(var(--aperture-t) + var(--aperture-w));
				left: calc((100vw - var(--aperture-w)) / 2);
				width: calc(var(--aperture-w) + var(--aperture-line));
				height: var(--aperture-line);
			}

			.camera-aperture-left {
				top: var(--aperture-t);
				left: calc((100vw - var(--aperture-w)) / 2);
				width: var(--aperture-line);
				height: var(--aperture-w);
			}

			.camera-aperture-tips {
				position: absolute;
				top: calc(var(--aperture-t) + var(--aperture-w) + 60rpx);
				left: 0;
				right: 0;
				font-size: 32rpx;
				color: #fff;
				max-width: 95%;
				color: #fff;
				text-align: center;
				margin: 0 auto;
			}
		}

		.camera-control {
			position: fixed;
			bottom: 0;
			left: 0;
			width: 100%;
			height: var(--control-h);
			background-color: #333;
			padding: 0 56rpx;
			box-sizing: border-box;
			display: flex;
			align-items: center;
			justify-content: space-between;
			z-index: 999;
			position: fixed;
			bottom: 0;
			left: 0;

			.left-item {
				width: 25%;
				display: flex;

				.sample {
					font-size: 32rpx;
					color: var(--theme-color);
				}
			}

			.center-item {
				width: 50%;
				display: flex;
				align-items: center;

				.photo-btn {
					width: 140rpx;
					height: 140rpx;
					border: 4rpx solid var(--theme-color);
					border-radius: 50%;
					padding: 10rpx;
					box-sizing: border-box;
					margin: 0 auto;

					.photo {
						width: 100%;
						height: 100%;
						border-radius: 50%;
						background-color: var(--theme-color);
					}
				}
			}

			.right-item {
				width: 25%;
				display: flex;
				justify-content: flex-end;
				font-size: 30rpx;

				.device-pos {
					width: 66rpx;
					height: 66rpx;
				}
			}
		}

		.camera-img {
			position: relative;
			width: 100vw;
			z-index: 9999;

			.preview-box {
				width: 100%;
				height: calc(100vh - var(--control-h));
				background-color: #333;
				display: flex;
				align-items: center;
				justify-content: center;

				.preview {
					width: 100%;
					height: 100%;
				}
			}

			.preview-edit {
				width: 100%;
				height: var(--control-h);
				display: flex;
				justify-content: space-between;
				align-items: center;
				padding: 0 60rpx;
				box-sizing: border-box;
				background-color: #333;
				// box-shadow: 0 -4rpx 12rpx rgba(158, 158, 158, 0.05);
				z-index: 9;

				.preview-edit-btn {
					padding: 16rpx 36rpx;
					border-radius: 12rpx;
					background-color: #fff;
					font-size: 32rpx;
					line-height: 1;
					color: #565656;
					font-weight: bold;
				}

				.submit-btn {
					// background-color: var(--theme-color);
					// color: #fff;
					color: var(--theme-color);
				}
			}
		}

		.preview-area {
			position: fixed;
			bottom: var(--control-h);
			left: 0;
			width: 100%;
			height: var(--preview-h);
			background-color: rgba(0, 0, 0, 0.5);
			z-index: 998;

			.preview-scroll {
				width: 100%;
				height: 100%;
				white-space: nowrap;
				padding: 16rpx;
				box-sizing: border-box;
			}

			.preview-grid {
				display: inline-flex;
				gap: 16rpx;
			}

			.preview-item {
				width: 120rpx;
				height: 120rpx;
				border-radius: 12rpx;
				overflow: hidden;
				border: 2rpx solid rgba(255, 255, 255, 0.3);
				position: relative;

				image {
					width: 100%;
					height: 100%;
					object-fit: cover;
				}

				.delete-icon {
					position: absolute;
					top: 0;
					right: 0;
					width: 50rpx;
					height: 50rpx;
					background-color: rgba(0, 0, 0, 0.6);
					color: #ffffff;
					text-align: center;
					line-height: 50rpx;
					border-radius: 50%;
					font-size: 45rpx;
					z-index: 10;
				}
			}
		}

		.camera-canvas {
			position: fixed;
			top: 200vh;
			left: 0;
			z-index: -999;
			opacity: 0;
		}
	}

	// 安全底部
	.safety-zone-bottom {
		--safety-zone-bottom: 34px;

		.camera-img>.preview-box,
		.camera-box {
			height: calc(100vh - var(--control-h) - var(--safety-zone-bottom));
		}

		// .safety-zone {
		// 	height: var(--safety-zone-bottom);
		// 	width: 100%;
		// 	background-color: inherit;
		// 	// z-index: 9999;
		// 	background-color: #000000;
		// }
	}

	/* 添加提示文字样式 */
	.photo-tip {
		position: absolute;
		top: 20rpx;
		left: 0;
		right: 0;
		z-index: 1000;
		text-align: center;
		padding: 10rpx;
	}

	.photo-tip text {
		background-color: rgba(0, 0, 0, 0.6);
		color: #fff;
		padding: 10rpx 30rpx;
		border-radius: 30rpx;
		font-size: 28rpx;
	}
</style>