<template>
	<!-- 页面主体内容 -->
	<view class="common_page adffc" :style="{'min-height':h+'px', 'padding-top':mt+'px'}">
		<cus-header title="申领社会实践记录" bgColor="#FFFFFF"></cus-header>
		<!-- 证书部分 -->
		<view class="prove adffcac">
			<image class="prove-logo" mode="widthFix" :src="certificateData.logoUrl"></image>
			<image class="prove-title" mode="widthFix" :src="certificateData.titleUrl"></image>
			<image class="prove-line" mode="widthFix" :src="certificateData.lineUrl"></image>
			<view class="prove-no">证书编号：{{ certificateData.certificateNumber }}</view>
			<view class="prove-info">
				<view class="prove-info-pre adf">
					<view class="prove-info-pre-left">
						<view class="prove-info-pre-left-text">义工服务姓名：</view>
						<view class="prove-info-pre-left-tip">Volunteer service Name</view>
					</view>
					<view class="prove-info-pre-right">{{ certificateData.memberName }}</view>
				</view>
				<view class="prove-info-pre adf">
					<view class="prove-info-pre-left">
						<view class="prove-info-pre-left-text space">所属学校：</view>
						<view class="prove-info-pre-left-tip">Affiliated school</view>
					</view>
					<view class="prove-info-pre-right">{{ certificateData.currentSchool }}</view>
				</view>
				<view class="prove-info-pre adf">
					<view class="prove-info-pre-left">
						<view class="prove-info-pre-left-text space">证件类型：</view>
						<view class="prove-info-pre-left-tip">Type of ID</view>
					</view>
					<view class="prove-info-pre-right">{{ certificateData.idType }}</view>
				</view>
				<view class="prove-info-pre adf">
					<view class="prove-info-pre-left">
						<view class="prove-info-pre-left-text space">证件号码：</view>
						<view class="prove-info-pre-left-tip">IdCard No</view>
					</view>
					<view class="prove-info-pre-right">{{ certificateData.idCard }}</view>
				</view>
				<view class="prove-info-pre adf">
					<view class="prove-info-pre-left">
						<view class="prove-info-pre-left-text">义工服务时长：</view>
						<view class="prove-info-pre-left-tip">Volunteer service Time</view>
					</view>
					<view class="prove-info-pre-right">{{ certificateData.volunteerHours }}小时</view>
				</view>
			</view>
			<view class="prove-memo">
				您累计参与了 <span>{{ certificateData.welfareCount }}</span> 场活动，捐赠了 <span>{{ certificateData.loveValue }}</span> 爱心值。向您践行志愿精神，为社会进步奉献力量致以最崇高的敬意。
			</view>
			<view class="prove-memo" style="margin-top: 30rpx;">特发此证！</view>
			<view class="prove-bottom">
				<view class="prove-bottom-pre">证明单位：{{ certificateData.issuer }}</view>
				<view class="prove-bottom-pre">发证日期：{{ certificateData.createDate }}</view>
			</view>
			<image class="prove-seal" mode="widthFix" :src="certificateData.sealUrl"></image>
		</view>
		<!-- 列表部分 -->
		<view class="list">
			<view class="list-box" v-for="(item,index) in activityList" :key="index">
				<view class="title">{{ item.activityName||'' }}</view>
				<view class="content adf">
					<view class="right">
						<view class="right-pre adf">
							<view class="tip">活动时间：</view>
							<view class="text">{{ item.activityStartTime||'' }}</view>
						</view>
						<view class="right-pre adf">
							<template v-if="item.activityLimit==2">
								<view class="tip">专享券贡献：</view>
								<view class="text">{{ item.valueLimit||0 }}张</view>
							</template>
							<template v-else>
								<view class="tip">爱心值贡献：</view>
								<view class="text">{{ item.valueLimit||0 }}</view>
							</template>
						</view>
						<view class="right-pre adf">
							<view class="tip">义工时长：</view>
							<view class="text">{{ item.serviceHours||0 }}小时</view>
						</view>
						<view class="right-pre adf">
							<view class="tip">公益合作：</view>
							<view class="text">{{ item.channelName||'' }}</view>
						</view>
					</view>
				</view>
			</view>
		</view>
		<!-- 下载按钮 -->
		<view class="btn" @click="handleDownload">
			{{ isLoading ? '生成中...' : '下载' }}
		</view>
	</view>
	<canvas canvas-id="pdf-canvas" :style="'width:' + canvasWidth + 'px; height:' + canvasHeight + 'px; position: fixed; left: -9999px; top: -9999px;'"></canvas>
