<template>
	<view class="confirm-popup-root" v-if="visible" @click.stop.prevent>
		<view class="popup-mask" @click="handleClose"></view>
		<view class="popup-body">
			<view class="popup-header">
				<text class="header-title">订单确认</text>
				<view class="header-actions">
					<text class="preview-btn" @click="previewFullScreen">全屏查看</text>
					<text class="close-btn" @click="handleClose">×</text>
				</view>
			</view>

			<view class="client-info" v-if="clientName">
				<text class="client-label">客户：</text>
				<text class="client-value">{{ clientName }}</text>
			</view>

			<view class="canvas-wrapper">
				<canvas canvas-id="orderConfirmPopupCanvas" class="confirm-canvas"
					:style="{ width: canvasW + 'px', height: canvasH + 'px' }" @click="previewFullScreen">
				</canvas>
			</view>

			<view class="summary-row">
				<text>共 <text class="num-highlight">{{ models.length }}</text> 个型号，合计 <text class="num-highlight">{{
					totalCount }}</text> 支</text>
			</view>

			<view class="popup-footer">
				<button class="cancel-btn" @click="handleClose">取消</button>
				<button class="confirm-btn" :disabled="submitting" @click="handleConfirm">
					{{ submitting ? '提交中...' : '确认下单' }}
				</button>
			</view>
		</view>
	</view>
</template>

<script>
/**
 * 订单确认弹窗 - canvas绘制表格
 * @Author: Trae
 */
import { getImagesByNums } from '../../../api/drawing/drawingFile.js';

