<template>
  <div class="image-canvas-container">
    <div class="canvas-toolbar">
      <a-button-group>
        <a-button @click="zoomIn" :disabled="scale >= 5">
          <template #icon><icon-zoom-in /></template>
          放大
        </a-button>
        <a-button @click="zoomOut" :disabled="scale <= 0.1">
          <template #icon><icon-zoom-out /></template>
          缩小
        </a-button>
        <a-button @click="resetZoom">
          <template #icon><icon-refresh /></template>
          重置
        </a-button>
        <a-button @click="fitToScreen">
          <template #icon><icon-fullscreen /></template>
          适应屏幕
        </a-button>
      </a-button-group>
      
      <a-button-group>
        <a-button 
          :type="drawMode === 'rectangle' ? 'primary' : 'secondary'"
          @click="setDrawMode('rectangle')"
        >
          <template #icon><icon-minus-circle /></template>
          矩形
        </a-button>
        <a-button 
          :type="drawMode === 'move' ? 'primary' : 'secondary'"
          @click="setDrawMode('move')"
        >
          <template #icon><icon-drag-dot /></template>
          移动
        </a-button>
      </a-button-group>
      
      <a-button-group>
        <a-button @click="clearAnnotations" type="outline" status="danger">
          <template #icon><icon-delete /></template>
          清空标注
        </a-button>
        <a-button @click="finishAnnotation" type="primary" :disabled="annotations.length === 0">
          <template #icon><icon-check /></template>
          完成标注
        </a-button>
      </a-button-group>
    </div>
    
    <div class="canvas-wrapper" ref="canvasWrapper">
      <canvas
        ref="canvas"
        @mousedown="handleMouseDown"
        @mousemove="handleMouseMove"
        @mouseup="handleMouseUp"
        @wheel="handleWheel"
        @click="handleClick"
        @dblclick="handleDoubleClick"
        @contextmenu="handleContextMenu"
      />
    </div>
    
    <div class="canvas-info">
      <span>缩放: {{ Math.round(scale * 100) }}%</span>
      <span v-if="currentAnnotation">正在绘制矩形</span>
      <span v-if="annotations.length > 0">已绘制: {{ annotations.length }} 个区域</span>
      <span v-if="annotations.length > 0" class="info-tip">点击"完成标注"提交所有区域</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { 
  IconZoomIn, 
  IconZoomOut, 
  IconRefresh, 
  IconFullscreen,
  IconMinusCircle,
  IconDragDot,
  IconDelete,
  IconCheck
} from '@arco-design/web-vue/es/icon'

export interface Point {
  x: number
  y: number
}

export interface Rectangle {
  x: number
  y: number
  width: number
  height: number
}

export interface Annotation {
  id: string
  type: 'rectangle'
  points: Point[]
  color: string
  label?: string
  metadata?: {
    isMultiAnnotation?: boolean
    attachId?: string
    attachPath?: string
    attachInfo?: any
    allAnnotations?: Annotation[]
    [key: string]: any
  }
}

export interface ImageData {
  imageId: string
  imagePath: string
  imageName: string
}

const props = defineProps<{
  selectedImage?: ImageData
  annotations?: Annotation[]
}>()

const emit = defineEmits<{
  annotationAdd: [annotation: Annotation]
  annotationUpdate: [annotation: Annotation]
  annotationDelete: [annotationId: string]
  annotationFinish: [annotations: Annotation[], imageBlob: Blob]
}>()

const canvas = ref<HTMLCanvasElement>()
const canvasWrapper = ref<HTMLDivElement>()
const ctx = ref<CanvasRenderingContext2D>()

const scale = ref(1)
const offsetX = ref(0)
const offsetY = ref(0)

type DrawMode = 'rectangle' | 'move'
const drawMode = ref<DrawMode>('move')

