<template>
  <div
    class="main_container"
    ref="mainContainerRef"
    v-loading="loading"
    element-loading-text="图片加载中……"
    element-loading-spinner="el-icon-loading"
    element-loading-background="#ffffff"
    @mousedown="onMouseDown"
    @mousemove="onMouseMove"
    @mouseup="onMouseUp"
    @wheel="onWheel"
  >
    <canvas
      id="paperCanvas"
      ref="paperCanvasRef"
      class="paper_canvas"
      @mouseleave="onCanvasLeave"
    ></canvas>
    <div id="imgContainer" class="img_container">
      <img v-if="paperImgUrl" :src="paperImgUrl" />
    </div>
    <div class="no_paper_url" v-if="paperImgUrl == ''">
      暂无数据
      <!-- 请先制作模版 -->
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, watch, onBeforeUnmount, onMounted } from 'vue'
import { throttle } from 'lodash'
// import { mmToPx } from '@/utils/common.ts' // 如果需要取消注释

// 定义 Props
const props = defineProps({
  drawData: {
    type: Array,
    default: () => [],
  }, // 画的边框的数据
  paperInfo: {
    type: Object,
    default: () => null,
  }, // 纸张大小
  paperImgUrl: {
    type: String,
    default: '',
  }, // 试卷地址相关信息
  currentId: {
    type: String,
    default: '',
  }, // 当前选中的id
  isDrag: {
    type: Boolean,
    default: true,
  }, // 是否可以拖动 默认可以拖动
  isAbnormal: {
    type: Boolean,
    default: false,
  }, // 是否异常处使用 区别 异常处理使用的地方 正常答案显示蓝色
})

// 定义 Emits
const emit = defineEmits(['GetRectPoint'])

// 响应式数据
const mainContainerRef = ref(null)
const paperCanvasRef = ref(null)

const position = reactive({
  x: 0,
  y: 0,
}) // 初始canvas图片位置

const startX = ref(0) // 鼠标按下时的初始位置x坐标
const startY = ref(0) // 鼠标按下时的初始位置y坐标
const scale = ref(1) // 画布缩放倍数
const isDragging = ref(false) // 是否拖动画布
const isDrawing = ref(false) // 是否正在画线
const drawType = ref(0) // 1画线 0 拖拽模式
const image = ref(null)

const paperImgInfo = reactive({
  width: 0,
  height: 0,
})

const canvasInfo = reactive({
  width: 0,
  height: 0,
}) // 画布的大小

const zoomRate = ref(0) // 图片的缩放比例
const dpr = window.devicePixelRatio || 1
const minScale = 0.7 // 最小缩放值
const maxScale = 4 // 最大缩放值

const rectPoint = reactive({
  startX: 0,
  startY: 0,
  endX: 0,
  endY: 0,
}) // 矩形起始坐标点

const showObjectArea = ref(false) // 是否显示对象区域
const addObjectAreaOption = reactive({
  derection: 1, // 排列方向 1 横线 2竖向
  questionType: 1, // 题类型 1单选 2多选 3 判断
  startNumber: 16, // 起始题号
  endNumber: 20, // 结束题号
  interval: 1, // 题号间隔 默认1
  answerNumber: 4, // 选项个数 答案个数
  answerWidth: 0, // 选项宽度
  answerHeight: 0, // 选项高度
}) // 添加选择题设置信息

const currenPoint = reactive({
  x: 0,
  y: 0,
  w: 0,
  h: 0,
})

const containerWidth = ref(0) // 容器宽度
const containerHeight = ref(0) // 容器高度
const isInit = ref(true) // 是否是初始加载
const isShowDraw = ref(true) // 是否显示画框
const loading = ref(false) // 是否正在加载图片

// 模拟 this.$global.floatNum，请根据实际项目替换为真实工具函数
const floatNum = (num, fixed = 2) => {
  if (typeof num !== 'number') return 0
  return Number(num.toFixed(fixed))
}