</template>

<script setup>
	import CusHeader from '@/components/CusHeader/index.vue'
	import { onLoad } from '@dcloudio/uni-app'
	import { ref, computed, getCurrentInstance } from 'vue'
	const { proxy } = getCurrentInstance()

	// 页面数据，实际项目中这些数据应该是动态获取的
	const certificateData = ref({
		logoUrl: 'https://oss.familydaf.cn/sxsnfile/20251218/b198be43fefc4d9aa11176a79dd82b89.png',
		titleUrl: 'https://oss.familydaf.cn/sxsnfile/20251218/92165c10788943b3a63e922dc4646ad9.png',
		lineUrl: 'https://oss.familydaf.cn/sxsnfile/20251218/d1a2627aed1c477883f6b4a35d26434f.png',
		backgroundUrl: 'https://oss.familydaf.cn/sxsnfile/20251218/f66a2b0f890542048731701396420697.png',
		sealUrl: 'https://oss.familydaf.cn/sxsnfile/20251218/6eb067ae1d19451aaffe0118d214f053.png',
		certificateNumber: '',
		memberName: '',
		currentSchool: '',
		idType: '居民身份证',
		idCard: '',
		volunteerHours: 0,
		welfareCount: 0,
		loveValue: 0,
		issuer: '善行少年服务基金会',
		createDate: ''
	});

	const activityList = ref([]);

	const isLoading = ref(false);
	const canvasWidth = ref(0);
	const canvasHeight = ref(0);
	
	// rpx转px的工具函数
	const rpxToPx = (rpx) => {
		const screenWidth = uni.getSystemInfoSync().windowWidth;
		return (screenWidth / 750) * rpx;
	};
	
	// 文本换行绘制函数
	const drawWrappedText = (ctx, text, x, y, maxWidth, lineHeight) => {
		const words = text.split('');
		let line = '';
		let currentY = y;

		for (let n = 0; n < words.length; n++) {
			const testLine = line + words[n];
			const metrics = ctx.measureText(testLine);
			const testWidth = metrics.width;
			if (testWidth > maxWidth && n > 0) {
				ctx.fillText(line, x, currentY);
				line = words[n];
				currentY += lineHeight;
			} else {
				line = testLine;
			}
		}
		ctx.fillText(line, x, currentY);
		return currentY - y + lineHeight; // 返回这段文本所占的总高度
	};
	
	// 获取网络图片信息，返回一个Promise
	const getImageInfo = (url) => {
		return new Promise((resolve, reject) => {
			uni.getImageInfo({
				src: url,
				success: (res) => resolve(res),
				fail: (err) => reject(err),
			});
		});
	};
	
	// 主下载处理函数
	const handleDownload = async () => {
	    if (isLoading.value) return;
	    isLoading.value = true;
	    uni.showLoading({ title: '正在生成图片...', mask: true });
	
	    try {
	        // 1. 动态计算Canvas尺寸
	        const proveHeight = rpxToPx(945);
	        const pagePaddingTop = rpxToPx(20); // prove-margin-top
	        const pagePaddingBottom = rpxToPx(184); // 页面底部到按钮的距离
	
	        // 估算一个列表项的高度: 上下padding(36*2) + 标题(32) + 标题margin(30) + 4行内容(4*50) + 列表项间距(20)
	        // 这里的 4*50 是一个估算值，基于你的CSS
	        const singleListHeight = rpxToPx(36 * 2 + 32 + 30 + (20 + 24) * 4 + 20); // 估算每行高度(margin-top + font-size)
	        
	        canvasWidth.value = uni.getSystemInfoSync().windowWidth;
	        // 总高度 = 证书高度 + 列表总高度 + 页面顶部边距 + 底部空白区域
	        canvasHeight.value = proveHeight + (singleListHeight * activityList.value.length) + pagePaddingTop + pagePaddingBottom;
	
	        // 2. 预加载所有图片
	        const imagesToLoad = [
	            certificateData.value.backgroundUrl,
	            certificateData.value.logoUrl,
	            certificateData.value.titleUrl,
	            certificateData.value.lineUrl,
	            certificateData.value.sealUrl
	        ];
	        const imageInfos = await Promise.all(imagesToLoad.map(url => getImageInfo(url)));
	        
	        const [
	            bgImg, logoImg, titleImg, lineImg, sealImg
	        ] = imageInfos.map(info => info.path);
	
	        // 3. 开始绘制
	        const ctx = uni.createCanvasContext('pdf-canvas', proxy); // 传入 proxy
	        
	        // 绘制白色背景
	        ctx.setFillStyle('#F5F5F5');
	        ctx.fillRect(0, 0, canvasWidth.value, canvasHeight.value);
	
	        let currentY = rpxToPx(20); // 从顶部20rpx的margin开始
	
	        // ---- 3.1 绘制证书 (这部分逻辑基本正确，无需大改) ----
	        const proveX = 0; 
	        const proveWidth = canvasWidth.value;
	
	        // 绘制证书背景
	        ctx.drawImage(bgImg, proveX, currentY, proveWidth, proveHeight);
	        
	        // 绘制Logo
	        ctx.drawImage(logoImg, rpxToPx(72), currentY + rpxToPx(58), rpxToPx(133), rpxToPx(40));
	        // 绘制标题
	        ctx.drawImage(titleImg, (proveWidth - rpxToPx(363)) / 2, currentY + rpxToPx(101), rpxToPx(363), rpxToPx(40));
	        // 绘制线条
	        ctx.drawImage(lineImg, (proveWidth - rpxToPx(400)) / 2, currentY + rpxToPx(101 + 40 + 7), rpxToPx(400), rpxToPx(5));
	        
	        // 绘制证书编号
	        ctx.setFontSize(rpxToPx(20));
	        ctx.setFillStyle('#9F793F');
	        ctx.setTextAlign('center');
	        ctx.fillText(`证书编号：${certificateData.value.certificateNumber}`, proveWidth / 2, currentY + rpxToPx(190));
	        
	        // 绘制个人信息
	        ctx.setTextAlign('left');
	        const infoStartX = (proveWidth - rpxToPx(135 + 188)) / 2;
	        const infoStartY = currentY + rpxToPx(244);
	        const infoItems = [
	            { label: '义工服务姓名：', value: certificateData.value?.memberName||'', tip: 'Volunteer service Name' },
	            { label: '所属学校：', value: certificateData.value?.currentSchool||'', tip: 'Affiliated school' },
	            { label: '证件类型：', value: certificateData.value?.idType, tip: 'Type of ID' },
	            { label: '证件号码：', value: certificateData.value?.idCard||'', tip: 'IdCard No' },
	            { label: '义工服务时长：', value: `${certificateData.value?.volunteerHours||0}小时`, tip: 'Volunteer service Time' }
	        ];
	        infoItems.forEach((item, index) => {
	            const itemY = infoStartY + index * rpxToPx(40);
	            ctx.setFillStyle('#252525');
	            ctx.setFontSize(rpxToPx(17));
	            ctx.fillText(item.label, infoStartX, itemY);
	            ctx.setFontSize(rpxToPx(10));
	            ctx.fillText(item.tip, infoStartX, itemY + rpxToPx(13));
	            
	            const valueX = infoStartX + rpxToPx(135);
	            ctx.setFontSize(rpxToPx(17));
	            ctx.fillText(item.value, valueX, itemY);
	            
	            ctx.setStrokeStyle('#DDCEAF');
	            ctx.setLineWidth(rpxToPx(1)); // 1px的线在高清屏下更清晰
	            ctx.beginPath();
	            ctx.moveTo(valueX, itemY + rpxToPx(8));
	            ctx.lineTo(valueX + rpxToPx(188), itemY + rpxToPx(8));
	            ctx.stroke();
	        });
	        
	        // 绘制memo
	        ctx.setFontSize(rpxToPx(20));
	        const memoY = currentY + rpxToPx(500);
	        const memoLineHeight = rpxToPx(31);
	        const memoStartX = rpxToPx(80);
	        const memoMaxWidth = proveWidth - rpxToPx(160); // 左右边距各80rpx
	        
	        const memoSegments = [
	            { text: `您累计参与了 `, color: '#252525' },
	            { text: `${certificateData.value.welfareCount}`, color: '#C9A771' },
	            { text: ` 场活动，捐赠了 `, color: '#252525' },
	            { text: `${certificateData.value.loveValue}`, color: '#C9A771' },
	            { text: ` 爱心值。向您践行志愿精神，为社会进步奉献力量致以最崇高的敬意。`, color: '#252525' }
	        ];
	        
	        let currentMemoX = memoStartX;
	        let currentMemoY = memoY;
	        ctx.setTextAlign('left'); // 确保对齐方式正确
	        
	        for (const segment of memoSegments) {
	            ctx.setFillStyle(segment.color);
	            const chars = segment.text.split('');
	            for (const char of chars) {
	                const charWidth = ctx.measureText(char).width;
	                // 如果当前字符加上后会超出最大宽度，则换行
	                if (currentMemoX + charWidth > memoStartX + memoMaxWidth) {
	                    currentMemoX = memoStartX; // X坐标重置
	                    currentMemoY += memoLineHeight; // Y坐标下移一行
	                }
	                ctx.fillText(char, currentMemoX, currentMemoY);
	                currentMemoX += charWidth; // 更新X坐标
	            }
	        }
	
	        ctx.fillText('特发此证！', rpxToPx(80), currentY + rpxToPx(600));
	
	        // 绘制证明单位和日期
	        ctx.setFontSize(rpxToPx(17));
	        ctx.fillText(`证明单位：${certificateData.value.issuer}`, rpxToPx(80), currentY + rpxToPx(700));
	        ctx.fillText(`发证日期：${certificateData.value.createDate}`, rpxToPx(80), currentY + rpxToPx(730));
	
	        // 绘制印章
	        ctx.drawImage(sealImg, proveWidth - rpxToPx(73 + 131), currentY + proveHeight - rpxToPx(69 + 131), rpxToPx(131), rpxToPx(131));
	        
	        currentY += proveHeight; // 更新Y坐标到证书底部
	
	        // ---- 3.2 绘制活动列表 ----
	        for (const item of activityList.value) {
	            currentY += rpxToPx(20); // 列表项间距
	            
	            const boxX = rpxToPx(24);
	            const boxWidth = canvasWidth.value - rpxToPx(48);
	            
	            let itemContentHeight = 0; // 动态计算每个item的高度
	            
	            // 预计算高度
	            const titleHeight = rpxToPx(32);
	            const contentPaddingTop = rpxToPx(36);
	            const titleMarginBottom = rpxToPx(30);
	            const contentPaddingBottom = rpxToPx(36);
	            const rightItemLineHeight = rpxToPx(50); // 估算行高（包含margin）
	            itemContentHeight = contentPaddingTop + titleHeight + titleMarginBottom + (rightItemLineHeight * 4) + contentPaddingBottom;
	
	            // 绘制列表项背景
	            ctx.setFillStyle('#FFFFFF');
	            ctx.setShadow(0, rpxToPx(5), rpxToPx(10), 'rgba(0,0,0,0.05)'); // 可选：添加阴影使其更逼真
	            ctx.fillRect(boxX, currentY, boxWidth, itemContentHeight);
	            ctx.setShadow(0, 0, 0, 'rgba(0,0,0,0)'); // 清除阴影
	
	            const contentPaddingX = rpxToPx(20);
	            let itemInnerY = currentY + contentPaddingTop;
	            
	            // 绘制标题
	            ctx.setFontSize(rpxToPx(32));
	            ctx.setFillStyle('#252525');
	            ctx.font = `bold ${rpxToPx(32)}px sans-serif`;
	            ctx.fillText(item.activityName || '', boxX + contentPaddingX, itemInnerY + rpxToPx(16)); // Y微调
	            
	            itemInnerY += titleHeight + titleMarginBottom;
	
	            // 绘制右侧文字
	            const textStartX = boxX + contentPaddingX;
	            ctx.setFontSize(rpxToPx(24));
	            ctx.font = `normal ${rpxToPx(24)}px sans-serif`;
	
	            const rightItems = [
	                { tip: '活动时间：', text: item.activityStartTime || '' },
	                { tip: `${item.activityLimit == 2 ? '专享券贡献：' : '爱心值贡献：'}`, text: `${item.valueLimit || 0}${item.activityLimit == 2 ? '张' : ''}` },
	                { tip: '义工时长：', text: `${item.serviceHours || 0}小时` },
	                { tip: '公益合作：', text: item.channelName || '' },
	            ];
	            
	            rightItems.forEach((rightItem, idx) => {
	                const textY = itemInnerY + (idx * rightItemLineHeight);
	                ctx.setFillStyle('#676775');
	                ctx.fillText(rightItem.tip, textStartX, textY);
	                
	                const tipWidth = ctx.measureText(rightItem.tip).width;
	                ctx.setFillStyle('#252525');
	                ctx.font = `bold ${rpxToPx(24)}px sans-serif`;
	                // 绘制文本，这里不使用换行函数，因为内容一般不长
	                ctx.fillText(rightItem.text, textStartX + tipWidth, textY);
	                ctx.font = `normal ${rpxToPx(24)}px sans-serif`; // 重置字体
	            });
	            
	            currentY += itemContentHeight;
	        }
	        
	        // 4. 执行绘制并生成图片
	        ctx.draw(false, () => {
	            uni.canvasToTempFilePath({
	                canvasId: 'pdf-canvas',
	                destWidth: canvasWidth.value * 2, // 提高图片清晰度
	                destHeight: canvasHeight.value * 2,
	                fileType: 'png',
	                quality: 1,
	                success: (res) => {
	                    // 5. 保存图片到相册
	                    uni.saveImageToPhotosAlbum({
	                        filePath: res.tempFilePath,
	                        success: () => {
	                            uni.showToast({ title: '已保存到相册', icon: 'success' });
	                        },
	                        fail: (err) => {
								console.log(err);
	                            if (err.errMsg && err.errMsg.includes('auth deny')) {
	                                uni.showModal({
	                                    title: '提示',
	                                    content: '需要您授权保存相册',
	                                    showCancel: false,
	                                    success: () => uni.openSetting()
	                                });
	                            } else {
	                                uni.showToast({ title: '保存失败，请稍后重试', icon: 'none' });
	                            }
	                        }
	                    });
	                },
	                fail: (err) => {
	                    console.error('canvasToTempFilePath failed:', err);
	                    uni.showToast({ title: '图片生成失败', icon: 'none' });
	                },
	                complete: () => {
	                    uni.hideLoading();
	                    isLoading.value = false;
	                }
	            }, proxy); // 传入 proxy
	        });
	
	    } catch (error) {
	        console.error('handleDownload error:', error);
	        uni.hideLoading();
	        isLoading.value = false;
	        uni.showToast({
	            title: '生成失败，请检查网络或资源链接', // 提示更具体
	            icon: 'none'
	        });
	    }
	};
	onLoad((options)=>{
		proxy.$api.get(`/core/social/practice/record/${options?.id||''}`).then(({data:res})=>{
			if(res.code!==0) return proxy.$showToast(res.msg)
			certificateData.value = {...certificateData.value,...res.data};
			certificateData.value.idCard = certificateData.value.idCard&&certificateData.value.idCard.replace(/^(\d{6})(\d{8})(\d{3}[\dX])$/i,'$1********$3');
			activityList.value = res.data?.activityVos||[];
		})
	})