const isDragging = ref(false)
const isDrawing = ref(false)
const dragStart = ref<Point>({ x: 0, y: 0 })
const currentAnnotation = ref<Annotation | null>(null)
const annotations = ref<Annotation[]>([])

const image = ref<HTMLImageElement>()
const imageLoaded = ref(false)

const setDrawMode = (mode: DrawMode) => {
  drawMode.value = mode
  finishCurrentAnnotation()
}

const finishCurrentAnnotation = () => {
  if (currentAnnotation.value) {
    if (currentAnnotation.value.type === 'rectangle' && currentAnnotation.value.points.length >= 2) {
      annotations.value.push(currentAnnotation.value)
      // 不再立即触发annotationAdd事件，等待用户完成所有标注
    }
    currentAnnotation.value = null
  }
}

const finishAnnotation = async () => {
  if (annotations.value.length === 0) return
  
  try {
    // 导出带有标注的图片
    const imageBlob = await exportAnnotatedImage()
    
    // 触发完成标注事件，传递所有标注和图片blob
    emit('annotationFinish', [...annotations.value], imageBlob)
    
    // 清空当前标注
    annotations.value = []
    currentAnnotation.value = null
    redraw()
  } catch (error) {
    console.error('导出标注图片失败:', error)
  }
}

const exportAnnotatedImage = (): Promise<Blob> => {
  return new Promise((resolve, reject) => {
    if (!canvas.value) {
      reject(new Error('Canvas not found'))
      return
    }
    
    canvas.value.toBlob((blob) => {
      if (blob) {
        resolve(blob)
      } else {
        reject(new Error('Failed to export canvas as blob'))
      }
    }, 'image/png')
  })
}

const clearAnnotations = () => {
  annotations.value = []
  currentAnnotation.value = null
  redraw()
}

const zoomIn = () => {
  if (scale.value < 5) {
    scale.value = Math.min(5, scale.value * 1.2)
    redraw()
  }
}

const zoomOut = () => {
  if (scale.value > 0.1) {
    scale.value = Math.max(0.1, scale.value / 1.2)
    redraw()
  }
}

const resetZoom = () => {
  scale.value = 1
  offsetX.value = 0
  offsetY.value = 0
  centerImage()
  redraw()
}

const fitToScreen = () => {
  if (!image.value || !canvas.value) return
  
  const dpr = window.devicePixelRatio || 1
  const canvasWidth = canvas.value.width / dpr
  const canvasHeight = canvas.value.height / dpr
  const imageWidth = image.value.naturalWidth
  const imageHeight = image.value.naturalHeight
  
  const scaleX = canvasWidth / imageWidth
  const scaleY = canvasHeight / imageHeight
  
  scale.value = Math.min(scaleX, scaleY, 1)
  centerImage()
  redraw()
}

const centerImage = () => {
  if (!image.value || !canvas.value) return
  
  const dpr = window.devicePixelRatio || 1
  const canvasWidth = canvas.value.width / dpr
  const canvasHeight = canvas.value.height / dpr
  const imageWidth = image.value.naturalWidth * scale.value
  const imageHeight = image.value.naturalHeight * scale.value
  
  offsetX.value = (canvasWidth - imageWidth) / 2
  offsetY.value = (canvasHeight - imageHeight) / 2
}

const getMousePos = (event: MouseEvent): Point => {
  const rect = canvas.value?.getBoundingClientRect()
  if (!rect) return { x: 0, y: 0 }
  
  // 获取鼠标在canvas中的像素位置
  const canvasX = event.clientX - rect.left
  const canvasY = event.clientY - rect.top
  
  // 转换为图像坐标系
  const imageX = (canvasX - offsetX.value) / scale.value
  const imageY = (canvasY - offsetY.value) / scale.value
  
  return {
    x: imageX,
    y: imageY
  }
}

const handleMouseDown = (event: MouseEvent) => {
  event.preventDefault()
  
  if (drawMode.value === 'move') {
    isDragging.value = true
    dragStart.value = { x: event.clientX, y: event.clientY }
  }
}

