<script setup lang="ts">
import type { KonvaMarkingData, MarkingTool } from '../../composables/renderer/useMarkingKonva'
import Konva from 'konva'

import { useMessage } from 'wot-design-uni'
import { useSimpleKonvaLayer } from '../../composables/renderer/useMarkingKonva'

interface Props {
  imageUrl: string
  scale?: number
  markingData?: KonvaMarkingData
  backgroundColor?: string
  currentTool: MarkingTool
}

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

const emit = defineEmits<{
  'layer-ready': [layerManager: ReturnType<typeof useSimpleKonvaLayer>]
}>()

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

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

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

// Konva实例
let stage: Konva.Stage | null = null
let layer: Konva.Layer | null = null

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

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

  const scaledWidth = naturalWidth.value * props.scale
  const scaledHeight = naturalHeight.value * props.scale

  return {
    width: `${scaledWidth}px`,
    height: `${scaledHeight}px`,
    backgroundColor: props.backgroundColor,
  }
})

// Layer管理器
let layerManager: ReturnType<typeof useSimpleKonvaLayer> | null = null
const message = useMessage()

/**
 * 初始化Konva画布
 */
async function initKonva() {
  if (!konvaContainer.value)
    return

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

  const containerWidth = konvaContainer.value.offsetWidth
  const containerHeight = konvaContainer.value.offsetHeight

  // 创建Stage
  const newStage = new Konva.Stage({
    container: konvaContainer.value,
    width: containerWidth,
    height: containerHeight,
  })

  // 创建Layer
  const newLayer = new Konva.Layer()
  newStage.add(newLayer)

  stage = newStage
  layer = newLayer

  // 加载图片
  await loadImage()

  // 创建layer管理器
  layerManager = useSimpleKonvaLayer({
    layer: newLayer,
    scale,
    currentTool,
    initialData: props.markingData,
    message,
  })
  layerManager.initializeEvents()

  // 如果有初始数据，渲染它
  if (props.markingData) {
    layerManager.renderMarkingData()
  }

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

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

    img.onload = () => {
      if (!layer || !stage) {
        reject(new Error('Konva not initialized'))
        return
      }

      // 记录图片自然尺寸
      naturalWidth.value = img.naturalWidth
      naturalHeight.value = img.naturalHeight

      // 创建Konva图片节点
      const image = new Konva.Image({
        x: 0,
        y: 0,
        image: img,
        width: img.naturalWidth,
        height: img.naturalHeight,
      })

      // 清空layer并添加图片
      layer.destroyChildren()
      layer.add(image)

      // 应用缩放和标记数据
      applyScale()

      layer.draw()
      resolve()
    }

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

    img.src = props.imageUrl
  })
}

/**
 * 应用缩放
 */
function applyScale() {
  if (!layer || !stage)
    return

  // 重置layer的变换
  layer.scale({ x: props.scale, y: props.scale })
  layer.offset({ x: 0, y: 0 })
  layer.position({ x: 0, y: 0 })

  // 更新stage尺寸以适应缩放后的图片
  const scaledWidth = naturalWidth.value * props.scale
  const scaledHeight = naturalHeight.value * props.scale

  stage.size({
    width: scaledWidth,
    height: scaledHeight,
  })

  layer.draw()
}

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

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

// 监听缩放变化
watch(
  () => props.scale,
  () => {
    applyScale()
  },
)

// 暴露方法给父组件
defineExpose({
  getLayerManager,
  getStage: () => stage,
  getLayer: () => layer,
})

// 组件挂载时初始化
onMounted(async () => {
  await initKonva()
})

// 组件卸载时清理
onUnmounted(() => {
  layerManager?.cleanupEvents()
  stage?.destroy()
})
</script>

<template>
  <div ref="containerRef" class="konva-image-renderer relative" :style="containerStyle">
    <div ref="konvaContainer" class="h-full w-full" />
  </div>
</template>

<style scoped>
.konva-image-renderer {
  display: inline-block;
  overflow: hidden;
}
</style>