// 方法定义

// 显示画框
const ShowDrawData = () => {
  isShowDraw.value = !isShowDraw.value
  drawImage()
}

// 初始数据加载
const initData = () => {
  if (!mainContainerRef.value) return
  console.log('初始化数据加载图片地址信息',props.paperImgUrl)
  // 获取容器的宽高
  const { width, height } = mainContainerRef.value.getBoundingClientRect()
  containerHeight.value = Number(height)
  containerWidth.value = Number(width)
  console.log('初始化数据加载容器宽高',containerWidth.value,containerHeight.value)
  image.value = new Image()
  image.value.src = props.paperImgUrl

  // 初始化获取试卷数据
  if (props.paperInfo?.width && props.paperInfo?.height) {
    // 设置初始数据
    paperImgInfo.width = props.paperInfo.width // 获取宽
    paperImgInfo.height = props.paperInfo.height // 获取高
    
    image.value.onload = () => {
      loading.value = false // 图片加载完成
      // 更新缩放率
      updateZoomAndPaperInfo()
      // 更新画布尺寸
      updateCanvasSize()
      // 计算中心位置使图片居中 初始加载图片是居中
      if (isInit.value) {
        centerCanvas()
      }
      // 加载图片
      loadImage()
    }
  } else {
    // 没有值 默认图片的宽高
    image.value.onload = () => {
      paperImgInfo.width = image.value.width // 获取宽
      paperImgInfo.height = image.value.height // 获取高
      loading.value = false // 图片加载完成
      // 更新缩放率
      updateZoomAndPaperInfo()
      // 更新画布尺寸
      updateCanvasSize()
      // 计算中心位置使图片居中
      if (isInit.value) {
        centerCanvas()
      }
      // 加载图片
      loadImage()
    }
  }
}

// 切换试卷图片
const chanagePaperImage = () => {
  // 更新缩放率
  updateZoomAndPaperInfo()
  // 更新画布尺寸
  updateCanvasSize()
  // 加载图片
  loadImage()
}

// 适合屏幕
const fitScreen = () => {
  scale.value = 1
  isInit.value = true
  initData() // 初始化屏幕加载
}

// 加载图片
const loadImage = () => {
  drawImage() // 绘制边框数据
}

// 图片宽高坐标变化
const ImageInfoChange = () => {
  const { width, height } = paperImgInfo
  const imgDom = document.getElementById('imgContainer')
  if (imgDom) {
    imgDom.style.width = width * zoomRate.value * scale.value + 'px'
    imgDom.style.height = height * zoomRate.value * scale.value + 'px'
    imgDom.style.left = position.x + 'px'
    imgDom.style.top = position.y + 'px'
  }
}