</script>

<style scoped lang="scss">
	.common_page {
		background-color: #F5F5F5;
		padding: 0 0 184rpx;
		
		.prove{
			margin: 20rpx 24rpx 0; // 改为外边距，避免影响全屏截图
			width: calc(100% - 40rpx);
			background: url('https://oss.familydaf.cn/sxsnfile/20251218/f66a2b0f890542048731701396420697.png') no-repeat;
			background-size: 100% 100%;
			height: 945rpx;
			position: relative;
			&-logo{
				width: 133rpx;
				position: absolute;
				top: 58rpx;
				left: 72rpx;
			}
			&-title{
				width: 363rpx;
				margin-top: 101rpx;
			}
			&-line{
				width: 400rpx;
				margin-top: 7rpx;
			}
			&-seal{
				width: 131rpx;
				border-radius: 50%;
				position: absolute;
				bottom: 69rpx;
				right: 73rpx;
			}
		
			&-no{
				font-family: SourceHanSerifSC, SourceHanSerifSC;
				font-weight: bold;
				font-size: 20rpx;
				color: #9F793F;
				line-height: 20rpx;
				letter-spacing: 1px;
				margin-top: 9rpx;
			}
			
			&-info{
				margin-top: 27rpx;
				overflow: auto;
				&-pre{
					margin-top: 22rpx;
					&-left{
						width: 135rpx;
						&-text{
							font-family: PingFangSC, PingFang SC;
							font-weight: 400;
							font-size: 17rpx;
							color: #252525;
							line-height: 17rpx;
							letter-spacing: 1px;
							&.space{
								letter-spacing: 10rpx;
							}
						}
						&-tip{
							font-family: PingFangSC, PingFang SC;
							font-weight: 400;
							font-size: 10rpx;
							color: #252525;
							line-height: 10rpx;
							margin-top: 3rpx;
						}
					}
					&-right{
						width: 188rpx;
						font-family: PingFangSC, PingFang SC;
						font-weight: 400;
						font-size: 17rpx;
						color: #252525;
						line-height: 17rpx;
						padding-bottom: 8rpx;
						border-bottom: 2rpx solid #DDCEAF;
					}
				}
			}
			&-memo{
				width: 100%;
				padding: 0 80rpx;
				box-sizing: border-box;
				margin-top: 79rpx;
				font-family: PingFangSC, PingFang SC;
				font-weight: 400;
				font-size: 20rpx;
				color: #252525;
				line-height: 31rpx;
				label{ // canvas无法直接渲染span，颜色在js中处理
					color: #C9A771;
					margin: 0 5rpx;
				}
			}
			&-bottom{
				width: 100%;
				padding: 0 80rpx;
				box-sizing: border-box;
				margin-top: 89rpx;
				overflow: hidden;
				&-pre{
					margin-top: 16rpx;
					font-family: PingFangSC, PingFang SC;
					font-weight: 400;
					font-size: 17rpx;
					color: #252525;
					line-height: 20rpx;
				}
			}
		}
		
		.list{
			margin: 0 24rpx;
			&-box{
				margin-top: 20rpx;
				padding: 36rpx 20rpx;
				background: #FFFFFF;
				.title{
					font-family: PingFang-SC, PingFang-SC;
					font-weight: bold;
					font-size: 32rpx;
					color: #252525;
					// line-height: 32rpx;
				}
				.content{
					margin-top: 30rpx;
					// .left{
					// 	width: 182rpx;
					// 	height: 240rpx;
					// 	image{
					// 		width: 100%;
					// 		height: 100%;
					// 	}
					// }
					.right{
						width: 100%;
						// width: calc(100% - 182rpx);
						// padding-left: 20rpx;
						// box-sizing: border-box;
						&-pre{
							margin-top: 20rpx;
							&:first-child{
								margin-top: 12rpx;
							}
							.tip{
								width: 150rpx;
								font-family: PingFangSC, PingFang SC;
								font-weight: 400;
								font-size: 24rpx;
								color: #676775;
							}
							.text{
								width: calc(100% - 150rpx);
								font-family: PingFang-SC, PingFang-SC;
								font-weight: bold;
								font-size: 24rpx;
								color: #252525;
							}
						}
					}
				}
			}
		}
		
		.btn{
			width: calc(100% - 210rpx);
			height: 90rpx;
			background: #B7F358;
			border-radius: 45rpx;
			font-family: PingFang-SC, PingFang-SC;
			font-weight: bold;
			font-size: 32rpx;
			color: #151B29;
			line-height: 90rpx;
			text-align: center;
			letter-spacing: 2rpx;
			position: fixed;
			left: 105rpx;
			bottom: 64rpx;
			z-index: 10;
		}
	}
</style>