import { computed, ref } from 'vue'

/**
 * 通用形状接口（兼容Konva和DOM）
 */
export interface BaseShape {
  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 BaseMarkingData {
  version: string
  shapes: BaseShape[]
  specialMarks: SpecialMark[]
  annotations: TextAnnotation[]
}

/**
 * 标记操作命令接口
 */
export interface MarkingCommand {
  id: string
  type: string
  timestamp: number
  execute: () => void
  undo: () => void
  description: string
}

/**
 * 添加形状命令
 */
export class AddShapeCommand implements MarkingCommand {
  id: string
  type = 'add_shape'
  timestamp: number
  description: string

  constructor(
    private data: BaseMarkingData,
    private shape: BaseShape,
    private layer: any,
  ) {
    this.id = `cmd_${Date.now()}_${Math.random()}`
    this.timestamp = Date.now()
    this.description = `添加${shape.type}`
  }

  execute() {
    this.data.shapes.push(this.shape)
  }

  undo() {
    const index = this.data.shapes.findIndex(s => s.id === this.shape.id)
    if (index > -1) {
      this.data.shapes.splice(index, 1)
    }
  }
}

/**
 * 添加特殊标记命令
 */
export class AddSpecialMarkCommand implements MarkingCommand {
  id: string
  type = 'add_special_mark'
  timestamp: number
  description: string

  constructor(
    private data: BaseMarkingData,
    private mark: SpecialMark,
    private layer: any,
  ) {
    this.id = `cmd_${Date.now()}_${Math.random()}`
    this.timestamp = Date.now()
    this.description = `添加${mark.type}标记`
  }

  execute() {
    this.data.specialMarks.push(this.mark)
  }

  undo() {
    const index = this.data.specialMarks.findIndex(m => m.id === this.mark.id)
    if (index > -1) {
      this.data.specialMarks.splice(index, 1)
    }
  }
}

/**
 * 添加文本注释命令
 */
export class AddTextCommand implements MarkingCommand {
  id: string
  type = 'add_text'
  timestamp: number
  description: string

  constructor(
    private data: BaseMarkingData,
    private annotation: TextAnnotation,
    private layer: any,
  ) {
    this.id = `cmd_${Date.now()}_${Math.random()}`
    this.timestamp = Date.now()
    this.description = `添加文本: ${annotation.text}`
  }

  execute() {
    console.log('[AddTextCommand] execute:', this.annotation)
    this.data.annotations.push(this.annotation)
  }

  undo() {
    console.log('[AddTextCommand] undo:', this.annotation.id)
    const index = this.data.annotations.findIndex(a => a.id === this.annotation.id)
    if (index > -1) {
      this.data.annotations.splice(index, 1)
    }
  }
}

/**
 * 擦除元素命令
 */
export class EraseCommand implements MarkingCommand {
  id: string
  type = 'erase'
  timestamp: number
  description: string

  private erasedShape?: BaseShape
  private erasedMark?: SpecialMark
  private erasedAnnotation?: TextAnnotation

  constructor(
    private data: BaseMarkingData,
    private targetId: string,
    private layer: any,
  ) {
    this.id = `cmd_${Date.now()}_${Math.random()}`
    this.timestamp = Date.now()
    this.description = `擦除元素: ${targetId}`

    // 备份要删除的元素
    this.erasedShape = this.data.shapes.find(s => s.id === targetId)
    this.erasedMark = this.data.specialMarks.find(m => m.id === targetId)
    this.erasedAnnotation = this.data.annotations.find(a => a.id === targetId)
  }

  execute() {
    console.log('[EraseCommand] execute:', this.targetId)
    this.data.shapes = this.data.shapes.filter(s => s.id !== this.targetId)
    this.data.specialMarks = this.data.specialMarks.filter(m => m.id !== this.targetId)
    this.data.annotations = this.data.annotations.filter(a => a.id !== this.targetId)
  }

  undo() {
    console.log('[EraseCommand] undo:', this.targetId)
    if (this.erasedShape) {
      this.data.shapes.push(this.erasedShape)
    }
    if (this.erasedMark) {
      this.data.specialMarks.push(this.erasedMark)
    }
    if (this.erasedAnnotation) {
      this.data.annotations.push(this.erasedAnnotation)
    }
  }
}

/**
 * 清空所有标记命令
 */
export class ClearAllCommand implements MarkingCommand {
  id: string
  type = 'clear_all'
  timestamp: number
  description = '清空所有标记'

  private backupShapes: BaseShape[] = []
  private backupMarks: SpecialMark[] = []
  private backupAnnotations: TextAnnotation[] = []

  constructor(
    private data: BaseMarkingData,
    private layer: any,
  ) {
    this.id = `cmd_${Date.now()}_${Math.random()}`
    this.timestamp = Date.now()

    // 备份当前数据
    this.backupShapes = [...this.data.shapes]
    this.backupMarks = [...this.data.specialMarks]
    this.backupAnnotations = [...this.data.annotations]

    console.log('[ClearAllCommand] constructor - backup:', {
      shapes: this.backupShapes.length,
      marks: this.backupMarks.length,
      annotations: this.backupAnnotations.length,
    })
  }