// 图片加载完成后绘制图片
const drawImage = () => {
  const canvas = paperCanvasRef.value
  if (!canvas) return
  
  const ctx = canvas.getContext('2d')
  if (!ctx) return

  ctx.clearRect(0, 0, canvasInfo.width, canvasInfo.height) // 清除边框数据
  ImageInfoChange() // 用image图片替代背景

  for (let i = 0; i < props.drawData.length; i++) {
    let point = {
      x: props.drawData[i].x * zoomRate.value * scale.value,
      y: props.drawData[i].y * zoomRate.value * scale.value,
      width: props.drawData[i].w * zoomRate.value * scale.value,
      height: props.drawData[i].h * zoomRate.value * scale.value,
      blockName: props.drawData[i].blockName,
      page: props.drawData[i].page,
      blockArea: props.drawData[i].blockArea,
    }

    // 外边框数据 mm单位 比如系统卡 使用
    if (props.drawData[i].usedCardType == 1) {
      // 系统卡
      const imageInfo = paperImgInfo
      let offsexPoint = {
        x: props.drawData[i].x - 30,
        y: props.drawData[i].y - 25,
        w: props.drawData[i].w,
        h: props.drawData[i].h,
      } // 相对与第一个黑块的坐标
      
      let templateInfo = {
        width: 794 - 30 * 2,
        height: 1123 - 25 * 2,
      } // 模板去掉边框的尺寸

      // 如果长大于宽 就是A3 否则就是A4
      if (paperImgInfo.width > paperImgInfo.height) {
        // A3 1588*1123
        offsexPoint = {
          x: props.drawData[i].x - 30,
          y: props.drawData[i].y - 25,
          w: props.drawData[i].w,
          h: props.drawData[i].h,
        }
        templateInfo = {
          width: 1588 - 30 * 2,
          height: 1123 - 25 * 2,
        }
      } else {
        // A4 794*1123
        offsexPoint = {
          x: props.drawData[i].x - 30,
          y: props.drawData[i].y - 25,
          w: props.drawData[i].w,
          h: props.drawData[i].h,
        }
        templateInfo = {
          width: 794 - 30 * 2,
          height: 1123 - 25 * 2,
        }
      }

      // 系统卡 需要根据模板的坐标进行转换
      const x = parseFloat(
        ((offsexPoint.x / templateInfo.width) * imageInfo.width).toFixed(2)
      )
      const y = parseFloat(
        ((offsexPoint.y / templateInfo.height) * imageInfo.height).toFixed(2)
      )
      const w = parseFloat(
        ((props.drawData[i].w / templateInfo.width) * imageInfo.width).toFixed(2)
      )
      const h = parseFloat(
        ((props.drawData[i].h / templateInfo.height) * imageInfo.height).toFixed(2)
      )

      point = {
        x: x * zoomRate.value * scale.value,
        y: y * zoomRate.value * scale.value,
        width: w * zoomRate.value * scale.value,
        height: h * zoomRate.value * scale.value,
        blockName: props.drawData[i].blockName,
        page: props.drawData[i].page || 1,
        blockArea: props.drawData[i].blockArea,
      }
    }

    // 当前表格选择的边框换蓝色显示
    if (props.currentId == props.drawData[i].id) {
      ctx.strokeStyle = 'blue'
      ctx.fillStyle = 'blue'
      ctx.lineWidth = 2
    } else {
      ctx.strokeStyle = 'red'
      ctx.fillStyle = 'red'
      ctx.lineWidth = 2
    }

    const topiclist = props.drawData[i].topiclist || []
    
    if (topiclist.length > 0) {
      const topicName = String(topiclist?.[0]?.topicName)
      // 客观题有题目则不显示外边框
      if (topicName.includes('选做区')) {
        ctx.strokeRect(point.x, point.y, point.width, point.height) // 绘制边框
      }
      if (topiclist[0].index < 0) {
        // 系统卡选做题显示边框
        ctx.strokeRect(point.x, point.y, point.width, point.height) // 绘制边框
      }
    } else {
      ctx.lineWidth = 2
      ctx.strokeRect(point.x, point.y, point.width, point.height) // 绘制边框
    }

    // 客观题小题加载
    if (props.drawData[i].topiclist) {
      const topiclist = props.drawData[i].topiclist
      let derection = 1 // 排列方向 1 横向 2竖向
      
      if (props.drawData[i].areaOption) {
        try {
          const option = JSON.parse(props.drawData[i].areaOption)
          derection = option.derection
        } catch (e) {
          console.error('解析 areaOption 失败', e)
        }
      }

      if (isShowDraw.value) {
        topiclist.forEach((topicItem) => {
          ctx.font = '15px Arial'
          ctx.fillStyle = 'red'
          ctx.textAlign = 'left'

          if (String(topicItem.topicName).includes('选做区')) {
            // 选做题不显示题目文字
          } else {
            let namePoint = {
              x: topicItem.answerList[0].x,
              y: topicItem.answerList[0].y,
            }

            // 绘制文字 系统卡
            if (props.drawData[i].usedCardType == 1) {
              const imageInfo = paperImgInfo
              let offsexPoint = {
                x: topicItem.answerList[0].x - 30,
                y: topicItem.answerList[0].y - 25,
              }
              let templateInfo = {
                width: 794 - 30 * 2,
                height: 1123 - 25 * 2,
              }

              if (paperImgInfo.width > paperImgInfo.height) {
                // A3
                offsexPoint = {
                  x: topicItem.answerList[0].x - 30,
                  y: topicItem.answerList[0].y - 25,
                }
                templateInfo = {
                  width: 1588 - 30 * 2,
                  height: 1123 - 25 * 2,
                }
              } else {
                // A4
                offsexPoint = {
                  x: topicItem.answerList[0].x - 30,
                  y: topicItem.answerList[0].y - 25,
                }
                templateInfo = {
                  width: 794 - 30 * 2,
                  height: 1123 - 25 * 2,
                }
              }

              namePoint.x = parseFloat(
                ((offsexPoint.x / templateInfo.width) * imageInfo.width).toFixed(2)
              )
              namePoint.y = parseFloat(
                ((offsexPoint.y / templateInfo.height) * imageInfo.height).toFixed(2)
              )
            }

            if (props.isAbnormal) {
              if (topicItem.hasAbnormal) {
                ctx.fillStyle = 'red'
              } else {
                ctx.fillStyle = 'blue'
              }
            } else {
              ctx.fillStyle = 'red'
              if (props.currentId == props.drawData[i].id) {
                ctx.fillStyle = 'blue'
              } else {
                ctx.fillStyle = 'red'
              }
            }

            if (derection == 1 || derection == 3) {
              // 横向 或者横纵向
              ctx.fillText(
                topicItem.topicName,
                parseFloat(namePoint.x - 30) * zoomRate.value * scale.value,
                parseFloat(namePoint.y + 15) * zoomRate.value * scale.value
              )
            } else {
              // 竖向
              ctx.fillText(
                topicItem.topicName,
                parseFloat(namePoint.x + 1) * zoomRate.value * scale.value,
                parseFloat(namePoint.y - 22) * zoomRate.value * scale.value
              )
            }
          }

          topicItem.answerList.forEach((answerItem) => {
            let obj = {
              x: answerItem.x * zoomRate.value * scale.value,
              y: answerItem.y * zoomRate.value * scale.value,
              width: answerItem.w * zoomRate.value * scale.value,
              height: answerItem.h * zoomRate.value * scale.value,
            }

            // 系统卡
            if (props.drawData[i].usedCardType == 1) {
              const imageInfo = paperImgInfo
              let offsexPoint = {
                x: answerItem.x - 30,
                y: answerItem.y - 25,
                w: answerItem.w,
                h: answerItem.h,
              }
              let templateInfo = {
                width: 794 - 30 * 2,
                height: 1123 - 25 * 2,
              }

              if (paperImgInfo.width > paperImgInfo.height) {
                // A3
                offsexPoint = {
                  x: answerItem.x - 30,
                  y: answerItem.y - 25,
                  w: answerItem.w,
                  h: answerItem.h,
                }
                templateInfo = {
                  width: 1588 - 30 * 2,
                  height: 1123 - 25 * 2,
                }
              } else {
                // A4
                offsexPoint = {
                  x: answerItem.x - 30,
                  y: answerItem.y - 25,
                  w: answerItem.w,
                  h: answerItem.h,
                }
                templateInfo = {
                  width: 794 - 30 * 2,
                  height: 1123 - 25 * 2,
                }
              }

              const x = parseFloat(
                ((offsexPoint.x / templateInfo.width) * imageInfo.width).toFixed(2)
              )
              const y = parseFloat(
                ((offsexPoint.y / templateInfo.height) * imageInfo.height).toFixed(2)
              )
              const w = parseFloat(
                ((answerItem.w / templateInfo.width) * imageInfo.width).toFixed(2)
              )
              const h = parseFloat(
                ((answerItem.h / templateInfo.height) * imageInfo.height).toFixed(2)
              )

              obj = {
                x: x * zoomRate.value * scale.value,
                y: y * zoomRate.value * scale.value,
                width: w * zoomRate.value * scale.value,
                height: h * zoomRate.value * scale.value,
              }
            }

            ctx.lineWidth = 1
            
            // 选中 绘制带背景阴影的边框
            if (topicItem.hasAbnormal) {
              // 有异常的
              if (answerItem.isCheck) {
                ctx.fillStyle = 'rgba(255,0,0,0.3)' // 红色背景
                ctx.strokeStyle = 'red' // 红色边框
                ctx.fillRect(obj.x, obj.y, obj.width, obj.height)
                ctx.strokeRect(obj.x, obj.y, obj.width, obj.height)
              } else {
                ctx.fillStyle = 'red' // 半透明红色背景
                ctx.strokeStyle = 'red' // 边框的颜色
                ctx.strokeRect(obj.x, obj.y, obj.width, obj.height)
              }
            } else {
              if (props.isAbnormal) {
                ctx.fillStyle = 'rgba(0,0,255,0.3)' // 半透明蓝色背景
                ctx.strokeStyle = 'blue' // 蓝色边框
              } else {
                ctx.fillStyle = 'rgba(255,0,0,0.3)' // 红色背景
                ctx.strokeStyle = 'red' // 红色边框

                if (props.currentId == props.drawData[i].id) {
                  ctx.strokeStyle = 'blue'
                } else {
                  ctx.strokeStyle = 'red'
                }
              }

              // 选中
              if (answerItem?.isCheck) {
                ctx.fillRect(obj.x, obj.y, obj.width, obj.height)
                ctx.strokeRect(obj.x, obj.y, obj.width, obj.height)
              } else {
                ctx.strokeRect(obj.x, obj.y, obj.width, obj.height)
              }
            }
          })
        })
      }
    }

    // 主观题划分区加载
    if (props.drawData[i].scoreList) {
      const scoreList = props.drawData[i].scoreList
      scoreList.forEach((scoreItem) => {
        ctx.font = '15px Arial'
        ctx.fillStyle = 'red'
        ctx.textAlign = 'left'

        let obj = {
          x: scoreItem.x * zoomRate.value * scale.value,
          y: scoreItem.y * zoomRate.value * scale.value,
          width: scoreItem.w * zoomRate.value * scale.value,
          height: scoreItem.h * zoomRate.value * scale.value,
        }

        // 系统卡
        if (props.drawData[i].usedCardType == 1) {
          const imageInfo = paperImgInfo
          let offsexPoint = {
            x: scoreItem.x - 30,
            y: scoreItem.y - 25,
            w: scoreItem.w,
            h: scoreItem.h,
          }
          let templateInfo = {
            width: 794 - 30 * 2,
            height: 1123 - 25 * 2,
          }

          if (paperImgInfo.width > paperImgInfo.height) {
            // A3
            offsexPoint = {
              x: scoreItem.x - 30,
              y: scoreItem.y - 25,
              w: scoreItem.w,
              h: scoreItem.h,
            }
            templateInfo = {
              width: 1588 - 30 * 2,
              height: 1123 - 25 * 2,
            }
          } else {
            // A4
            offsexPoint = {
              x: scoreItem.x - 30,
              y: scoreItem.y - 25,
              w: scoreItem.w,
              h: scoreItem.h,
            }
            templateInfo = {
              width: 794 - 30 * 2,
              height: 1123 - 25 * 2,
            }
          }

          const x = parseFloat(
            ((offsexPoint.x / templateInfo.width) * imageInfo.width).toFixed(2)
          )
          const y = parseFloat(
            ((offsexPoint.y / templateInfo.height) * imageInfo.height).toFixed(2)
          )
          const w = parseFloat(
            ((scoreItem.w / templateInfo.width) * imageInfo.width).toFixed(2)
          )
          const h = parseFloat(
            ((scoreItem.h / templateInfo.height) * imageInfo.height).toFixed(2)
          )

          obj = {
            x: x * zoomRate.value * scale.value,
            y: y * zoomRate.value * scale.value,
            width: w * zoomRate.value * scale.value,
            height: h * zoomRate.value * scale.value,
          }
        }

        ctx.lineWidth = 1
        ctx.fillStyle = scoreItem.color + '50' // 红色背景
        ctx.strokeStyle = scoreItem.color // 红色边框
        
        if (scoreItem.isCheck) {
          ctx.fillRect(obj.x, obj.y, obj.width, obj.height)
        }
        ctx.strokeRect(obj.x, obj.y, obj.width, obj.height) // 绘制答案边框
      })
    }

    ctx.fillStyle = 'rgba(255,0,0,1)' // 半透明红色背景
    ctx.font = '15px Arial'
    ctx.textAlign = 'left'
    
    // 绘制文字 定位去和客观题组不用显示
    if (point.blockArea != 2 && point.blockArea != 8) {
      ctx.fillText(point.blockName, point.x, point.y - 5)
    }
  }
  ctx.restore()
}

