<template>
	<view class="container">
		<view class="example">
			<uni-forms ref="dynamicForm" :model="form" label-width="80px">
				<uni-forms-item label="巡检点" name="inspectionPoint">
					<uni-easyinput disabled :value="form.inspectionPoint" placeholder="请输入巡检点"></uni-easyinput>
				</uni-forms-item>
				<uni-forms-item label="巡检要求" name="inspectionRequirements">
					<uni-easyinput type="textarea" disabled :value="form.inspectionRequirements"
						placeholder="请输入巡检要求"></uni-easyinput>
				</uni-forms-item>
				<uni-forms-item label="图片上传">
					<view class="example-body">
						<uni-file-picker limit="3" :sourceType="sourceType" :value="img" title="最多选择3张图片"
							file-mediatype="image" @delete="deleteImg" @select="upload"
							:auto-upload="false"></uni-file-picker>
					</view>
				</uni-forms-item>
				<!-- 备注 -->
				<uni-forms-item label="备注1" name="remark">
					<uni-easyinput type="textarea" v-model="form.remark" placeholder="请输入备注"></uni-easyinput>
				</uni-forms-item>
			</uni-forms>
			<view class="button-group">
				<button class="btn btn-primary" @click="submit()">提交</button>
				<button class="btn btn-cancel" @click="cancel()">取消</button>
			</view>
		</view>
		<!-- 消息提示框 -->
		<view>
			<uni-popup ref="alertDialog" type="dialog">
				<uni-popup-dialog :type="msgType" title="消息" :content="messageText" @confirm="dialogConfirm"
					showClose="false"></uni-popup-dialog>
			</uni-popup>
		</view>

	</view>
</template>