export default {
	props: {
		visible: { type: Boolean, default: false },
		models: { type: Array, default: () => [] },
		clientName: { type: String, default: '' },
		submitting: { type: Boolean, default: false }
	},
	data() {
		return {
			canvasW: 345,
			canvasH: 300,
			canvasImagePath: '',
			imagePathMap: {}
		}
	},
	computed: {
		totalCount() {
			return this.models.reduce((sum, m) => sum + (parseInt(m.count) || 0), 0);
		}
	},
	watch: {
		visible(val) {
			if (val) {
				this.$nextTick(() => {
					this.loadImagesAndDraw();
				});
			}
		}
	},
	methods: {
		getCellWidths() {
			return [32, 56, 56, 42, 42, 42, 36, 56, 56, 46];
		},
		getHeaders() {
			return ['序号', '型材型号', '型材名称', '长度', '米重', '壁厚', '支数', '表面名称', '包装方式', '简图'];
		},
		getColumnX(colIndex) {
			const widths = this.getCellWidths();
			let x = 0;
			for (let i = 0; i < colIndex; i++) { x += widths[i]; }
			return x;
		},
		async loadImagesAndDraw() {
			const models = this.models;
			const nums = [...new Set(models.map(m => m.modelNum).filter(Boolean))];
			this.imagePathMap = {};
			if (nums.length > 0) {
				try {
					const res = await getImagesByNums(nums.join(','));
					const imageMap = res.data || {};
					await this.convertBase64ToTempPaths(imageMap);
				} catch (e) {
					console.error('加载简图失败:', e);
				}
			}
			setTimeout(() => { this.drawTable(); }, 150);
		},
		convertBase64ToTempPaths(imageMap) {
			const fs = uni.getFileSystemManager();
			const tasks = Object.entries(imageMap).map(([fnum, base64], i) => {
				return new Promise((resolve) => {
					const tempPath = `${wx.env.USER_DATA_PATH}/drawing_thumb_${i}_${Date.now()}.jpg`;
					fs.writeFile({
						filePath: tempPath,
						data: base64,
						encoding: 'base64',
						success: () => {
							this.imagePathMap[fnum] = tempPath;
							resolve();
						},
						fail: (err) => {
							console.error('写入简图文件失败:', fnum, err);
							resolve();
						}
					});
				});
			});
			return Promise.all(tasks);
		},
		drawTable() {
			const models = this.models;
			if (!models || models.length === 0) return;

			const colWidths = this.getCellWidths();
			const rowHeight = 32;
			const headerHeight = 36;
			const totalWidth = colWidths.reduce((a, b) => a + b, 0);
			const totalHeight = headerHeight + models.length * rowHeight + 4;

			this.canvasW = totalWidth;
			this.canvasH = totalHeight;

			const ctx = uni.createCanvasContext('orderConfirmPopupCanvas', this);

			ctx.setFillStyle('#ffffff');
			ctx.fillRect(0, 0, totalWidth, totalHeight);

			this.drawHeader(ctx, colWidths, headerHeight);
			this.drawRows(ctx, colWidths, models, headerHeight, rowHeight);

			ctx.draw(false, () => {
				setTimeout(() => {
					this.exportCanvasImage(totalWidth, totalHeight);
				}, 300);
			});
		},
		drawHeader(ctx, colWidths, headerHeight) {
			let x = 0;
			ctx.setLineWidth(1);
			ctx.setStrokeStyle('#666666');
			const headers = this.getHeaders();
			headers.forEach((header, i) => {
				ctx.setFillStyle('#f5f5f5');
				ctx.fillRect(x, 0, colWidths[i], headerHeight);
				ctx.setFillStyle('#222222');
				ctx.setFontSize(12);
				ctx.setTextAlign('center');
				ctx.setTextBaseline('middle');
				const cx = x + colWidths[i] / 2;
				ctx.fillText(header, cx, headerHeight / 2);
				ctx.beginPath();
				ctx.moveTo(x, 0);
				ctx.lineTo(x, headerHeight);
				ctx.stroke();
				x += colWidths[i];
			});
			ctx.beginPath();
			ctx.moveTo(x, 0);
			ctx.lineTo(x, headerHeight);
			ctx.stroke();
			ctx.setLineWidth(1.5);
			ctx.beginPath();
			ctx.moveTo(0, 0);
			ctx.lineTo(x, 0);
			ctx.stroke();
			ctx.beginPath();
			ctx.moveTo(0, headerHeight);
			ctx.lineTo(x, headerHeight);
			ctx.stroke();
		},
		drawRows(ctx, colWidths, models, headerHeight, rowHeight) {
			const totalW = colWidths.reduce((a, b) => a + b, 0);
			models.forEach((item, rowIndex) => {
				const y = headerHeight + rowIndex * rowHeight;
				ctx.setFillStyle(rowIndex % 2 === 0 ? '#ffffff' : '#fafafa');
				ctx.fillRect(0, y, totalW, rowHeight);

				ctx.setFillStyle('#333333');
				ctx.setFontSize(10);
				ctx.setTextAlign('center');
				ctx.setTextBaseline('middle');

				const val0 = '' + (rowIndex + 1);
				const val1 = this.truncateText(ctx, item.modelNum != null ? '' + item.modelNum : '', colWidths[1] - 6);
				const val2 = this.truncateText(ctx, item.modelName != null ? '' + item.modelName : '', colWidths[2] - 6);
				const val3 = this.toDecimalStr(item.length, 3);
				const val4 = this.toDecimalStr(item.meterWeight, 3);
				const val5 = this.toDecimalStr(item.wallThickness, 3);
				const val6 = item.count != null ? '' + item.count : '-';
				const val7 = this.truncateText(ctx, '' + (item.surfaceName || ''), colWidths[7] - 6);
				const val8 = this.truncateText(ctx, '' + (item.packName || ''), colWidths[8] - 6);

				const valueTexts = [val0, val1, val2, val3, val4, val5, val6, val7, val8];

				valueTexts.forEach((val, colIndex) => {
					const cx = this.getColumnX(colIndex) + colWidths[colIndex] / 2;
					ctx.fillText('' + val, cx, y + rowHeight / 2);
				});

				const imgPath = this.imagePathMap[item.modelNum];
				if (imgPath) {
					const imgColX = this.getColumnX(9);
					const imgSize = rowHeight - 8;
					const imgX = imgColX + (colWidths[9] - imgSize) / 2;
					const imgY = y + 4;
					ctx.drawImage(imgPath, imgX, imgY, imgSize, imgSize);
				}

				this.drawRowLines(ctx, colWidths, y, rowHeight);
			});

			ctx.setStrokeStyle('#666666');
			ctx.setLineWidth(1.5);
			ctx.beginPath();
			ctx.moveTo(0, headerHeight + models.length * rowHeight);
			ctx.lineTo(totalW, headerHeight + models.length * rowHeight);
			ctx.stroke();
		},
		drawRowLines(ctx, colWidths, y, rowHeight) {
			ctx.setStrokeStyle('#dddddd');
			ctx.setLineWidth(0.5);
			let x = 0;
			colWidths.forEach(w => {
				ctx.beginPath();
				ctx.moveTo(x, y);
				ctx.lineTo(x, y + rowHeight);
				ctx.stroke();
				x += w;
			});
		},
		toDecimalStr(val, digits) {
			if (val === null || val === undefined || val === '') return '-';
			const num = parseFloat(String(val));
			if (isNaN(num)) return '-';
			return num.toFixed(digits);
		},
		truncateText(ctx, text, maxWidth) {
			if (!text) return '';
			const metrics = ctx.measureText ? ctx.measureText(text) : null;
			if (!metrics || metrics.width <= maxWidth) return text;
			let truncated = text;
			while (truncated.length > 0) {
				truncated = truncated.slice(0, -1);
				const m = ctx.measureText(truncated + '…');
				if (m.width <= maxWidth) return truncated + '…';
			}
			return '';
		},
		exportCanvasImage(canvasW, canvasH) {
			uni.canvasToTempFilePath({
				canvasId: 'orderConfirmPopupCanvas',
				destWidth: canvasW * 2,
				destHeight: canvasH * 2,
				success: (res) => {
					this.canvasImagePath = res.tempFilePath;
				},
				fail: () => {
					console.error('canvas导出失败');
				}
			}, this);
		},
		previewFullScreen() {
			if (!this.canvasImagePath) {
				setTimeout(() => {
					if (this.canvasImagePath) {
						this.doPreviewImage();
					} else {
						uni.showToast({ title: '图片生成中，请稍后', icon: 'none' });
					}
				}, 500);
				return;
			}
			this.doPreviewImage();
		},
		doPreviewImage() {
			uni.previewImage({
				urls: [this.canvasImagePath],
				current: 0
			});
		},
		handleConfirm() {
			this.$emit('confirm');
		},
		handleClose() {
			this.$emit('close');
		}
	}
}
</script>

