<template>
	<scroll-view class="page" scroll-y :scroll-with-animation="false" :enable-flex="true"
		:scroll-enabled="!isSigning">
		<!-- 协议内容 -->
		<view class="section">
			<view class="doc-title">{{ docTitle }}</view>
			<rich-text class="doc-body" :nodes="docContent" />
		</view>

		<!-- 收入金额（仅income类型） -->
		<view class="section" v-if="signType === 'income'">
			<view class="form-label">请填写您的个人月可支配收入（元）</view>
			<view class="amount-wrap">
				<text class="amount-prefix">¥</text>
				<u-input v-model="incomeAmount" type="number" placeholder="请输入金额" border="none" />
			</view>
		</view>

		<!-- 签名区域 -->
		<view class="section">
			<view class="sign-label">请在下方签名确认</view>
			<view class="canvas-wrap">
				<canvas canvas-id="signCanvas" class="sign-canvas"
					@touchstart="onTouchStart" @touchmove.stop.prevent="onTouchMove" @touchend="onTouchEnd" />
				<text v-if="!hasSigned" class="canvas-placeholder">请在此处签名</text>
			</view>
			<view class="sign-actions">
				<view class="clear-btn" @tap="clearSign">清除重签</view>
			</view>
		</view>

		<!-- 底部按钮 -->
		<view class="btn-wrap">
			<u-button text="确认签署" :loading="submitting" @click="confirmSign" color="#0E63E3" size="large" />
		</view>
	</scroll-view>
</template>

<script setup>
import { ref } from 'vue'
import { onLoad, onReady } from '@dcloudio/uni-app'
import { get, post, upload } from '@/utils/request.js'

const signType = ref('')
const docTitle = ref('')
const docContent = ref('')
const incomeAmount = ref('')
const hasSigned = ref(false)
const submitting = ref(false)
const isSigning = ref(false)

let ctx = null
let points = []

const titleMap = {
	income: '个人可支配收入声明',
	privacy: '个人信息处理同意书',
	promise: '声明与承诺'
}

onLoad((options) => {
	signType.value = options.type || 'privacy'
	uni.setNavigationBarTitle({ title: titleMap[signType.value] || '签署协议' })
	loadContent()
})

onReady(() => {
	ctx = uni.createCanvasContext('signCanvas')
	ctx.setStrokeStyle('#333')
	ctx.setLineWidth(3)
	ctx.setLineCap('round')
	ctx.setLineJoin('round')
})

const loadContent = async () => {
	try {
		const key = 'sign_' + signType.value
		const res = await get('/api/content', { key })
		docTitle.value = res.data.title || ''
		docContent.value = res.data.content || ''
	} catch (e) {}
}

const onTouchStart = (e) => {
	isSigning.value = true
	const touch = e.touches[0]
	points = [{ x: touch.x, y: touch.y }]
	ctx.beginPath()
	ctx.moveTo(touch.x, touch.y)
}

const onTouchMove = (e) => {
	const touch = e.touches[0]
	points.push({ x: touch.x, y: touch.y })
	ctx.lineTo(touch.x, touch.y)
	ctx.stroke()
	ctx.draw(true)
	ctx.beginPath()
	ctx.moveTo(touch.x, touch.y)
	if (!hasSigned.value) hasSigned.value = true
}

const onTouchEnd = () => {
	points = []
	isSigning.value = false
}

const clearSign = () => {
	ctx.clearRect(0, 0, 9999, 9999)
	ctx.draw()
	hasSigned.value = false
}

const confirmSign = async () => {
	if (!hasSigned.value) {
		return uni.showToast({ title: '请先签名', icon: 'none' })
	}
	if (signType.value === 'income' && (!incomeAmount.value || Number(incomeAmount.value) <= 0)) {
		return uni.showToast({ title: '请填写有效的收入金额', icon: 'none' })
	}

	submitting.value = true
	try {
		// 1. 导出 canvas 为图片
		const tempPath = await new Promise((resolve, reject) => {
			uni.canvasToTempFilePath({
				canvasId: 'signCanvas',
				fileType: 'png',
				success: (res) => resolve(res.tempFilePath),
				fail: reject
			})
		})

		// 2. 上传签名图到 COS
		const uploadRes = await upload('/api/mp/upload', { filePath: tempPath, name: 'file' })
		if (!uploadRes.data || !uploadRes.data.url) {
			throw { msg: '签名图上传失败' }
		}
		const signImage = uploadRes.data.url

		// 3. 调后端合成接口
		const params = {
			type: signType.value,
			signImage,
			amount: signType.value === 'income' ? incomeAmount.value : undefined
		}
		const res = await post('/api/mp/sign', params)

		// 4. 通过事件把结果传回 myinfo 页面
		uni.$emit('signResult', {
			type: signType.value,
			url: res.data.url,
			amount: signType.value === 'income' ? incomeAmount.value : undefined
		})

		uni.showToast({ title: '签署成功', icon: 'success' })
		setTimeout(() => uni.navigateBack(), 1000)
	} catch (e) {
		if (e && e.msg) uni.showToast({ title: e.msg, icon: 'none' })
	} finally {
		submitting.value = false
	}
}
</script>

<style lang="scss" scoped>
.page {
	height: 100vh;
	background: #f4f4f5;
	padding: 24rpx;
	padding-bottom: 140rpx;
}

.section {
	background: #fff;
	margin-bottom: 24rpx;
	border-radius: 10rpx;
	padding: 32rpx;
	border: 1rpx solid #ebeef5;
}

.doc-title {
	font-size: 32rpx;
	font-weight: 600;
	text-align: center;
	margin-bottom: 32rpx;
	color: #222;
}

.doc-body {
	font-size: 28rpx;
	color: #555;
	line-height: 1.8;
}

.form-label {
	font-size: 28rpx;
	color: #333;
	font-weight: 600;
	margin-bottom: 16rpx;
}

.amount-wrap {
	display: flex;
	align-items: center;
	border: 1rpx solid #ddd;
	border-radius: 12rpx;
	overflow: hidden;
	gap: 12rpx;
}

.amount-prefix {
	padding: 20rpx 24rpx;
	font-size: 28rpx;
	color: #999;
	background: #f8f8f8;
}

.sign-label {
	font-size: 28rpx;
	color: #333;
	font-weight: 600;
	margin-bottom: 16rpx;
}

.canvas-wrap {
	position: relative;
	border: 1rpx solid #ddd;
	border-radius: 12rpx;
	overflow: hidden;
	margin-bottom: 16rpx;
}

.sign-canvas {
	width: 100%;
	height: 300rpx;
	background: #fff;
}

.canvas-placeholder {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	color: #ccc;
	font-size: 32rpx;
	pointer-events: none;
}

.sign-actions {
	display: flex;
	justify-content: flex-end;
}

.clear-btn {
	padding: 12rpx 32rpx;
	border: 1rpx solid #ccc;
	border-radius: 12rpx;
	font-size: 26rpx;
	color: #666;

	&:active {
		border-color: #0e63e3;
		color: #0e63e3;
	}
}

.btn-wrap {
	position: fixed;
	bottom: 0;
	left: 0;
	right: 0;
	background: #fff;
	padding: 20rpx 32rpx;
	padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
	box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.06);
	z-index: 100;
}
</style>