// 更新缩放率
const updateZoomAndPaperInfo = () => {
  const widthZoomRate = containerWidth.value / paperImgInfo.width
  const heightZoomRate = containerHeight.value / paperImgInfo.height
  // 选择较小的缩放率作为基准，确保图像完整显示在容器内
  zoomRate.value = Math.min(widthZoomRate, heightZoomRate)
}

// 更新画布尺寸
const updateCanvasSize = () => {
  canvasInfo.width = Math.round(paperImgInfo.width * zoomRate.value * scale.value)
  canvasInfo.height = Math.round(paperImgInfo.height * zoomRate.value * scale.value)
  
  if (paperCanvasRef.value) {
    paperCanvasRef.value.width = canvasInfo.width
    paperCanvasRef.value.height = canvasInfo.height
  }
}

// 中心化画布
const centerCanvas = () => {
  position.x = (containerWidth.value - canvasInfo.width) / 2
  position.y = (containerHeight.value - canvasInfo.height) / 2
  
  if (paperCanvasRef.value) {
    paperCanvasRef.value.style.left = `${position.x}px`
    paperCanvasRef.value.style.top = `${position.y}px`
  }
  isInit.value = false // 后面不在执行居中操作
}

// 全局鼠标释放事件处理
const onGlobalMouseUp = () => {
  isDragging.value = false
}