const handleMouseMove = (event: MouseEvent) => {
  if (isDragging.value && drawMode.value === 'move') {
    const deltaX = event.clientX - dragStart.value.x
    const deltaY = event.clientY - dragStart.value.y
    
    offsetX.value += deltaX
    offsetY.value += deltaY
    
    dragStart.value = { x: event.clientX, y: event.clientY }
    redraw()
  }
  
  if (isDrawing.value && drawMode.value === 'rectangle' && currentAnnotation.value) {
    const mousePos = getMousePos(event)
    if (currentAnnotation.value.points.length >= 1) {
      currentAnnotation.value.points[1] = mousePos
      redraw()
    }
  }
}

const handleMouseUp = () => {
  isDragging.value = false
  isDrawing.value = false
}

const handleClick = (event: MouseEvent) => {
  if (drawMode.value === 'move') return
  
  const mousePos = getMousePos(event)
  
  if (drawMode.value === 'rectangle') {
    if (!currentAnnotation.value) {
      currentAnnotation.value = {
        id: Date.now().toString(),
        type: 'rectangle',
        points: [mousePos],
        color: '#ff4d4f'
      }
      isDrawing.value = true
    } else {
      currentAnnotation.value.points[1] = mousePos
      finishCurrentAnnotation()
      isDrawing.value = false
    }
  }
}

const handleDoubleClick = (event: MouseEvent) => {
  // 双击事件不需要处理，只有矩形绘制
}

const handleContextMenu = (event: MouseEvent) => {
  event.preventDefault()
  // 右键菜单不需要处理，只有矩形绘制
}

const handleWheel = (event: WheelEvent) => {
  event.preventDefault()
  
  const delta = event.deltaY > 0 ? 0.9 : 1.1
  const newScale = Math.max(0.1, Math.min(5, scale.value * delta))
  
  const rect = canvas.value?.getBoundingClientRect()
  if (!rect) return
  
  const mouseX = event.clientX - rect.left
  const mouseY = event.clientY - rect.top
  
  const scaleDiff = newScale - scale.value
  offsetX.value -= (mouseX - offsetX.value) * scaleDiff / scale.value
  offsetY.value -= (mouseY - offsetY.value) * scaleDiff / scale.value
  
  scale.value = newScale
  redraw()
}

const redraw = () => {
  if (!ctx.value || !canvas.value) return
  
  const dpr = window.devicePixelRatio || 1
  const canvasWidth = canvas.value.width / dpr
  const canvasHeight = canvas.value.height / dpr
  
  ctx.value.clearRect(0, 0, canvasWidth, canvasHeight)
  
  if (image.value && imageLoaded.value) {
    ctx.value.save()
    ctx.value.translate(offsetX.value, offsetY.value)
    ctx.value.scale(scale.value, scale.value)
    // 使用图像的原始尺寸
    ctx.value.drawImage(image.value, 0, 0, image.value.naturalWidth, image.value.naturalHeight)
    ctx.value.restore()
  }
  
  drawAnnotations()
}

const drawAnnotations = () => {
  if (!ctx.value) return
  
  ctx.value.save()
  ctx.value.translate(offsetX.value, offsetY.value)
  ctx.value.scale(scale.value, scale.value)
  
  const allAnnotations = [...annotations.value]
  if (currentAnnotation.value) {
    allAnnotations.push(currentAnnotation.value)
  }
  
  allAnnotations.forEach(annotation => {
    if (!annotation || annotation.points.length === 0) return
    
    ctx.value!.strokeStyle = annotation.color
    ctx.value!.lineWidth = 2 / scale.value
    ctx.value!.fillStyle = annotation.color + '20'
    
    if (annotation.type === 'rectangle' && annotation.points.length >= 2) {
      const [start, end] = annotation.points
      const width = end.x - start.x
      const height = end.y - start.y
      
      ctx.value!.strokeRect(start.x, start.y, width, height)
      ctx.value!.fillRect(start.x, start.y, width, height)
    }
  })
  
  ctx.value.restore()
}

