<script setup lang="ts">
import type { DomMarkingData, MarkingTool } from '../../composables/renderer/useMarkingDom'
import { useMessage } from 'wot-design-uni'
import { useSimpleDomLayer } from '../../composables/renderer/useMarkingDom'

interface Props {
  imageUrl: string
  scale?: number
  markingData?: DomMarkingData
  backgroundColor?: string
  currentTool: MarkingTool
  readOnly?: boolean
  adaptiveWidth?: boolean // 是否启用自适应宽度模式
  onQuickScore?: (value: number) => boolean
}

const props = withDefaults(defineProps<Props>(), {
  scale: 1,
  backgroundColor: '#ffffff',
  readOnly: false,
  adaptiveWidth: false,
})

const emit = defineEmits<{
  'layer-ready': [layerManager: ReturnType<typeof useSimpleDomLayer>]
  'quick-score': [value: number]
}>()

const scale = computed(() => {
  return props.scale
})

const currentTool = computed(() => {
  return props.currentTool
})

// Refs
const containerRef = ref<HTMLDivElement>()
const canvasRef = ref<HTMLDivElement>()

// 图片的自然尺寸
const naturalWidth = ref(0)
const naturalHeight = ref(0)

// 容器尺寸
const containerWidth = ref(0)
const containerHeight = ref(0)

// 计算实际使用的缩放比例
const actualScale = computed(() => {
  if (!props.adaptiveWidth || !naturalWidth.value || !containerWidth.value) {
    return props.scale
  }

  // 自适应宽度模式：计算适合容器宽度的缩放比例
  const adaptiveScale = containerWidth.value / naturalWidth.value
  return Math.min(adaptiveScale, props.scale) // 不超过原始设定的缩放比例
})

// 计算容器样式
const containerStyle = computed(() => {
  if (!naturalWidth.value || !naturalHeight.value) {
    return {
      width: props.adaptiveWidth ? '100%' : '100%',
      height: '400px',
      backgroundColor: props.backgroundColor,
    }
  }

  if (props.adaptiveWidth) {
    // 自适应模式：容器宽度100%，高度根据比例计算
    const scaledHeight = naturalHeight.value * actualScale.value
    return {
      width: '100%',
      height: `${scaledHeight}px`,
      backgroundColor: props.backgroundColor,
    }
  }
  else {
    // 固定缩放模式：根据缩放比例设置固定尺寸
    const scaledWidth = naturalWidth.value * actualScale.value
    const scaledHeight = naturalHeight.value * actualScale.value
    return {
      width: `${scaledWidth}px`,
      height: `${scaledHeight}px`,
      backgroundColor: props.backgroundColor,
    }
  }
})

// Canvas样式（应用缩放）
const canvasStyle = computed(() => {
  if (!naturalWidth.value || !naturalHeight.value) {
    return {
      width: '100%',
      height: '100%',
    }
  }

  return {
    width: `${naturalWidth.value}px`,
    height: `${naturalHeight.value}px`,
    transform: `scale(${actualScale.value})`,
    transformOrigin: 'top left',
  }
})

// Layer管理器
const message = useMessage()
const layerManager = useSimpleDomLayer({
  scale: actualScale,
  currentTool,
  initialData: props.markingData,
  onQuickScore: (value: number) => props.onQuickScore?.(value),
  readOnly: props.readOnly,
  message,
})
/**
 * 更新容器尺寸
 */
function updateContainerSize() {
  if (!canvasRef.value)
    return

  containerWidth.value = canvasRef.value.offsetWidth
  containerHeight.value = canvasRef.value.offsetHeight
}

/**
 * 初始化DOM画布
 */
async function initCanvas() {
  if (!canvasRef.value)
    return

  // 等待容器尺寸稳定
  await nextTick()

  // 更新容器尺寸
  updateContainerSize()

  // 加载图片获取尺寸
  await loadImage()

  // 触发ready事件
  emit('layer-ready', layerManager)
}

/**
 * 加载图片获取尺寸
 */
async function loadImage(): Promise<void> {
  return new Promise((resolve, reject) => {
    const img = new Image()

    img.onload = () => {
      // 记录图片自然尺寸
      naturalWidth.value = img.naturalWidth
      naturalHeight.value = img.naturalHeight
      resolve()
    }

    img.onerror = () => {
      reject(new Error(`Failed to load image: ${props.imageUrl}`))
    }

    img.src = props.imageUrl
  })
}