// 鼠标按下事件
const onMouseDown = (event) => {
  // 只响应左键点击（button值为0表示左键）
  if (event.button !== 0) {
    isDragging.value = false
    return
  }
  
  // 确保在开始新的拖拽前，先重置拖拽状态
  isDragging.value = false
  
  if (drawType.value == 0) {
    if (props.isDrag) {
      isDragging.value = true
      startX.value = event.clientX - position.x
      startY.value = event.clientY - position.y
    }
  }
  
  if (drawType.value == 1) {
    if (event.target.id != 'paperCanvas') {
      isDragging.value = true
      startX.value = event.clientX - position.x
      startY.value = event.clientY - position.y
    }
  }
}

// 鼠标移动事件
const onMouseMove = (event) => {
  if (isDragging.value) {
    // 在拖拽模式下，移动画布
    position.x = event.clientX - startX.value
    position.y = event.clientY - startY.value
    
    if (paperCanvasRef.value) {
      paperCanvasRef.value.style.left = `${position.x}px`
      paperCanvasRef.value.style.top = `${position.y}px`
    }
    ImageInfoChange()
  }
}

// 鼠标抬起事件
const onMouseUp = (event) => {
  // 只响应左键释放
  if (event && event.button !== 0) {
    return
  }
  isDragging.value = false // 停止拖拽
}