const loadImage = (imagePath: string) => {
  if (!imagePath) return
  
  image.value = new Image()
  image.value.onload = () => {
    imageLoaded.value = true
    // 图像加载完成后自动适应屏幕
    nextTick(() => {
      fitToScreen()
    })
  }
  
  image.value.onerror = () => {
    console.error('Failed to load image:', imagePath)
    imageLoaded.value = false
  }
  
  // 设置crossOrigin以支持跨域图像
  image.value.crossOrigin = 'anonymous'
  
  if (imagePath.startsWith('http')) {
    image.value.src = imagePath
  } else {
    image.value.src = `http://pms.dtyx.net:9158${imagePath}`
  }
}

const resizeCanvas = () => {
  if (!canvas.value || !canvasWrapper.value) return
  
  const rect = canvasWrapper.value.getBoundingClientRect()
  const dpr = window.devicePixelRatio || 1
  
  // 设置canvas的实际尺寸
  canvas.value.width = rect.width * dpr
  canvas.value.height = rect.height * dpr
  
  // 设置canvas的显示尺寸
  canvas.value.style.width = rect.width + 'px'
  canvas.value.style.height = rect.height + 'px'
  
  // 缩放绘图上下文以匹配设备像素比
  if (ctx.value) {
    ctx.value.scale(dpr, dpr)
  }
  
  // 重新计算偏移量，因为canvas尺寸发生了变化
  if (image.value && imageLoaded.value) {
    centerImage()
  }
  
  redraw()
}

onMounted(() => {
  if (canvas.value) {
    ctx.value = canvas.value.getContext('2d')
    // 延迟执行以确保DOM已经渲染完成
    nextTick(() => {
      resizeCanvas()
    })
  }
  
  window.addEventListener('resize', resizeCanvas)
})

onUnmounted(() => {
  window.removeEventListener('resize', resizeCanvas)
})

watch(() => props.selectedImage, (newImage) => {
  if (newImage?.imagePath) {
    loadImage(newImage.imagePath)
    clearAnnotations()
  }
}, { immediate: true })

watch(() => props.annotations, (newAnnotations) => {
  if (newAnnotations) {
    annotations.value = [...newAnnotations]
    redraw()
  }
}, { immediate: true })
</script>

<style scoped lang="scss">
.image-canvas-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #f5f5f5;
}

.canvas-toolbar {
  display: flex;
  gap: 12px;
  padding: 12px;
  background: white;
  border-bottom: 1px solid #e5e7eb;
  align-items: center;
  
  .arco-btn-group {
    display: flex;
    gap: 0;
    
    .arco-btn {
      border-radius: 0;
      
      &:first-child {
        border-top-left-radius: 6px;
        border-bottom-left-radius: 6px;
      }
      
      &:last-child {
        border-top-right-radius: 6px;
        border-bottom-right-radius: 6px;
      }
    }
  }
}

.canvas-wrapper {
  flex: 1;
  position: relative;
  overflow: hidden;
  min-height: 0;
  
  canvas {
    display: block;
    cursor: crosshair;
    background: #ffffff;
    border: 1px solid #e5e7eb;
    
    &.dragging {
      cursor: grabbing;
    }
  }
}

.canvas-info {
  display: flex;
  gap: 16px;
  padding: 8px 12px;
  background: white;
  border-top: 1px solid #e5e7eb;
  font-size: 12px;
  color: #666;
  
  span {
    padding: 2px 8px;
    background: #f0f0f0;
    border-radius: 4px;
    
    &.info-tip {
      background: #e6f7ff;
      color: #1890ff;
      font-size: 11px;
    }
  }
}
</style>