/**
 * 获取layer管理器
 */
const getLayerManager = () => layerManager

// 事件处理
function handleMouseDown(e: MouseEvent | TouchEvent) {
  if (!layerManager || !canvasRef.value)
    return
  const rect = canvasRef.value.getBoundingClientRect()
  layerManager.handleMouseDown(e, rect)
}

function handleMouseMove(e: MouseEvent | TouchEvent) {
  if (!layerManager || !canvasRef.value)
    return
  const rect = canvasRef.value.getBoundingClientRect()
  layerManager.handleMouseMove(e, rect)
}

function handleMouseUp() {
  if (!layerManager)
    return
  layerManager.handleMouseUp()
}

// 监听图片URL变化
watch(
  () => props.imageUrl,
  async () => {
    await loadImage()
  },
  { immediate: false },
)

// ResizeObserver实例
let resizeObserver: any = null

/**
 * 设置尺寸监听器
 */
function setupResizeObserver() {
  if (!props.adaptiveWidth || !containerRef.value)
    return

  if (typeof ResizeObserver !== 'undefined') {
    resizeObserver = new ResizeObserver((entries) => {
      for (const entry of entries) {
        const { width, height } = entry.contentRect
        containerWidth.value = width
        containerHeight.value = height
      }
    })

    resizeObserver.observe(containerRef.value)
  }
  else {
    // 备选方案：使用定时器监听尺寸变化
    let lastWidth = 0
    let lastHeight = 0

    const checkSizeChange = () => {
      if (!containerRef.value)
        return

      const newWidth = containerRef.value.offsetWidth || 0
      const newHeight = containerRef.value.offsetHeight || 0

      if (newWidth !== lastWidth || newHeight !== lastHeight) {
        lastWidth = newWidth
        lastHeight = newHeight
        containerWidth.value = newWidth
        containerHeight.value = newHeight
      }
    }

    resizeObserver = setInterval(checkSizeChange, 500)
  }
}

/**
 * 清理尺寸监听器
 */
function cleanupResizeObserver() {
  if (resizeObserver) {
    if (typeof ResizeObserver !== 'undefined' && resizeObserver.disconnect) {
      resizeObserver.disconnect()
    }
    else if (typeof resizeObserver === 'number') {
      clearInterval(resizeObserver)
    }
    resizeObserver = null
  }
}

// 暴露方法给父组件
defineExpose({
  getLayerManager,
  updateContainerSize,
})

// 组件挂载时初始化
onMounted(async () => {
  await initCanvas()
  if (props.adaptiveWidth) {
    setupResizeObserver()
  }
})

// 组件卸载时清理
onUnmounted(() => {
  cleanupResizeObserver()
})
</script>