// 鼠标滚轮事件
const onWheel = (event) => {
  event.preventDefault()
  // 计算新的缩放比例
  const delta = event.deltaY < 0 ? 1 : -1
  const newScale = scale.value + delta * 0.1
  const clampedScale = Math.max(minScale, Math.min(maxScale, newScale))
  
  // 如果缩放值没有变化，则直接返回
  if (clampedScale === scale.value) return
  
  // 获取鼠标在容器中的位置
  const containerRect = mainContainerRef.value.getBoundingClientRect()
  const mouseX = event.clientX - containerRect.left
  const mouseY = event.clientY - containerRect.top
  
  // 计算鼠标相对于当前画布的位置
  const mouseRelativeToCanvasX = (mouseX - position.x) / scale.value
  const mouseRelativeToCanvasY = (mouseY - position.y) / scale.value
  
  // 更新缩放比例
  scale.value = clampedScale
  
  // 更新画布尺寸
  updateCanvasSize()
  
  // 重新计算画布位置，使缩放围绕鼠标点进行
  position.x = mouseX - mouseRelativeToCanvasX * scale.value
  position.y = mouseY - mouseRelativeToCanvasY * scale.value
  
  // 应用新的位置
  if (paperCanvasRef.value) {
    paperCanvasRef.value.style.left = `${position.x}px`
    paperCanvasRef.value.style.top = `${position.y}px`
  }
  
  // 更新图片位置信息
  ImageInfoChange()
  
  // 重新绘制内容
  drawImage()
}

