/* eslint-disable ts/no-use-before-define */
import type { Ref } from 'vue'
import type { useMessage } from 'wot-design-uni'
import Konva from 'konva'
import { computed, ref } from 'vue'
import { markingSettings } from '../useMarkingSettings'
import { useMarkingCommand } from './useMarkingCommand'
import { useMarkingTools } from './useMarkingTools'

export enum MarkingTool {
  SELECT = 'select',
  RECT = 'rect',
  TEXT = 'text',
  PEN = 'pen',
  CORRECT = 'correct',
  WRONG = 'wrong',
  HALF = 'half',
  ERASER = 'eraser',
}

export interface KonvaShape {
  id: string
  type: string
  x: number
  y: number
  width?: number
  height?: number
  points?: number[]
  text?: string
  fontSize?: number
  fill?: string
  stroke?: string
  strokeWidth?: number
  [key: string]: any
}

export interface SpecialMark {
  id: string
  type: 'correct' | 'wrong' | 'half'
  x: number
  y: number
}

export interface TextAnnotation {
  id: string
  x: number
  y: number
  text: string
  fontSize: number
  color: string
}

export interface KonvaMarkingData {
  version: string
  shapes: KonvaShape[]
  specialMarks: SpecialMark[]
  annotations: TextAnnotation[]
}

interface SimpleKonvaLayerProps {
  layer: Konva.Layer
  scale: Ref<number>
  currentTool: Ref<MarkingTool>
  initialData?: KonvaMarkingData
  /** 位移配置，用于多层叠加渲染 */
  offset?: {
    x: number
    y: number
  }
  /** 快捷打分回调 */
  onQuickScore?: (value: number) => void
  /** 只读模式，不响应交互事件 */
  readOnly?: boolean
  message: ReturnType<typeof useMessage>
}

/**
 * 简化的Konva图层管理器
 * 专注于绘制和数据管理，历史记录交给命令模式处理
 */