<script>
	import {
		addRecord
	} from "@/api/inspection/record.js"
	// 如果你已有 uploadImg 封装且内部就是 uni.uploadFile，可以继续用；
	// 但前提是它支持 H5 直接传 File 对象（不是 URL 字符串）。
	// 这里我示范“直接用 uni.uploadFile”的写法，更稳妥。
	import {
		addWatermarkToImage
	} from "@/utils/watermark.js"
	import appConfig from '@/config'
	const UPLOAD_URL = appConfig.baseUrl + "/common/upload" // 按你后端改

	export default {
		data() {
			return {
				form: {
					inspectionType: 0,
					inspectorId: this.$store.state.user.nickName,
					inspectionPoint: "",
					inspectionRequirements: "",
					inspectionImg: "",
					ImgUrl: [], // 存后端返回的文件名/URL
					remark: ""
				},
				img: [], // 绑定给 uni-file-picker 的预览列表
				sourceType: ['camera'],
				msgType: '',
				messageText: '',
				isUploading: false,
				isMobileBrowser: false
			}
		},
		methods: {
			async submit() {
				if (this.isUploading) {
					this.showMessage('warning', '图片正在上传中，请稍等')
					return
				}
				if (!Array.isArray(this.form.ImgUrl) || this.form.ImgUrl.length === 0) {
					this.showMessage('error', '请选择要上传的图片')
					return
				}
				this.form.inspectionImg = this.joinList()
				try {
					const res = await addRecord(this.form)
					if (res.code === 200) {
						this.showMessage('success', '打卡成功')
					} else {
						this.showMessage('error', '打卡失败')
					}
				} catch (err) {
					this.showMessage('error', `提交失败: ${err.message}`)
				}
			},

			// uni-file-picker 删除：e.tempFile 里通常有 {url/path}，与你传给 value 的结构需一致
			deleteImg(e) {
				const url = e.tempFile?.url || e.tempFile?.path
				const idx = this.img.findIndex(x => x.url === url)
				if (idx !== -1) {
					this.img.splice(idx, 1)
					// 同步移除已上传结果（按你的业务，可以用同索引移除或按返回名移除）
					this.form.ImgUrl.splice(idx, 1)
				}
			},

			// 选择文件（支持多张）
			async upload(e) {
				if (!e?.tempFiles?.length) return
				if (this.isUploading) {
					this.showMessage('warning', '图片正在上传中，请稍等')
					return
				}

				this.isUploading = true
				try {
					// 逐张处理
					for (const tf of e.tempFiles) {
						await this.handleImageUpload(tf) // 这里传入每个 tempFile
					}
					// this.showMessage('success', '图片处理/上传完成')
				} catch (err) {
					console.error(err)
					this.showMessage('error', `图片上传失败：${err.message || err}`)
				} finally {
					this.isUploading = false
				}
			},

			// 单张处理：加水印 ->（可选）压缩 -> 上传
			async handleImageUpload(tempFile) {
				// tempFile.file: H5 下是 File 对象；App/小程序是临时路径
				const raw = tempFile.file || tempFile // 兼容各端
				// 生成水印文字
				const watermarkText = `${this.form.inspectionPoint || '未命名地点'} \n${this.getCurrentDate()}`
				// 加水印（返回 File/Blob）
				const watermarked = await addWatermarkToImage(raw, watermarkText)
				// 可选：移动端压缩（你已有方法，按需启用）
				//   const finalFile = await this.compressImageForMobile(watermarked)

				const finalFile = watermarked

				// 预览：用本地 URL，仅供前端显示
				const previewUrl = URL.createObjectURL(finalFile)
				this.img.push({
					url: previewUrl, // uni-file-picker 识别 url
					name: finalFile.name || `image_${Date.now()}.jpg`,
					extname: 'jpg'
				})

				// 真正上传：**不要传 previewUrl 字符串**，而是传二进制 `file`
				// H5 下：uni.uploadFile 支持传 `file: File`
				const uploadedName = await this.uploadFileWithUni(finalFile)
				// 回填后端返回的文件名/URL
				this.form.ImgUrl.push(uploadedName)
			},

			// 用 uni.uploadFile 直接传二进制
			uploadFileWithUni(file) {
				return new Promise((resolve, reject) => {
					uni.uploadFile({
						url: UPLOAD_URL,
						name: 'file', // 后端接收字段名（按你的后端改）
						file, // H5 直接传 File 对象（重点！）
						// 如果后端还需要额外字段：
						// formData: { bizType: 'inspection' },
						success: (res) => {
							try {
								const data = typeof res.data === 'string' ? JSON.parse(res.data) : res
									.data
								if (data.code === 200) {
									// 假设后端返回 { code:200, fileName: 'xxx.jpg', url:'...' }
									resolve(data.fileName || data.url)
								} else {
									reject(new Error(data.msg || '上传失败'))
								}
							} catch (e) {
								reject(new Error('上传响应解析失败'))
							}
						},
						fail: (err) => reject(err)
					})
				})
			},

			cancel() {
				uni.reLaunch({
					url: '/pages/work/index'
				})
			},

			joinList() {
				return this.form.ImgUrl.join(',')
			},

			getCurrentDate() {
				const now = new Date()
				const y = now.getFullYear()
				const m = String(now.getMonth() + 1).padStart(2, '0')
				const d = String(now.getDate()).padStart(2, '0')
				const hh = String(now.getHours()).padStart(2, '0')
				const mm = String(now.getMinutes()).padStart(2, '0')
				const ss = String(now.getSeconds()).padStart(2, '0')
				return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
			},

			dialogConfirm() {
				if (this.msgType === 'success') {
					uni.reLaunch({
						url: '/pages/work/index'
					})
				}
			},

			showMessage(type, text) {
				this.msgType = type
				this.messageText = text
				this.$refs.alertDialog.open()
			},

			checkMobileBrowser() {
				const ua = navigator.userAgent.toLowerCase()
				const isMobile = /iphone|ipod|android|windows phone|mobile|blackberry/.test(ua)
				this.isMobileBrowser = isMobile || window.__uniAppWebview
			},
			// 计算目标尺寸
			calcTargetSize(imgW, imgH, maxW, maxH) {
				let w = imgW,
					h = imgH
				if (w > maxW || h > maxH) {
					const ratio = Math.min(maxW / w, maxH / h)
					w = Math.round(w * ratio)
					h = Math.round(h * ratio)
				}
				return {
					w,
					h
				}
			},

			// iOS 兼容 toBlob（老 Safari）
			canvasToBlob(canvas, type, quality) {
				return new Promise((resolve) => {
					if (canvas.toBlob) {
						canvas.toBlob((blob) => resolve(blob), type, quality)
					} else {
						// fallback: toDataURL -> Blob
						const dataURL = canvas.toDataURL(type, quality)
						const arr = dataURL.split(',')
						const mime = arr[0].match(/:(.*?);/)[1]
						const bstr = atob(arr[1])
						let n = bstr.length
						const u8arr = new Uint8Array(n)
						while (n--) u8arr[n] = bstr.charCodeAt(n)
						resolve(new Blob([u8arr], {
							type: mime
						}))
					}
				})
			},

			// H5: DataURL -> File
			blobToFile(blob, filename) {
				return new File([blob], filename || `img_${Date.now()}.jpg`, {
					type: blob.type || 'image/jpeg'
				})
			},

			/**
			 * 压缩图片（移动端友好）
			 * @param {File|Object|String} input  H5: File；小程序/APP：tempFile 对象或临时路径
			 * @param {Object} opts  { quality: 0.6, maxWidth: 1200, maxHeight: 1200, mime: 'image/jpeg' }
			 * @returns Promise<File|string>  H5 返回 File；小程序/APP 返回压缩后的临时路径
			 */
			async compressImageForMobile(input, opts = {}) {
				const {
					quality = 0.6,
						maxWidth = 1200,
						maxHeight = 1200,
						mime = 'image/jpeg'
				} = opts

				// #ifdef H5
				// —— H5：使用 canvas 压缩 —— //
				const file = input instanceof File ? input : (input?.file instanceof File ? input.file : null)
				if (!file) return input // 没拿到 File 就直接返回原始值

				// 读取为 dataURL
				const dataURL = await new Promise((resolve, reject) => {
					const reader = new FileReader()
					reader.onload = () => resolve(reader.result)
					reader.onerror = () => reject(new Error('文件读取失败'))
					reader.readAsDataURL(file)
				})

				// 图片加载
				const img = await new Promise((resolve, reject) => {
					const image = new Image()
					image.onload = () => resolve(image)
					image.onerror = () => reject(new Error('图片加载失败'))
					image.src = dataURL
				})

				const {
					w,
					h
				} = this.calcTargetSize(img.width, img.height, maxWidth, maxHeight)
				// 如果尺寸本来就不大，直接走质量压缩（或原图）
				const canvas = document.createElement('canvas')
				canvas.width = w
				canvas.height = h
				const ctx = canvas.getContext('2d')
				ctx.imageSmoothingQuality = 'high'
				ctx.drawImage(img, 0, 0, w, h)

				const blob = await this.canvasToBlob(canvas, mime, quality)
				if (!blob) return file

				// 若压缩后反而更大，则返回原图
				if (blob.size > file.size) return file

				return this.blobToFile(blob, file.name)
				// #endif

				// #ifdef MP-WEIXIN || APP-PLUS
				// —— 小程序 / APP：使用 uni.compressImage —— //
				// 允许传入 input 为对象（如 tempFile）或字符串路径
				const srcPath = typeof input === 'string' ?
					input :
					(input?.tempFilePath || input?.path || input?.filePath)

				if (!srcPath) return input

				// uni.compressImage 文档：quality 0-100，部分端支持 width/height
				const q = Math.max(1, Math.min(100, Math.round(quality * 100)))

				// 尝试带上 width/height（端上不支持也会忽略）
				const compressed = await new Promise((resolve, reject) => {
					uni.compressImage({
						src: srcPath,
						quality: q,
						width: maxWidth,
						height: maxHeight,
						success: (res) => resolve(res.tempFilePath || res.apFilePath || res.target ||
							res.path),
						fail: (err) => reject(err)
					})
				})
				return compressed
				// #endif
			},
		},
		onLoad(option) {
			this.form.inspectionPoint = option.inspectionPoint || ''
			this.form.inspectionRequirements = option.inspectionRequirements || ''
			this.form.inspectionPointId = option.inspectionPointId || ''
		},
		mounted() {
			this.checkMobileBrowser()
		}
	}
</script>



<style lang="scss">
	page {
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		background-color: #fff;
		height: 90vh;
		/* 使页面高度占满整个视口 */
	}

	.container {
		flex: 1;
		/* 让 container 占满剩余空间 */
		display: flex;
		flex-direction: column;
		/* 设置为列方向 */
	}

	.example {
		flex: 1;
		/* 让 example 占满 container 的剩余空间 */
		display: flex;
		flex-direction: column;
		/* 设置为列方向，确保子元素垂直排列 */
		padding: 15px;
		background-color: #fff;
	}

	// 样式沉底
	.button-group {
		position: fixed;
		bottom: 20px;
		left: 0;
		/* 使用 margin-top: auto 来将按钮组推到 example 容器的底部 */
		display: flex;
		width: 100%;
		justify-content: space-around;
	}

	.button-group button {
		flex: 1;
		background: #fff;
		color: #000;
		/* 使按钮平分可用空间 */
		/* 可能还需要设置一些其他的样式来确保按钮看起来正确，比如 text-align, padding 等 */
	}
</style>