<!-- 子组件 transform-canvas.vue -->
<template>
  <view>
    <canvas 
      id="myCanvas" 
      canvas-id="myCanvas" 
      type="2d" 
      :style="{
        width: `${canvasDisplayWidth}px`, 
        height: `${canvasDisplayHeight}px`,
        border: '1px solid #eee'
      }"
    ></canvas>
  </view>
</template>

<script>
export default {
  props: {
    width: Number,    // 画布实际宽度(像素)
    height: Number,   // 画布实际高度(像素)
    imgUrl: String,   // 图片URL
    matrix: {         // 变换矩阵
      type: Object,
      default: () => ({
        a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0
      })
    },
		areaData:{},
	  seatData:{},
		selectedCodes:{}
  },
  data() {
    return {
      canvasContext: null,
      image: null,
      dpr: 1,
      canvasDisplayWidth: 800,  // 默认显示尺寸
      canvasDisplayHeight: 600,
      canvasActualWidth: 800,  // 实际像素尺寸
      canvasActualHeight: 600,
			nowSelectedCodes:this.selectedCodes
    };
  },
  watch: {
		selectedCodes:{
			handler(newVal) {
			  this.nowSelectedCodes = newVal
			},
			immediate: true
		},
    imgUrl: {
      handler(newUrl) {
        if (newUrl) this.loadImage(newUrl);
      },
      immediate: true
    },
    width: {
      handler() {
        this.updateCanvasSize();
      },
      immediate: true
    },
    height: {
      handler() {
        this.updateCanvasSize();
      },
      immediate: true
    },
    matrix: {
			deep: true,
			immediate: true, // 添加立即触发
			handler() {
				this.$nextTick(this.redraw); // 确保在下一个tick重绘
			}
		},
		areaData: {
			deep: true,
			handler() {
				this.$nextTick(this.redraw);
			}
		},
		seatData: {
			deep: true,
			handler() {
				this.$nextTick(this.redraw);
			}
		}
  },
  mounted() {
    this.initCanvas();
  },
  methods: {
	
		invertPoint(x, y) {
			// 注意：直接使用矩阵的逆转换，不需要除以dpr
			const inverted = this.matrix.invertPoint(x, y);
			return inverted;
		},
		
		// 添加点击检测方法
		checkHitArea(x, y) {
			if (!this.areaData) return null;
			
			// 转换坐标到原始画布空间
			const inverted = this.matrix.invertPoint(x, y, this.dpr);
			console.log('checkHitArea',inverted)
			// 遍历所有区域检测
			for (const area of this.areaData) {
				if (this.pointInPolygon(inverted.x, inverted.y, area.polygon)) {
					return area;
				}
			}
			return null;
		},
	
		pointInPolygon(x, y, polygon) {
		  const points = [];
		  for (let i = 0; i < polygon.length; i += 2) {
		    points.push([polygon[i], polygon[i + 1]]);
		  }
		
		  let inside = false;
		  let j = points.length - 1;
		  
		  for (let i = 0; i < points.length; j = i++) {
		    const [xi, yi] = points[i];
		    const [xj, yj] = points[j];
		    
		    // 检测点是否在线段上
		    if (this.pointOnLineSegment(x, y, xi, yi, xj, yj)) return true;
		    
		    // 射线法核心逻辑
		    if (yi <= y && yj > y || yj <= y && yi > y) {
		      const slope = (xj - xi) / (yj - yi);
		      if (x <= xi + (y - yi) * slope) {
		        inside = !inside;
		      }
		    }
		  }
		  
		  return inside;
		},
		

		
		// 添加点是否在线段上的检查
		pointOnLineSegment(x, y, x1, y1, x2, y2) {
		  // 线段的长度
		  const dx = x2 - x1;
		  const dy = y2 - y1;
		  const segmentLength = Math.sqrt(dx * dx + dy * dy);
		  
		  // 点到线段起点的向量
		  const vx = x - x1;
		  const vy = y - y1;
		  
		  // 向量在方向上的投影
		  const dotProduct = vx * dx + vy * dy;
		  
		  // 计算参数t (0-1之间表示在线段上)
		  const t = dotProduct / (segmentLength * segmentLength);
		  
		  // 点在线段上
		  if (t >= 0 && t <= 1) {
		    // 计算点在线段上的位置
		    const projX = x1 + t * dx;
		    const projY = y1 + t * dy;
		    
		    // 检查点与投影点的距离（容差5px）
		    const distance = Math.sqrt((x - projX) * 2 + (y - projY) * 2);
		    return distance < 5;
		  }
		  
		  return false;
		},
		
    initCanvas() {
      const query = uni.createSelectorQuery().in(this);
      query.select('#myCanvas')
        .fields({ node: true, size: true })
        .exec(async (res) => {
          if (!res[0]) return;
          
          this.canvas = res[0].node;
          this.ctx = res[0].node.getContext('2d');
          
          // 获取设备像素比
          this.dpr = uni.getSystemInfoSync().pixelRatio;
          
          // 更新画布尺寸
          this.updateCanvasSize();
          
          // 如果已有图片URL，加载图片
          if (this.imgUrl) {
            await this.loadImage(this.imgUrl);
          }
        });
    },
    
    updateCanvasSize() {
      // 显示尺寸使用prop传入的width/height
      this.canvasDisplayWidth = this.width;
      this.canvasDisplayHeight = this.height;
       // * this.dpr
			 // * this.dpr
      // 实际像素尺寸考虑DPR
      this.canvasActualWidth = this.width;
      this.canvasActualHeight = this.height;
      
      if (this.canvas) {
        this.canvas.width = this.canvasActualWidth;
        this.canvas.height = this.canvasActualHeight;
        // this.ctx.scale(this.dpr, this.dpr);
        this.redraw();
      }
    },
    async loadImage(src) {
      try {
        // 等待canvas初始化
        if (!this.canvas) {
          await this.initCanvas();
        }
        
        this.image = await new Promise((resolve, reject) => {
          if (!this.canvas) {
            // reject(new Error("Canvas not initialized"));
            return;
          }
          
          const image = this.canvas.createImage();
          image.src = src;
          image.onload = () => resolve(image);
          image.onerror = reject;
        });
        this.redraw();
      } catch (e) {
        console.error("图片加载失败:", e);
        this.image = null;
      }
    },
		
	// 在redraw方法中添加视图判断
	 checkSeatHit(x, y) {
	    if (!this.seatData) return null;
	    
	    // 转换坐标到原始画布空间
	    const inverted = this.matrix.invertPoint(x, y, this.dpr);
	    
	    // 遍历所有座位检测
	    for (const seat of this.seatData) {
	      const dx = seat.x - inverted.x;
	      const dy = seat.y - inverted.y;
	      const distance = Math.sqrt(dx * dx + dy * dy);
	      
	      // 命中检测（8px半径）
	      if (distance < 8) {
	        return seat;
	      }
	    }
	    return null;
	  },
		redraw() {
		  if (!this.ctx) return;
		  
		  this.ctx.save();
		  this.ctx.resetTransform();
		  this.ctx.clearRect(0, 0, this.canvasActualWidth, this.canvasActualHeight);
		  this.ctx.scale(this.dpr, this.dpr);
		  
		  // 应用变换矩阵
		  const { a, b, c, d, tx, ty } = this.matrix;
		  this.ctx.setTransform(a, b, c, d, tx, ty);
		  
		  // 仅在区域视图显示背景图片
		  if (this.image && this.$parent?.currentView === 'area') {
		    this.ctx.drawImage(
		      this.image, 
		      0, 
		      0, 
		      this.canvasDisplayWidth, 
		      this.canvasDisplayHeight
		    );
		  }
		  
		  // 绘制区域（仅在区域视图）
		  if (this.areaData && this.areaData.length > 0 && this.$parent?.currentView === 'area') {
		    this.drawAreas();
		  }
		  
		  // 绘制座位（仅在座位视图）
		  if (this.seatData && this.seatData.length > 0 && this.$parent?.currentView === 'seat') {
		    this.drawSeats();
		  }
		  
		  this.ctx.restore();
		},
	 // 添加绘制区域方法
	 drawAreas() {
		 this.areaData.forEach(area => {
			 const points = [];
			 for (let i = 0; i < area.polygon.length; i += 2) {
				 points.push([area.polygon[i], area.polygon[i + 1]]);
			 }
			 
			 this.ctx.beginPath();
			 points.forEach(([x, y], index) => {
				 if (index === 0) this.ctx.moveTo(x, y);
				 else this.ctx.lineTo(x, y);
			 });
			 this.ctx.closePath();
			 this.ctx.strokeStyle = 'rgba(255, 0, 0, 0.7)';
			 this.ctx.lineWidth = 2;
			 this.ctx.stroke();
			 this.ctx.fillStyle = 'rgba(0, 255, 0, 0.2)';
			 this.ctx.fill();
		 });
	 },
		drawSeats() {
			 this.ctx.save();
			  
			  // 应用变换矩阵
			  const { a, b, c, d, tx, ty } = this.matrix;
			  this.ctx.setTransform(a, b, c, d, tx, ty);
			  
			  // 获取当前缩放比例
			  const scale = Math.sqrt(a * a + b * b);
			  
			  this.seatData.forEach(seat => {
			    const x = seat.x;
			    const y = seat.y;
			    
			    // 根据缩放调整座位大小
			    const radius = 8 / scale;
			    
					console.log(this.nowSelectedCodes,'nowSelectedCodesnowSelectedCodesnowSelectedCodes')
			    // 修改1：为选中座位添加特殊样式
			    if (this.nowSelectedCodes.has(seat.code) && seat.status === 1) {
			      // 1. 绘制金色边框
			      this.ctx.beginPath();
			      this.ctx.arc(x, y, radius + 1, 0, Math.PI * 2);
			      this.ctx.strokeStyle = '#FFD700'; // 金色
			      this.ctx.lineWidth = 2 / scale;
			      this.ctx.stroke();
			      
			      // 2. 绘制半透明金色背景
			      this.ctx.beginPath();
			      this.ctx.arc(x, y, radius, 0, Math.PI * 2);
			      this.ctx.fillStyle = 'rgba(255, 215, 0, 0.3)';
			      this.ctx.fill();
			      
			      // 3. 绘制白色对勾（缩小版）
			      this.ctx.strokeStyle = '#fff';
			      this.ctx.lineWidth = 1 / scale;
			      this.ctx.lineCap = 'round';
			      this.ctx.beginPath();
			      this.ctx.moveTo(x - 2.5, y);
			      this.ctx.lineTo(x - 0.5, y + 1.5);
			      this.ctx.lineTo(x + 2.5, y - 2);
			      this.ctx.stroke();
			    } else {
			      // 普通座位的绘制保持不变
			      this.ctx.beginPath();
			      this.ctx.arc(x, y, radius, 0, Math.PI * 2);
			      this.ctx.fillStyle = seat.status === 1 ? '#4cd964' : '#dd524d';
			      this.ctx.fill();
			    }
			    
			    // 仅在缩放足够大时显示文字
			  
			  });
			  
			  this.ctx.restore();
		}
		  
	}
}
</script>