  execute() {
    console.log('[ClearAllCommand] execute - clearing all marks')
    this.data.shapes = []
    this.data.specialMarks = []
    this.data.annotations = []
  }

  undo() {
    console.log('[ClearAllCommand] undo - restoring:', {
      shapes: this.backupShapes.length,
      marks: this.backupMarks.length,
      annotations: this.backupAnnotations.length,
    })
    this.data.shapes = [...this.backupShapes]
    this.data.specialMarks = [...this.backupMarks]
    this.data.annotations = [...this.backupAnnotations]
  }
}

/**
 * 基于命令模式的历史记录管理
 */
export function useMarkingCommand() {
  const commandStack = ref<MarkingCommand[]>([])
  const currentIndex = ref(-1)
  const maxCommands = ref(50)

  const canUndo = computed(() => currentIndex.value >= 0)
  const canRedo = computed(() => currentIndex.value < commandStack.value.length - 1)

  /**
   * 执行命令并添加到历史记录
   */
  const executeCommand = (command: MarkingCommand) => {
    console.log('[CommandSystem] executeCommand:', {
      commandId: command.id,
      commandType: command.type,
      description: command.description,
      currentIndex: currentIndex.value,
      stackLength: commandStack.value.length,
    })

    // 截断后续命令（如果当前不在最新位置）
    if (currentIndex.value < commandStack.value.length - 1) {
      const removedCommands = commandStack.value.slice(currentIndex.value + 1)
      console.log('[CommandSystem] truncating future commands:', removedCommands.length)
      commandStack.value = commandStack.value.slice(0, currentIndex.value + 1)
    }

    // 执行命令
    command.execute()

    // 添加到历史记录
    commandStack.value.push(command)
    currentIndex.value = commandStack.value.length - 1

    console.log('[CommandSystem] command executed, new state:', {
      currentIndex: currentIndex.value,
      stackLength: commandStack.value.length,
      canUndo: canUndo.value,
      canRedo: canRedo.value,
    })

    // 限制历史记录数量
    if (commandStack.value.length > maxCommands.value) {
      commandStack.value.shift()
      currentIndex.value--
      console.log('[CommandSystem] history limit reached, removed oldest command')
    }
  }

  /**
   * 撤销操作
   */
  const undo = () => {
    console.log('[CommandSystem] undo attempt:', {
      canUndo: canUndo.value,
      currentIndex: currentIndex.value,
      stackLength: commandStack.value.length,
    })

    if (!canUndo.value) {
      console.log('[CommandSystem] cannot undo - no commands available')
      return false
    }

    const command = commandStack.value[currentIndex.value]
    console.log('[CommandSystem] undoing command:', {
      commandId: command.id,
      commandType: command.type,
      description: command.description,
    })

    command.undo()
    currentIndex.value--

    console.log('[CommandSystem] undo completed, new state:', {
      currentIndex: currentIndex.value,
      canUndo: canUndo.value,
      canRedo: canRedo.value,
    })

    return true
  }

  /**
   * 重做操作
   */
  const redo = () => {
    console.log('[CommandSystem] redo attempt:', {
      canRedo: canRedo.value,
      currentIndex: currentIndex.value,
      stackLength: commandStack.value.length,
    })

    if (!canRedo.value) {
      console.log('[CommandSystem] cannot redo - no future commands available')
      return false
    }

    currentIndex.value++
    const command = commandStack.value[currentIndex.value]

    console.log('[CommandSystem] redoing command:', {
      commandId: command.id,
      commandType: command.type,
      description: command.description,
    })

    command.execute()

    console.log('[CommandSystem] redo completed, new state:', {
      currentIndex: currentIndex.value,
      canUndo: canUndo.value,
      canRedo: canRedo.value,
    })

    return true
  }

  /**
   * 清空历史记录
   */
  const clearHistory = () => {
    commandStack.value = []
    currentIndex.value = -1
  }

  /**
   * 获取历史记录摘要
   */
  const getHistorySummary = () => {
    return commandStack.value.map((cmd, index) => ({
      id: cmd.id,
      type: cmd.type,
      description: cmd.description,
      timestamp: cmd.timestamp,
      isCurrent: index === currentIndex.value,
    }))
  }

  return {
    // 状态
    canUndo,
    canRedo,
    commandStack: computed(() => commandStack.value),
    currentIndex: computed(() => currentIndex.value),

    // 操作
    executeCommand,
    undo,
    redo,
    clearHistory,
    getHistorySummary,

    // 命令类
    AddShapeCommand,
    AddSpecialMarkCommand,
    AddTextCommand,
    EraseCommand,
    ClearAllCommand,
  }
}