// 鼠标复位
const MouseReset = () => {
  drawType.value = 0
  const canvas = paperCanvasRef.value
  if (canvas) {
    canvas.style.cursor = 'pointer'
    canvas.onmousedown = null
    canvas.onmousemove = null
    canvas.onmouseup = null
  }
}

// 框选答案区域
const SelectionBox = () => {
  drawType.value = 1
  const canvas = paperCanvasRef.value
  if (canvas) {
    canvas.style.cursor = 'crosshair'
    canvas.onmousedown = onCanvasDown
    canvas.onmousemove = onCanvasMove
    canvas.onmouseup = onCanvasUp
  }
}

// 画圈模式
const PaintingCircle = () => {
  drawType.value = 1
  const canvas = paperCanvasRef.value
  if (canvas) {
    canvas.style.cursor = 'crosshair'
    canvas.onmousedown = onCanvasDown
    canvas.onmousemove = onCanvasMove
    canvas.onmouseup = onCanvasUp
  }
}

// 开始画答案区域圈
const StartPaintingCircle = (obj) => {
  Object.assign(addObjectAreaOption, obj)
  drawType.value = 1
  const canvas = paperCanvasRef.value
  if (canvas) {
    canvas.style.cursor = 'crosshair'
    canvas.onmousedown = onCanvasDown
    canvas.onmousemove = onCanvasMove
    canvas.onmouseup = onCanvasUp
  }
}

// canvas上按下事件
const onCanvasDown = (e) => {
  const canvas = paperCanvasRef.value
  if (canvas) canvas.style.cursor = 'crosshair'
  
  isDrawing.value = true
  isDragging.value = false // 禁止拖拽
  
  rectPoint.startX = e.offsetX
  rectPoint.startY = e.offsetY
  rectPoint.endX = e.offsetX
  rectPoint.endY = e.offsetY
}

// canvas上移动事件
const onCanvasMove = (e) => {
  if (isDrawing.value) {
    const canvas = paperCanvasRef.value
    if (!canvas) return
    
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    // 更新当前鼠标位置
    rectPoint.endX = e.offsetX
    rectPoint.endY = e.offsetY
    
    // 清除之前的矩形
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    // 重新绘制之前的边框数据
    drawImage()
    
    // 设置矩形样式
    ctx.strokeStyle = 'blue'
    ctx.lineWidth = 1 // 画框的线的粗细
    
    // 计算矩形的起点和宽高，处理反向框选
    const startX = rectPoint.startX
    const startY = rectPoint.startY
    const width = e.offsetX - startX
    const height = e.offsetY - startY
    
    // 绘制矩形（可以处理负宽度和高度）
    ctx.strokeRect(startX, startY, width, height)
  }
}