<style scoped>
.confirm-popup-root {
	position: fixed;
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
}

.popup-mask {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: rgba(0, 0, 0, 0.5);
}

.popup-body {
	position: relative;
	width: 680rpx;
	max-height: 90vh;
	background: #fff;
	border-radius: 24rpx;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.popup-header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 30rpx 30rpx 20rpx;
	border-bottom: 1rpx solid #f0f0f0;
}

.header-title {
	font-size: 34rpx;
	font-weight: bold;
	color: #1a1a1a;
}

.header-actions {
	display: flex;
	align-items: center;
	gap: 24rpx;
}

.preview-btn {
	font-size: 26rpx;
	color: #C1001C;
}

.close-btn {
	font-size: 40rpx;
	color: #999;
	line-height: 1;
}

.client-info {
	padding: 16rpx 30rpx;
	background: #fdf6f7;
}

.client-label {
	font-size: 26rpx;
	color: #666;
}

.client-value {
	font-size: 26rpx;
	color: #C1001C;
	font-weight: bold;
}

.canvas-wrapper {
	width: 690rpx;
	max-height: 55vh;
	overflow: auto;
	background: #fff;
	flex-shrink: 1;
}

.confirm-canvas {
	display: block;
	margin: 0 auto;
}

.summary-row {
	padding: 20rpx 30rpx;
	border-top: 1rpx solid #f0f0f0;
	text-align: center;
	font-size: 26rpx;
	color: #666;
}

.num-highlight {
	color: #C1001C;
	font-weight: bold;
	font-size: 28rpx;
}

.popup-footer {
	display: flex;
	gap: 20rpx;
	padding: 20rpx 30rpx 30rpx;
	border-top: 1rpx solid #f0f0f0;
}

.cancel-btn {
	flex: 1;
	height: 80rpx;
	background: #f5f5f5;
	color: #666;
	border-radius: 40rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 28rpx;
	border: none;
}

.confirm-btn {
	flex: 2;
	height: 80rpx;
	background: #C1001C;
	color: #fff;
	border-radius: 40rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 28rpx;
	font-weight: bold;
	border: none;
}

.confirm-btn[disabled] {
	background: #edb3bb;
	color: rgba(255, 255, 255, 0.6);
}
</style>
