<template>
  <view class="container">
    <view class="screen">银幕</view>
    <canvas 
      canvas-id="seatCanvas" 
      type="2d" 
      class="seat-canvas"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
    ></canvas>
    <view class="legend">
      <view class="legend-item">
        <view class="seat-icon available"></view>
        <text>可选</text>
      </view>
      <view class="legend-item">
        <view class="seat-icon selected"></view>
        <text>已选</text>
      </view>
      <view class="legend-item">
        <view class="seat-icon sold"></view>
        <text>已售</text>
      </view>
    </view>
    <view class="selected-seats">
      <text>已选座位：{{ selectedSeats.join(', ') || '无' }}</text>
    </view>
  </view>
</template>
<script>
export default {
  data() {
    return {
      ctx: null,
      canvasWidth: 0,
      canvasHeight: 0,
      seatSize: 30,
      gap: 10,
      rows: 8,
      cols: 10,
      seats: [],
      selectedSeats: [],
      touchStartX: 0,
      touchStartY: 0,
      offsetX: 0,
      offsetY: 0,
      scale: 1
    }
  },
  onReady() {
    this.initSeats()
    this.initCanvas()
  },
  methods: {
    initSeats() {
      // 初始化座位数据
      for (let i = 0; i < this.rows; i++) {
        this.seats[i] = []
        for (let j = 0; j < this.cols; j++) {
          // 随机生成一些已售座位
          const isSold = Math.random() < 0.2
          this.seats[i][j] = {
            row: i,
            col: j,
            status: isSold ? 'sold' : 'available', // available, selected, sold
            x: 0,
            y: 0
          }
        }
      }
    },
    async initCanvas() {
      // 获取canvas上下文
      const { canvas, width, height } = await this.getCanvasNode('seatCanvas')
      this.canvasWidth = width
      this.canvasHeight = height
      this.ctx = canvas.getContext('2d')
      
      // 计算初始偏移使座位居中
      const totalWidth = this.cols * (this.seatSize + this.gap) - this.gap
      const totalHeight = this.rows * (this.seatSize + this.gap) - this.gap
      this.offsetX = (this.canvasWidth - totalWidth) / 2
      this.offsetY = (this.canvasHeight - totalHeight) / 2
      
      this.drawSeats()
    },
    getCanvasNode(id) {
      return new Promise((resolve) => {
        const query = uni.createSelectorQuery().in(this)
        query.select(`#${id}`)
          .fields({ node: true, size: true })
          .exec((res) => {
						console.log('给我看看',res)
						console.log('给我看看',res)
						console.log('给我看看',res)
						console.log('给我看看',res)
						console.log('给我看看',res)
						console.log('给我看看',res)
            const canvas = res[0].node
            const width = res[0].width
            const height = res[0].height
            // 设置canvas实际宽高
            canvas.width = width * uni.getSystemInfoSync().pixelRatio
            canvas.height = height * uni.getSystemInfoSync().pixelRatio
            resolve({ canvas, width, height })
          })
      })
    },
    drawSeats() {
      if (!this.ctx) return
      
      // 清空画布
      this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
      
      // 保存当前状态
      this.ctx.save()
      
      // 应用缩放和平移
      this.ctx.translate(this.offsetX, this.offsetY)
      this.ctx.scale(this.scale, this.scale)
      
      // 绘制座位
      for (let i = 0; i < this.rows; i++) {
        for (let j = 0; j < this.cols; j++) {
          const seat = this.seats[i][j]
          const x = j * (this.seatSize + this.gap)
          const y = i * (this.seatSize + this.gap)
          
          // 更新座位坐标（用于点击检测）
          seat.x = x
          seat.y = y
          
          // 设置座位颜色
          switch (seat.status) {
            case 'available':
              this.ctx.fillStyle = '#4CAF50' // 绿色
              break
            case 'selected':
              this.ctx.fillStyle = '#2196F3' // 蓝色
              break
            case 'sold':
              this.ctx.fillStyle = '#9E9E9E' // 灰色
              break
          }
          
          // 绘制座位
          this.ctx.beginPath()
          this.ctx.roundRect(x, y, this.seatSize, this.seatSize, 4)
          this.ctx.fill()
          
          // 绘制座位编号
          this.ctx.fillStyle = '#FFFFFF'
          this.ctx.font = '12px Arial'
          this.ctx.textAlign = 'center'
          this.ctx.textBaseline = 'middle'
          this.ctx.fillText(
            `${String.fromCharCode(65 + i)}${j + 1}`,
            x + this.seatSize / 2,
            y + this.seatSize / 2
          )
        }
      }
      
      // 恢复状态
      this.ctx.restore()
    },
    handleTouchStart(e) {
      this.touchStartX = e.touches[0].x
      this.touchStartY = e.touches[0].y
    },
    handleTouchMove(e) {
      const touchX = e.touches[0].x
      const touchY = e.touches[0].y
      
      // 计算移动距离
      const dx = touchX - this.touchStartX
      const dy = touchY - this.touchStartY
      
      // 更新偏移量
      this.offsetX += dx
      this.offsetY += dy
      
      // 限制边界
      const minX = this.canvasWidth - (this.cols * (this.seatSize + this.gap) - this.gap) * this.scale
      const minY = this.canvasHeight - (this.rows * (this.seatSize + this.gap) - this.gap) * this.scale
      
      this.offsetX = Math.max(minX, Math.min(0, this.offsetX))
      this.offsetY = Math.max(minY, Math.min(0, this.offsetY))
      
      // 更新起始位置
      this.touchStartX = touchX
      this.touchStartY = touchY
      
      this.drawSeats()
    },
    handleTouchEnd(e) {
      // 检测是否点击了座位
      const touchX = e.changedTouches[0].x
      const touchY = e.changedTouches[0].y
      
      // 转换为画布坐标（考虑缩放和偏移）
      const canvasX = (touchX - this.offsetX) / this.scale
      const canvasY = (touchY - this.offsetY) / this.scale
      
      // 检查是否点击了座位
      for (let i = 0; i < this.rows; i++) {
        for (let j = 0; j < this.cols; j++) {
          const seat = this.seats[i][j]
          if (
            canvasX >= seat.x && 
            canvasX <= seat.x + this.seatSize && 
            canvasY >= seat.y && 
            canvasY <= seat.y + this.seatSize
          ) {
            this.toggleSeatSelection(seat)
            return
          }
        }
      }
    },
    toggleSeatSelection(seat) {
      if (seat.status === 'sold') return
      
      if (seat.status === 'available') {
        seat.status = 'selected'
        this.selectedSeats.push(`${String.fromCharCode(65 + seat.row)}${seat.col + 1}`)
      } else {
        seat.status = 'available'
        this.selectedSeats = this.selectedSeats.filter(
          s => s !== `${String.fromCharCode(65 + seat.row)}${seat.col + 1}`
        )
      }
      
      this.drawSeats()
    }
  }
}
</script>
<style>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20rpx;
  height: 100vh;
  background-color: #f5f5f5;
}

.screen {
  width: 80%;
  height: 40rpx;
  background: linear-gradient(to bottom, #ccc, #fff);
  margin-bottom: 40rpx;
  text-align: center;
  font-size: 28rpx;
  color: #333;
  border-radius: 8rpx;
  box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
}

.seat-canvas {
  width: 100%;
  height: 500rpx;
  background-color: #fff;
  margin-bottom: 20rpx;
  border-radius: 8rpx;
  box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
}

.legend {
  display: flex;
  justify-content: center;
  margin-bottom: 20rpx;
}

.legend-item {
  display: flex;
  align-items: center;
  margin: 0 20rpx;
}

.seat-icon {
  width: 30rpx;
  height: 30rpx;
  margin-right: 10rpx;
  border-radius: 4rpx;
}

.available {
  background-color: #4CAF50;
}

.selected {
  background-color: #2196F3;
}

.sold {
  background-color: #9E9E9E;
}

.selected-seats {
  padding: 20rpx;
  background-color: #fff;
  border-radius: 8rpx;
  width: 90%;
  text-align: center;
  box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
}
</style>