// canvas抬起事件
const onCanvasUp = () => {
  isDrawing.value = false
  
  // 处理反向框选，确保宽度和高度为正数
  let startX = rectPoint.startX
  let startY = rectPoint.startY
  let endX = rectPoint.endX
  let endY = rectPoint.endY
  
  // 确保起点坐标是左上角，终点坐标是右下角
  let actualStartX = Math.min(startX, endX)
  let actualStartY = Math.min(startY, endY)
  let actualEndX = Math.max(startX, endX)
  let actualEndY = Math.max(startY, endY)
  
  // 计算实际的宽度和高度（确保为正数）
  let width = Math.abs(actualEndX - actualStartX)
  let height = Math.abs(actualEndY - actualStartY)
  
  const point = {
    x: floatNum(actualStartX / zoomRate.value / scale.value),
    y: floatNum(actualStartY / zoomRate.value / scale.value),
    w: floatNum(width / zoomRate.value / scale.value),
    h: floatNum(height / zoomRate.value / scale.value),
    unit: 'px',
  }
  
  Object.assign(currenPoint, point)
  
  // 只有当宽度和高度都大于0时才触发事件
  if (point.w > 0 && point.h > 0) {
    emit('GetRectPoint', point)
  }
}

// 鼠标离开画布事件
const onCanvasLeave = () => {
  // 如果正在绘制，自动结束绘制
  if (isDrawing.value) {
    onCanvasUp()
  }
}

// 监听窗口大小变化，重新计算表格高度 使用节流防止频繁改变窗口大小导致计算量过大而页面卡顿
const handleResize = throttle(() => {
  // 如果需要重新计算，可以在这里 uncomment
  // if (mainContainerRef.value) {
  //   const { width, height } = mainContainerRef.value.getBoundingClientRect()
  //   containerWidth.value = width
  //   containerHeight.value = height
  //   updateZoomAndPaperInfo()
  //   updateCanvasSize()
  //   centerCanvas()
  //   loadImage()
  // }
}, 500)

// Watchers
watch(
  () => props.paperImgUrl,
  (newVal) => {
    loading.value = true // 加载图片
    initData() // 初始化数据
    setTimeout(() => {
      if (!props.paperImgUrl) {
        loading.value = false // 加载图片完成
      }
    }, 100)
  },
  { deep: true, immediate: true }
)

watch(
  () => props.drawData,
  () => {
    drawImage() // 更新边框数据并重新绘制
  },
  { deep: true }
)

watch(
  () => props.currentId,
  () => {
    drawImage() // 更新边框数据并重新绘制
  }
)

// Lifecycle Hooks
onMounted(() => {
  window.addEventListener('resize', handleResize)
  // 添加全局鼠标释放事件监听器，处理异常情况
  window.addEventListener('mouseup', onGlobalMouseUp)
  
  // 初始数据处理加载 如定位 居中 等 第一次居中
  initData()
})

onBeforeUnmount(() => {
  // 移除监听 防止内存泄漏
  window.removeEventListener('resize', handleResize)
  window.removeEventListener('mouseup', onGlobalMouseUp)
})

// 暴露方法给父组件（如果需要）
defineExpose({
  ShowDrawData,
  fitScreen,
  MouseReset,
  SelectionBox,
  PaintingCircle,
  StartPaintingCircle,
})
</script>

<style lang="scss" scoped>
.paper_canvas {
  position: absolute;
  cursor: pointer;
  background-color: transparent;
  z-index: 10; // 使canvas在图片上方
  // border:1px solid green;
}

.img_container {
  position: absolute;
  cursor: pointer;
  z-index: 9;
  // border:1px solid red;
  img {
    width: 100%;
    height: 100%;
  }
}

.main_container {
  position: relative;
  overflow: hidden;
}
</style>