export function useSimpleKonvaLayer({
  layer,
  scale,
  currentTool,
  initialData,
  offset = { x: 0, y: 0 },
  onQuickScore,
  readOnly = false,
  message,
}: SimpleKonvaLayerProps) {
  const tools = useMarkingTools()
  const stage = layer.getStage()!

  // 标记数据
  const markingData = ref<KonvaMarkingData>(
    initialData || {
      version: '1.0',
      shapes: [],
      specialMarks: [],
      annotations: [],
    },
  )

  // 命令系统
  const commandSystem = useMarkingCommand()

  // 当前绘制状态
  const isDrawing = ref(false)
  const currentShape = ref<Konva.Shape | null>(null)

  // 计算属性
  const hasMarks = computed(() => {
    return (
      markingData.value.shapes.length > 0
      || markingData.value.specialMarks.length > 0
      || markingData.value.annotations.length > 0
    )
  })

  /**
   * 初始化事件监听
   */
  const initializeEvents = () => {
    if (readOnly) {
      // 只读模式下不绑定交互事件
      return
    }

    layer.off() // 清除旧事件
    layer.on('mousedown touchstart', handleMouseDown)
    layer.on('mousemove touchmove', handleMouseMove)
    layer.on('mouseup touchend', handleMouseUp)
  }

  /**
   * 清理事件监听
   */
  const cleanupEvents = () => {
    layer.off()
  }

  /**
   * 鼠标按下事件
   */
  const handleMouseDown = (e: Konva.KonvaEventObject<MouseEvent | TouchEvent>) => {
    const target = e.target
    const clickedOnExistingShape = target !== (layer as any) && target.getClassName() !== 'Image'

    // 如果快捷打分点击模式激活，且当前没有选择任何工具，优先处理（仅左键）
    if (markingSettings.value.quickScoreClickMode && currentTool.value === MarkingTool.SELECT) {
      const mouseEvent = e.evt as MouseEvent
      // 只处理左键点击（button === 0）
      if (mouseEvent.button === 0) {
        const pos = getRelativePosition()
        if (pos) {
          handleQuickScoreClick(pos)
        }
      }
      return
    }

    // 如果点击在已有形状上且当前是矩形或文本工具，则不创建新形状
    if (
      clickedOnExistingShape
      && (currentTool.value === MarkingTool.RECT
        || currentTool.value === MarkingTool.TEXT
        || currentTool.value === MarkingTool.PEN)
    ) {
      return
    }

    const pos = getRelativePosition()
    if (!pos)
      return

    isDrawing.value = true

    switch (currentTool.value) {
      case MarkingTool.PEN:
        startPenDrawing(pos)
        break
      case MarkingTool.RECT:
        if (!clickedOnExistingShape) {
          startRectDrawing(pos)
        }
        break
      case MarkingTool.CORRECT:
        addSpecialMark('correct', pos)
        break
      case MarkingTool.WRONG:
        addSpecialMark('wrong', pos)
        break
      case MarkingTool.HALF:
        addSpecialMark('half', pos)
        break
      case MarkingTool.TEXT:
        addTextAnnotation(pos)
        break
      case MarkingTool.ERASER:
        console.log('[SimpleKonvaLayer] handleMouseDown - erasing at:', pos, e)
        eraseAt(pos)
        break
    }
  }

  /**
   * 鼠标移动事件
   */
  const handleMouseMove = () => {
    if (!isDrawing.value || (!currentShape.value && currentTool.value !== MarkingTool.ERASER))
      return

    const pos = getRelativePosition()
    if (!pos)
      return

    if (currentTool.value === MarkingTool.PEN) {
      continuePenDrawing(pos)
    }
    else if (currentTool.value === MarkingTool.RECT) {
      continueRectDrawing(pos)
    }
    else if (currentTool.value === MarkingTool.ERASER) {
      eraseAt(pos)
    }

    layer.draw()
  }

  /**
   * 鼠标抬起事件
   */
  const handleMouseUp = () => {
    if (!isDrawing.value)
      return

    if (currentShape.value) {
      finishDrawing()
    }

    isDrawing.value = false
    currentShape.value = null
  }

  /**
   * 获取相对位置（应用位移偏移）
   */
  const getRelativePosition = () => {
    const pos = stage.getPointerPosition()
    if (!pos)
      return null

    return {
      x: (pos.x - layer.x()) / scale.value - offset.x,
      y: (pos.y - layer.y()) / scale.value - offset.y,
    }
  }

  /**
   * 开始笔绘制
   */
  const startPenDrawing = (pos: { x: number, y: number }) => {
    const line = tools.createLine([pos.x, pos.y], {
      stroke: markingSettings.value.penColor,
      strokeWidth: markingSettings.value.penWidth,
    })
    currentShape.value = line
    layer.add(line)
    layer.draw()
  }

  /**
   * 继续笔绘制
   */
  const continuePenDrawing = (pos: { x: number, y: number }) => {
    const line = currentShape.value as Konva.Line
    if (line) {
      const newPoints = line.points().concat([Number(pos.x.toFixed(1)), Number(pos.y.toFixed(1))])
      line.points(newPoints)
    }
  }

  /**
   * 开始矩形绘制
   */
  const startRectDrawing = (pos: { x: number, y: number }) => {
    const rect = tools.createRect(pos.x, pos.y, 0, 0)
    currentShape.value = rect;
    (rect as any).startPos = pos
    layer.add(rect)
    layer.draw()
  }

  /**
   * 继续矩形绘制
   */
  const continueRectDrawing = (pos: { x: number, y: number }) => {
    const rect = currentShape.value as Konva.Rect
    if (rect && (rect as any).startPos) {
      const startPos = (rect as any).startPos
      const width = pos.x - startPos.x
      const height = pos.y - startPos.y

      rect.width(Math.abs(width))
      rect.height(Math.abs(height))
      rect.x(width < 0 ? pos.x : startPos.x)
      rect.y(height < 0 ? pos.y : startPos.y)
    }
  }

  /**
   * 完成绘制
   */
  const finishDrawing = () => {
    if (!currentShape.value)
      return

    const shape = convertKonvaShapeToData(currentShape.value as Konva.Shape)
    if (shape) {
      console.log('[SimpleKonvaLayer] finishDrawing - creating AddShapeCommand for:', shape)
      const command = new commandSystem.AddShapeCommand(markingData.value, shape, layer)
      commandSystem.executeCommand(command)

      // 命令执行后重新渲染layer
      renderMarkingData()
    }
  }

  /**
   * 添加特殊标记
   */
  const addSpecialMark = (type: 'correct' | 'wrong' | 'half', pos: { x: number, y: number }) => {
    const mark: SpecialMark = {
      id: `mark_${Date.now()}_${Math.random()}`,
      type,
      x: pos.x,
      y: pos.y,
    }

    console.log('[SimpleKonvaLayer] addSpecialMark - creating AddSpecialMarkCommand for:', mark)
    const command = new commandSystem.AddSpecialMarkCommand(markingData.value, mark, layer)
    commandSystem.executeCommand(command)

    // 命令执行后重新渲染layer
    renderMarkingData()
    isDrawing.value = false
  }

  /**
   * 添加文本注释
   */
  const addTextAnnotation = async (pos: { x: number, y: number }) => {
    const text = await message.show({
      title: '请输入文字:',
      type: 'prompt',
    }).then((res) => {
      return res.value
    })
    if (text) {
      const annotation: TextAnnotation = {
        id: `text_${Date.now()}_${Math.random()}`,
        x: pos.x,
        y: pos.y,
        text: text.toString(),
        fontSize: markingSettings.value.textSize,
        color: markingSettings.value.textColor,
      }

      console.log(
        '[SimpleKonvaLayer] addTextAnnotation - creating AddTextCommand for:',
        annotation,
      )
      const command = new commandSystem.AddTextCommand(markingData.value, annotation, layer)
      commandSystem.executeCommand(command)

      // 命令执行后重新渲染layer
      renderMarkingData()
    }

    isDrawing.value = false
  }

  /**
   * 擦除指定位置的元素
   */
  const eraseAt = (pos: { x: number, y: number }) => {
    const shape = layer.getIntersection(pos)
    console.log('[SimpleKonvaLayer] eraseAt - found shape:', shape)
    if (shape && shape.getClassName() !== 'Image') {
      const id = shape.id() ? shape.id() : shape.parent?.id()

      if (id) {
        console.log('[SimpleKonvaLayer] eraseAt - creating EraseCommand for:', id)
        const command = new commandSystem.EraseCommand(markingData.value, id, layer)
        commandSystem.executeCommand(command)

        // 命令执行后重新渲染layer
        renderMarkingData()
      }
    }
  }

  /**
   * 处理快捷打分点击
   */
  const handleQuickScoreClick = (pos: { x: number, y: number }) => {
    const value = markingSettings.value.quickScoreClickValue
    const scoreMode = markingSettings.value.scoreMode
    const finalValue = scoreMode === 'add' ? value : -value

    // 创建文字标记
    const text = scoreMode === 'add' ? `+${value}` : `-${value}`
    const annotation: TextAnnotation = {
      id: `quick_score_${Date.now()}_${Math.random()}`,
      x: pos.x,
      y: pos.y,
      text,
      fontSize: 48,
      color: scoreMode === 'add' ? '#ff4d4f' : '#1890ff',
    }

    console.log('[SimpleKonvaLayer] handleQuickScoreClick - creating text annotation:', annotation)
    const command = new commandSystem.AddTextCommand(markingData.value, annotation, layer)
    commandSystem.executeCommand(command)

    // 命令执行后重新渲染layer
    renderMarkingData()

    // 回调通知外部组件更新分数
    if (onQuickScore) {
      onQuickScore(finalValue)
    }

    isDrawing.value = false
  }

  /**
   * 将Konva形状转换为数据格式
   */
  const convertKonvaShapeToData = (shape: Konva.Shape): KonvaShape | null => {
    const id = shape.id() || `shape_${Date.now()}_${Math.random()}`
    shape.id(id)

    if (shape instanceof Konva.Line) {
      return {
        id,
        type: 'line',
        x: shape.x(),
        y: shape.y(),
        points: shape.points(),
        stroke: shape.stroke() as string,
        strokeWidth: shape.strokeWidth(),
      }
    }
    else if (shape instanceof Konva.Rect) {
      return {
        id,
        type: 'rect',
        x: shape.x(),
        y: shape.y(),
        width: shape.width(),
        height: shape.height(),
        stroke: shape.stroke() as string,
        strokeWidth: shape.strokeWidth(),
      }
    }

    return null
  }

  /**
   * 清空所有标记
   */
  const clearAllMarks = () => {
    console.log('[SimpleKonvaLayer] clearAllMarks - creating ClearAllCommand')
    const command = new commandSystem.ClearAllCommand(markingData.value, layer)
    commandSystem.executeCommand(command)

    // 命令执行后重新渲染layer
    renderMarkingData()
  }

  /**
   * 渲染标记数据到layer
   */
  const renderMarkingData = () => {
    console.log('[SimpleKonvaLayer] renderMarkingData called, current data:', {
      shapes: markingData.value.shapes.length,
      specialMarks: markingData.value.specialMarks.length,
      annotations: markingData.value.annotations.length,
      data: markingData.value,
    })

    // 清空layer（保留图片）
    const children = layer.getChildren().slice()
    console.log('[SimpleKonvaLayer] clearing layer, found children:', children.length)
    children.forEach((child) => {
      if (child.getClassName() !== 'Image') {
        child.remove()
        child.destroy()
      }
    })

    // 渲染形状（应用位移偏移）
    markingData.value.shapes.forEach((shape) => {
      console.log('[SimpleKonvaLayer] rendering shape:', shape)
      let node: Konva.Shape
      if (shape.type === 'rect') {
        node = tools.createRect(
          shape.x + offset.x,
          shape.y + offset.y,
          shape.width!,
          shape.height!,
          shape,
        )
      }
      else if (shape.type === 'line') {
        // 对线条的所有点应用偏移
        const offsetPoints = shape.points!.map((point, index) => {
          return index % 2 === 0 ? point + offset.x : point + offset.y
        })
        node = tools.createLine(offsetPoints, shape)
      }
      else {
        console.warn('[SimpleKonvaLayer] unknown shape type:', shape.type)
        return
      }
      node.id(shape.id)
      layer.add(node)
    })

    // 渲染特殊标记（应用位移偏移）
    markingData.value.specialMarks.forEach((mark) => {
      console.log('[SimpleKonvaLayer] rendering special mark:', mark)
      const node = tools.createSpecialMark(mark.type, mark.x + offset.x, mark.y + offset.y)
      node.id(mark.id)
      layer.add(node)
    })

    // 渲染文本（应用位移偏移）
    markingData.value.annotations.forEach((annotation) => {
      console.log('[SimpleKonvaLayer] rendering annotation:', annotation)
      const node = tools.createText(
        annotation.x + offset.x,
        annotation.y + offset.y,
        annotation.text,
        annotation,
      )
      node.id(annotation.id)
      layer.add(node)
    })

    layer.draw()
    console.log('[SimpleKonvaLayer] renderMarkingData completed, layer redrawn')
  }

  return {
    // 数据状态
    markingData,
    hasMarks,

    // 历史记录状态
    canUndo: commandSystem.canUndo,
    canRedo: commandSystem.canRedo,

    // 初始化和清理
    initializeEvents,
    cleanupEvents,
    renderMarkingData,

    // 操作方法
    clearAllMarks,
    undo: () => {
      console.log('[SimpleKonvaLayer] undo triggered')
      const result = commandSystem.undo()
      if (result) {
        renderMarkingData()
      }
      return result
    },
    redo: () => {
      console.log('[SimpleKonvaLayer] redo triggered')
      const result = commandSystem.redo()
      if (result) {
        renderMarkingData()
      }
      return result
    },

    // 数据导入导出
    exportData: () => JSON.stringify(markingData.value),
    importData: (data: string) => {
      try {
        markingData.value = JSON.parse(data)
        renderMarkingData()
        return true
      }
      catch {
        return false
      }
    },
  }
}