<template>
  <div ref="containerRef" class="dom-image-renderer relative" :style="containerStyle">
    <div
      ref="canvasRef"
      class="canvas-container relative"
      :style="canvasStyle"
      @mousedown="handleMouseDown"
      @mousemove="handleMouseMove"
      @mouseup="handleMouseUp"
      @touchstart="handleMouseDown"
      @touchmove="handleMouseMove"
      @touchend="handleMouseUp"
    >
      <!-- 背景图片 -->
      <img
        :src="imageUrl"
        class="pointer-events-none absolute left-0 top-0 select-none"
        :style="{
          width: `${naturalWidth}px`,
          height: `${naturalHeight}px`,
        }"
        draggable="false"
      >

      <!-- 当前绘制中的形状 -->
      <template v-if="layerManager && layerManager.currentDrawingShape.value">
        <!-- 矩形 -->
        <div
          v-if="layerManager.currentDrawingShape.value.type === 'rect'"
          class="pointer-events-none absolute"
          :style="{
            left: `${layerManager.currentDrawingShape.value.x}px`,
            top: `${layerManager.currentDrawingShape.value.y}px`,
            width: `${layerManager.currentDrawingShape.value.width}px`,
            height: `${layerManager.currentDrawingShape.value.height}px`,
            border: `${layerManager.currentDrawingShape.value.strokeWidth}px solid ${layerManager.currentDrawingShape.value.stroke}`,
          }"
        />

        <!-- 线条 -->
        <svg
          v-else-if="layerManager.currentDrawingShape.value.type === 'line'"
          class="pointer-events-none absolute left-0 top-0"
          :width="naturalWidth"
          :height="naturalHeight"
        >
          <polyline
            :points="layerManager.currentDrawingShape.value.points?.join(' ')"
            :stroke="layerManager.currentDrawingShape.value.stroke"
            :stroke-width="layerManager.currentDrawingShape.value.strokeWidth"
            fill="none"
            stroke-linecap="round"
            stroke-linejoin="round"
          />
        </svg>
      </template>

      <!-- 已保存的形状 -->
      <template v-if="layerManager">
        <!-- 矩形 -->
        <div
          v-for="shape in layerManager.markingData.value.shapes.filter(s => s.type === 'rect')"
          :key="shape.id"
          class="pointer-events-none absolute"
          :style="{
            left: `${shape.x}px`,
            top: `${shape.y}px`,
            width: `${shape.width}px`,
            height: `${shape.height}px`,
            border: `${shape.strokeWidth}px solid ${shape.stroke}`,
          }"
        />

        <!-- 线条 -->
        <svg
          v-if="layerManager.markingData.value.shapes.some(s => s.type === 'line')"
          class="pointer-events-none absolute left-0 top-0"
          :width="naturalWidth"
          :height="naturalHeight"
        >
          <polyline
            v-for="shape in layerManager.markingData.value.shapes.filter(s => s.type === 'line')"
            :key="shape.id"
            :points="shape.points?.join(' ')"
            :stroke="shape.stroke"
            :stroke-width="shape.strokeWidth"
            fill="none"
            stroke-linecap="round"
            stroke-linejoin="round"
          />
        </svg>

        <!-- 特殊标记 -->
        <div
          v-for="mark in layerManager.markingData.value.specialMarks"
          :key="mark.id"
          class="pointer-events-none absolute"
          :style="{
            left: `${mark.x - 10}px`,
            top: `${mark.y - 10}px`,
            width: '20px',
            height: '20px',
          }"
        >
          <!-- 正确标记 ✓ -->
          <svg v-if="mark.type === 'correct'" width="20" height="20" viewBox="0 0 20 20">
            <polyline
              points="2,8 7,14 18,2"
              stroke="#ff4d4f"
              stroke-width="3"
              fill="none"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
          </svg>

          <!-- 错误标记 ✗ -->
          <svg v-else-if="mark.type === 'wrong'" width="20" height="20" viewBox="0 0 20 20">
            <line x1="2" y1="2" x2="18" y2="18" stroke="#ff4d4f" stroke-width="3" stroke-linecap="round" />
            <line x1="18" y1="2" x2="2" y2="18" stroke="#ff4d4f" stroke-width="3" stroke-linecap="round" />
          </svg>

          <!-- 半对标记 -->
          <svg v-else-if="mark.type === 'half'" width="20" height="20" viewBox="0 0 20 20">
            <polyline
              points="2,8 7,14 18,2"
              stroke="#ff4d4f"
              stroke-width="3"
              fill="none"
              stroke-linecap="round"
              stroke-linejoin="round"
            />
            <line x1="7" y1="2" x2="20" y2="12" stroke="#ff4d4f" stroke-width="3" stroke-linecap="round" />
          </svg>
        </div>

        <!-- 文本注释 -->
        <div
          v-for="annotation in layerManager.markingData.value.annotations"
          :key="annotation.id"
          class="pointer-events-none absolute whitespace-nowrap font-bold"
          :style="{
            left: `${annotation.x}px`,
            top: `${annotation.y}px`,
            fontSize: `${annotation.fontSize}px`,
            color: annotation.color,
          }"
        >
          {{ annotation.text }}
        </div>
      </template>
    </div>
  </div>
</template>

<style scoped>
.dom-image-renderer {
  display: inline-block;
  overflow: hidden;
  user-select: none;
}

.canvas-container {
  cursor: crosshair;
  touch-action: none;
}

.canvas-container img {
  user-select: none;
  -webkit-user-drag: none;
}
</style>
