<template>
	<view class="signature-box">
		<!-- 签名 -->
		<view class="signature" v-show="showCanvas">
			<canvas class="mycanvas" canvas-id="mycanvas" @touchstart="touchstart" @touchmove="touchmove"
				@touchend="touchend"></canvas>
			<view class="footer">
				<!-- 新增验证提示 -->
				<view v-if="showValidationError" class="validation-error">
					{{validationError}}
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import { pathToBase64 } from '@/util/jssdk_image_tools.js'
	var x = 20;
	var y = 20;
	export default {
		name:'eSignature',
		data() {
			return {
				ctx: '',
				points: [],
				SignatureImg: '',
				hasSign: false,
				isDrawing: false,
				showValidationError: false, // 新增验证错误显示状态
				validationError: '',       // 新增验证错误信息
				strokeCount: 0,            // 新增笔画计数
				lastStrokeTime: null,       // 新增最后笔画时间
				// minSignDuration: 1000,      // 最小签名持续时间(毫秒)
				signStartTime: null,// 签名开始时间
				minStrokes: 5,              // 最小笔画数增加到5
				minSignDuration: 2000,      // 最小签名持续时间增加到2秒
				maxSignDuration: 60000,     // 最大签名持续时间
				minDirectionChanges: 4,     // 最小方向变化次数
				minSignatureWidth: 100,     // 最小签名宽度
				minSignatureHeight: 50,     // 最小签名高度
				strokePoints: [],           // 存储所有笔画点用于分析
				directionChanges: 0,        // 方向变化计数
				lastDirection: null,        // 上一个方向
				boundingBox: {              // 签名边界框
				  minX: Infinity,
				  minY: Infinity,
				  maxX: -Infinity,
				  maxY: -Infinity
				}
			};
		},
		props: {
			showCanvas:{
				type:Boolean
			},
			emptyTxt:{
				type:String,
				default:'签名不能为空'
			},
			validationTxt: {
				type: String,
				default: '签名过于简单，请认真签名'
			}
		},
		emits: ['sendImage','closeCanvas', 'validationError'],
		methods: {
			//清除签名的图片
			obliterate() {
				if (this.SignatureImg) {
					this.SignatureImg = '';
				}
				this.close();
			},
			//关闭并清空画布
			close() {
				this.$emit('closeCanvas');
				this.clear();
			},
			//创建并显示画布
			createCanvas() {
				this.ctx = uni.createCanvasContext('mycanvas', this);
				this.ctx.setFillStyle('#000000')
				this.ctx.fillStyle = '#000000'
				this.ctx.lineWidth = 4;
				this.ctx.lineCap = 'round';
				this.ctx.lineJoin = 'round';
			},
			
			// 修改touchstart方法
			touchstart(e) {
			  this.isDrawing = true;
			  if (!this.signStartTime) {
			    this.signStartTime = Date.now();
			  }
			  
			  let startX = e.changedTouches[0].x;
			  let startY = e.changedTouches[0].y;
			  
			  // 更新边界框
			  this.updateBoundingBox(startX, startY);
			  
			  let startPoint = {
			    X: startX,
			    Y: startY,
			    timestamp: Date.now()
			  };
			  
			  this.points = [startPoint];
			  this.strokePoints.push(startPoint);
			  this.ctx.beginPath();
			  
			  this.strokeCount++;
			  this.lastStrokeTime = Date.now();
			  
			  e.stopPropagation();
			  return false;
			},
			
			// 修改touchmove方法
			touchmove(e) {
			  if (!this.isDrawing) return;
			  
			  let moveX = e.changedTouches[0].x;
			  let moveY = e.changedTouches[0].y;
			  
			  // 更新边界框
			  this.updateBoundingBox(moveX, moveY);
			  
			  let movePoint = {
			    X: moveX,
			    Y: moveY,
			    timestamp: Date.now()
			  };
			  
			  this.points.push(movePoint);
			  this.strokePoints.push(movePoint);
			  
			  // 计算方向变化
			  if (this.points.length >= 2) {
			    this.calculateDirectionChanges();
			  }
			  
			  let len = this.points.length;
			  if (len >= 2) {
			    this.draw();
			  }
			  
			  e.stopPropagation();
			  return false;
			},
			touchend(e) {
				this.isDrawing = false;
				this.points = [];
				
				if (e) {
					e.stopPropagation();
				}
				return false;
			},
			// 新增方法：更新边界框
			updateBoundingBox(x, y) {
			  this.boundingBox.minX = Math.min(this.boundingBox.minX, x);
			  this.boundingBox.minY = Math.min(this.boundingBox.minY, y);
			  this.boundingBox.maxX = Math.max(this.boundingBox.maxX, x);
			  this.boundingBox.maxY = Math.max(this.boundingBox.maxY, y);
			},
			
			// 新增方法：计算方向变化
			calculateDirectionChanges() {
			  const points = this.points;
			  const lastPoint = points[points.length - 2];
			  const currentPoint = points[points.length - 1];
			  
			  // 计算方向向量
			  const dx = currentPoint.X - lastPoint.X;
			  const dy = currentPoint.Y - lastPoint.Y;
			  
			  // 忽略微小移动
			  if (Math.abs(dx) < 2 && Math.abs(dy) < 2) return;
			  
			  // 计算当前方向
			  let currentDirection = null;
			  if (Math.abs(dx) > Math.abs(dy)) {
			    currentDirection = dx > 0 ? 'right' : 'left';
			  } else {
			    currentDirection = dy > 0 ? 'down' : 'up';
			  }
			  
			  // 检查方向变化
			  if (this.lastDirection && this.lastDirection !== currentDirection) {
			    this.directionChanges++;
			  }
			  
			  this.lastDirection = currentDirection;
			},
			//绘制笔迹
			draw() {
				let point1 = this.points[0];
				let point2 = this.points[1];
				this.points.shift();
				this.ctx.moveTo(point1.X, point1.Y);
				this.ctx.lineTo(point2.X, point2.Y);
				this.ctx.stroke();
				this.ctx.draw(true);
				this.hasSign = true;
				this.showValidationError = false; // 有绘制动作时隐藏错误提示
			},
			//清空画布
			// 修改clear方法
			clear() {
			  this.hasSign = false;
			  this.strokeCount = 0;
			  this.signStartTime = null;
			  this.showValidationError = false;
			  this.strokePoints = [];
			  this.directionChanges = 0;
			  this.lastDirection = null;
			  this.boundingBox = {
			    minX: Infinity,
			    minY: Infinity,
			    maxX: -Infinity,
			    maxY: -Infinity
			  };
			  
			  let that = this;
			  uni.getSystemInfo({
			    success: function(res) {
			      let canvasw = res.windowWidth;
			      let canvash = res.windowHeight;
			      that.ctx.clearRect(0, 0, canvasw, canvash);
			      that.ctx.draw(true);
			    }
			  });
			},
			// 验证签名是否符合要求
			
			// 修改validateSignature方法
			validateSignature() {
			  // 1. 检查是否有签名
			  if (!this.hasSign) {
			    this.showValidationError = true;
			    this.validationError = this.emptyTxt;
			    this.$emit('validationError', this.emptyTxt);
			    return false;
			  }
			  
			  // 2. 检查笔画数是否足够
			  if (this.strokeCount < this.minStrokes) {
			    this.showValidationError = true;
			    this.validationError = '签名笔画太少，请完整书写您的姓名';
			    this.$emit('validationError', this.validationError);
			    return false;
			  }
			  
			  // 3. 检查签名时间是否足够
			  const signDuration = Date.now() - this.signStartTime;
			  if (signDuration < this.minSignDuration) {
			    this.showValidationError = true;
			    this.validationError = '签名时间太短，请认真书写';
			    this.$emit('validationError', this.validationError);
			    return false;
			  }
			  
			  // 4. 检查签名时间是否过长
			  if (signDuration > this.maxSignDuration) {
			    this.showValidationError = true;
			    this.validationError = '签名时间过长，请正常书写您的姓名';
			    this.$emit('validationError', this.validationError);
			    return false;
			  }
			  
			  // 5. 检查方向变化次数
			  if (this.directionChanges < this.minDirectionChanges) {
			    this.showValidationError = true;
			    this.validationError = '签名过于简单，请完整书写您的姓名';
			    this.$emit('validationError', this.validationError);
			    return false;
			  }
			  
			  // 6. 检查签名尺寸
			  const signatureWidth = this.boundingBox.maxX - this.boundingBox.minX;
			  const signatureHeight = this.boundingBox.maxY - this.boundingBox.minY;
			  
			  if (signatureWidth < this.minSignatureWidth || signatureHeight < this.minSignatureHeight) {
			    this.showValidationError = true;
			    this.validationError = '签名尺寸过小，请放大书写您的姓名';
			    this.$emit('validationError', this.validationError);
			    return false;
			  }
			  
			  // 7. 检查笔画速度 (防止快速涂鸦)
			  if (this.strokePoints.length > 10) {
			    const firstPoint = this.strokePoints[0];
			    const lastPoint = this.strokePoints[this.strokePoints.length - 1];
			    const totalDistance = this.calculateTotalDistance();
			    const totalTime = lastPoint.timestamp - firstPoint.timestamp;
			    const avgSpeed = totalDistance / totalTime; // 像素/毫秒
			    
			    if (avgSpeed > 0.5) { // 经验值，可根据实际情况调整
			      this.showValidationError = true;
			      this.validationError = '签名速度过快，请认真书写';
			      this.$emit('validationError', this.validationError);
			      return false;
			    }
			  }
			  
			  // 验证通过
			  this.showValidationError = false;
			  this.$emit('validationError', '');
			  return true;
			},
			// 新增方法：计算签名总距离
			calculateTotalDistance() {
			  let totalDistance = 0;
			  for (let i = 1; i < this.strokePoints.length; i++) {
			    const prev = this.strokePoints[i - 1];
			    const curr = this.strokePoints[i];
			    const dx = curr.X - prev.X;
			    const dy = curr.Y - prev.Y;
			    totalDistance += Math.sqrt(dx * dx + dy * dy);
			  }
			  return totalDistance;
			},
			//完成绘画并保存到本地
			finish() {
				// 先验证签名
				if (!this.validateSignature()) {
					return;
				}
				
				let that = this;
				uni.canvasToTempFilePath({
						canvasId: 'mycanvas',
						success: function(res) {
							if(!res || !res.tempFilePath) {
								that.SignatureImg = res.tempFilePath;
								that.$emit('sendImage', that.SignatureImg);
								that.close();
							}else{
								pathToBase64(res.tempFilePath).then(re => {
									that.SignatureImg = re;
									that.$emit('sendImage', that.SignatureImg);
									that.close();
								})
							}
						}
					}
				);
			}
		},
		mounted() {
			this.createCanvas();
			// 在组件挂载时添加额外的事件监听
			// #ifdef H5
			const canvas = document.querySelector('.mycanvas');
			if (canvas) {
			  canvas.addEventListener('touchmove', (e) => {
				if (this.isDrawing) {
				  e.preventDefault();
				}
			  }, { passive: false });
			}
			// #endif
		}
	};
</script>

<style lang="scss" scoped>
	.signature-box {
		display: flex;
		flex-direction: column;
		align-items: center;
		
		//签名模块
		.signature {
			touch-action: none;
			width:100%;
			
			//canvas
			.mycanvas {
				touch-action: none;
				width: 100%;
				height: 500rpx;
				background-color: #f9f9f9;
				border-radius: 5rpx;
				border: 2rpx dashed #e8e8e8;
			}
			
			//底部按钮
			.footer {
				display: flex;
				justify-content: space-around;
				flex-direction: column;
				align-items: center;
				margin-top: 20rpx;
				
				.validation-error {
				  color: #f56c6c;
				  font-size: 24rpx;
				  margin-top: 10rpx;
				  text-align: center;
				  padding: 10rpx 20rpx;
				  background-color: #fef0f0;
				  border-radius: 8rpx;
				  border: 1rpx solid #fbc4c4;
				}
			}
		}
		
		.imgBox{
			width: 120rpx;
			height: 120rpx;
		}
	}
</style>