<script setup lang="ts">
import type { MarkingSubmitData } from '../../composables/useMarkingData'
import { useSessionStorage } from '@vueuse/core'
import { DictCode, useDict } from '@/composables/useDict'
import { MarkingTool } from '../../composables/renderer/useMarkingKonva'
import { markingSettings as settings } from '../../composables/useMarkingSettings'

interface Props {
  canUndo?: boolean
  canRedo?: boolean
  hasMarks?: boolean
  specialMarks?: {
    excellent: boolean
    typical: boolean
    problem: boolean
  }
  isLandscape?: boolean
  currentMarkingData?: MarkingSubmitData
}

const props = withDefaults(defineProps<Props>(), {
  canUndo: false,
  canRedo: false,
  hasMarks: false,
  specialMarks: () => ({
    excellent: false,
    typical: false,
    problem: false,
  }),
  isLandscape: false,
})

const emit = defineEmits<{
  'add-correct-mark': [position: { x: number, y: number }]
  'add-wrong-mark': [position: { x: number, y: number }]
  'add-half-mark': [position: { x: number, y: number }]
  'undo': []
  'redo': []
  'clear-all': []
  'toggle-special-mark': [type: 'excellent' | 'typical' | 'problem']
}>()
const currentTool = defineModel<MarkingTool>('currentTool', { required: true })
const showToolOptions = computed(() => {
  return [MarkingTool.PEN, MarkingTool.TEXT].includes(currentTool.value)
})

// 工具栏引用
const toolbarRef = ref<HTMLElement>()

// 工具栏位置状态，使用 SessionStorage 持久化，默认位于左下角
const position = useSessionStorage('marking-toolbar-position', { x: 16, y: 16 })

// 收起状态
const isCollapsed = useSessionStorage('marking-toolbar-collapsed', false)

// 拖动状态
const isDragging = ref(false)
const dragState = ref({
  startX: 0,
  startY: 0,
  startPositionX: 0,
  startPositionY: 0,
})

const { getDictOptionsComputed } = useDict()
const { options: problemTypeOptions } = getDictOptionsComputed(DictCode.SCAN_ANOMALY_STATUS)
const problemTooltipContent = computed(() => {
  if (props.currentMarkingData?.isProblem) {
    return `当前问题类型：${problemTypeOptions.value.find(item => item.value === props.currentMarkingData?.problemType)?.label}`
  }
  return '标记为问题卷'
})

// 待放置标记的状态
const pendingMarkType = ref<'correct' | 'wrong' | 'half' | null>(null)

// 统一的按钮基础样式
const baseButtonClass = computed(() => {
  return props.isLandscape
    ? 'size-32rpx lg:size-8 !p-0 rounded-lg flex items-center justify-center transition-all duration-200 ease-in-out shadow-sm hover:shadow-md active:scale-95 after:border-none'
    : 'size-8 lg:size-10 !p-0 rounded-lg flex items-center justify-center transition-all duration-200 ease-in-out shadow-sm hover:shadow-md active:scale-95 after:border-none'
})

const separatorClass = computed(() => {
  return props.isLandscape
    ? 'mx-4rpx lg:mx-1 h-4 lg:h-6 w-px flex-shrink-0 bg-gradient-to-b from-transparent via-gray-300 to-transparent'
    : 'h-5 lg:h-6 w-px bg-gradient-to-b from-transparent via-gray-300 to-transparent'
})
const iconClass = computed(() => {
  return props.isLandscape
    ? 'size-20rpx lg:size-4'
    : 'size-5 lg:size-5 w-4 lg:w-5'
})

/**
 * 获取工具按钮样式类
 */
function getToolButtonClass(tool: MarkingTool) {
  const isActive = currentTool.value === tool
  return [
    baseButtonClass.value,
    isActive
      ? 'bg-gradient-to-r from-blue-600 to-blue-700 text-white border border-blue-500'
      : 'bg-white text-blue-600 border border-blue-200 hover:bg-gradient-to-r hover:from-blue-50 hover:to-blue-100 hover:border-blue-300 hover:text-blue-700',
  ]
}

/**
 * 获取标记按钮样式类（对错半对）
 */
function getMarkButtonClass(type: 'correct' | 'wrong' | 'half') {
  const toolMap = {
    correct: MarkingTool.CORRECT,
    wrong: MarkingTool.WRONG,
    half: MarkingTool.HALF,
  }
  const colorMap = {
    correct: {
      active: 'bg-gradient-to-r from-green-500 to-green-600 text-white border border-green-400',
      inactive: 'bg-white text-green-600 border border-green-200 hover:bg-gradient-to-r hover:from-green-50 hover:to-green-100 hover:border-green-300 hover:text-green-700',
    },
    wrong: {
      active: 'bg-gradient-to-r from-red-500 to-red-600 text-white border border-red-400',
      inactive: 'bg-white text-red-600 border border-red-200 hover:bg-gradient-to-r hover:from-red-50 hover:to-red-100 hover:border-red-300 hover:text-red-700',
    },
    half: {
      active: 'bg-gradient-to-r from-yellow-500 to-yellow-600 text-white border border-yellow-400',
      inactive: 'bg-white text-yellow-600 border border-yellow-200 hover:bg-gradient-to-r hover:from-yellow-50 hover:to-yellow-100 hover:border-yellow-300 hover:text-yellow-700',
    },
  }

  const isActive = currentTool.value === toolMap[type]
  const colors = colorMap[type]

  return [baseButtonClass.value, isActive ? colors.active : colors.inactive]
}

/**
 * 获取特殊标记按钮样式类
 */
function getSpecialButtonClass(type: 'excellent' | 'typical' | 'problem') {
  const isActive = props.specialMarks[type]
  const colorMap = {
    excellent: {
      active: 'bg-gradient-to-r from-yellow-500 to-yellow-600 text-white border border-yellow-400',
      inactive: 'bg-white text-yellow-600 border border-yellow-200 hover:bg-gradient-to-r hover:from-yellow-50 hover:to-yellow-100 hover:border-yellow-300 hover:text-yellow-700',
    },
    typical: {
      active: 'bg-gradient-to-r from-blue-600 to-blue-700 text-white border border-blue-500',
      inactive: 'bg-white text-blue-600 border border-blue-200 hover:bg-gradient-to-r hover:from-blue-50 hover:to-blue-100 hover:border-blue-300 hover:text-blue-700',
    },
    problem: {
      active: 'bg-gradient-to-r from-red-500 to-red-600 text-white border border-red-400',
      inactive: 'bg-white text-red-600 border border-red-200 hover:bg-gradient-to-r hover:from-red-50 hover:to-red-100 hover:border-red-300 hover:text-red-700',
    },
  }

  const colors = colorMap[type]
  return [baseButtonClass.value, props.isLandscape ? 'text-12rpx lg:text-sm' : 'text-sm lg:text-base', 'font-medium', isActive ? colors.active : colors.inactive]
}

/**
 * 切换工具
 */
function switchTool(tool: MarkingTool) {
  currentTool.value = tool
  pendingMarkType.value = null

  // 显示/隐藏工具选项
  settings.value.showToolOptions = tool === 'pen' || tool === 'text'
}

/**
 * 处理正确标记
 */
function handleCorrectMark() {
  currentTool.value = MarkingTool.CORRECT
}

/**
 * 处理错误标记
 */
function handleWrongMark() {
  currentTool.value = MarkingTool.WRONG
}

/**
 * 处理半对标记
 */
function handleHalfMark() {
  currentTool.value = MarkingTool.HALF
}

/**
 * 处理图片点击（用于放置标记）
 */
function handleImageClick(position: { x: number, y: number }) {
  if (pendingMarkType.value) {
    switch (pendingMarkType.value) {
      case 'correct':
        emit('add-correct-mark', position)
        break
      case 'wrong':
        emit('add-wrong-mark', position)
        break
      case 'half':
        emit('add-half-mark', position)
        break
    }

    pendingMarkType.value = null
  }
}

/**
 * 处理撤销
 */
function handleUndo() {
  if (props.canUndo) {
    emit('undo')
  }
}

/**
 * 处理重做
 */
function handleRedo() {
  if (props.canRedo) {
    emit('redo')
  }
}

/**
 * 处理清除所有
 */
function handleClearAll() {
  if (props.hasMarks) {
    uni.showModal({
      confirmButtonText: '确认清除',
      cancelButtonText: '取消',
      success: (result) => {
        if (result.confirm) {
          emit('clear-all')
        }
      },
    })
  }
}

/**
 * 切换特殊标记
 */
function toggleSpecialMark(type: 'excellent' | 'typical' | 'problem') {
  emit('toggle-special-mark', type)
}

/**
 * 更新画笔颜色
 */
function updatePenColor(color: string | null) {
  settings.value.penColor = color || '#ff0000'
}

/**
 * 更新画笔粗细
 */
function updatePenWidth(width: number | number[]) {
  settings.value.penWidth = Array.isArray(width) ? width[0] : width
}

/**
 * 更新文字大小
 */
function updateTextSize(size: number | undefined) {
  if (size !== undefined) {
    settings.value.textSize = size
  }
}

/**
 * 更新文字颜色
 */
function updateTextColor(color: string | null) {
  settings.value.textColor = color || '#000000'
}

/**
 * 处理鼠标按下开始拖动
 */
function handleMouseDown(event: MouseEvent) {
  // 如果已收起，不允许拖动
  if (isCollapsed.value) {
    return
  }

  // 如果点击的是按钮或其他交互元素，不触发拖动
  const target = event.target as HTMLElement
  if (
    target.tagName === 'BUTTON'
    || target.closest('button')
    || target.tagName === 'INPUT'
    || target.closest('input')
  ) {
    return
  }

  isDragging.value = true
  dragState.value = {
    startX: event.clientX,
    startY: event.clientY,
    startPositionX: position.value.x,
    startPositionY: position.value.y,
  }

  // 添加全局鼠标事件监听
  document.addEventListener('mousemove', handleMouseMove)
  document.addEventListener('mouseup', handleMouseUp)

  // 防止选中文本
  event.preventDefault()
}

/**
 * 处理鼠标移动进行拖动
 */
function handleMouseMove(event: MouseEvent) {
  if (!isDragging.value)
    return

  const deltaX = event.clientX - dragState.value.startX
  const deltaY = event.clientY - dragState.value.startY

  // 计算新位置
  let newX = dragState.value.startPositionX + deltaX
  let newY = dragState.value.startPositionY - deltaY // bottom 坐标系是相反的

  // 获取工具栏尺寸和窗口尺寸，确保工具栏不会超出屏幕边界
  if (toolbarRef.value) {
    const rect = toolbarRef.value.getBoundingClientRect()
    const windowWidth = window.innerWidth
    const windowHeight = window.innerHeight

    // 限制左右边界
    newX = Math.max(0, Math.min(newX, windowWidth - rect.width))
    // 限制上下边界 (注意 bottom 坐标系)
    newY = Math.max(0, Math.min(newY, windowHeight - rect.height))
  }

  // 更新位置
  position.value = { x: newX, y: newY }
}

/**
 * 处理鼠标松开结束拖动
 */
function handleMouseUp() {
  isDragging.value = false

  // 移除全局鼠标事件监听
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
}

/**
 * 切换收起/展开状态
 */
function toggleCollapse() {
  isCollapsed.value = !isCollapsed.value
}

/**
 * 键盘快捷键处理
 */
function handleKeydown(event: KeyboardEvent) {
  // 防止在输入框中触发
  const target = event.target as HTMLElement
  if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
    return
  }

  switch (event.code) {
    case 'KeyV':
      event.preventDefault()
      switchTool(MarkingTool.SELECT)
      break

    case 'KeyT':
      event.preventDefault()
      switchTool(MarkingTool.TEXT)
      break

    case 'KeyP':
      event.preventDefault()
      switchTool(MarkingTool.PEN)
      break

    case 'KeyR':
      event.preventDefault()
      switchTool(MarkingTool.RECT)
      break

    case 'KeyE':
      event.preventDefault()
      switchTool(MarkingTool.ERASER)
      break

    case 'KeyZ':
      if (event.ctrlKey || event.metaKey) {
        event.preventDefault()
        if (event.shiftKey) {
          handleRedo()
        }
        else {
          handleUndo()
        }
      }
      break

    case 'Delete':
    case 'Backspace':
      event.preventDefault()
      handleClearAll()
      break
  }
}

// 挂载时绑定键盘事件
onMounted(() => {
  document.addEventListener('keydown', handleKeydown)
})

// 卸载时移除事件监听
onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
  document.removeEventListener('mousemove', handleMouseMove)
  document.removeEventListener('mouseup', handleMouseUp)
})

// 暴露点击处理方法给父组件
defineExpose({
  handleImageClick,
})
</script>

<template>
  <div
    ref="toolbarRef"
    class="rounded-tr-base fixed bottom-0 left-0 z-10 select-none border border-white/20 shadow-xl backdrop-blur-sm transition-all duration-300"
    :class="[
      {
        'px-2 py-1 w-fit cursor-move lg:px-3 lg:py-2': !isLandscape && !isCollapsed,
        'px-4rpx py-2rpx': isLandscape && !isCollapsed,
        'bg-gradient-to-r from-slate-800/95 to-slate-900/95': !isCollapsed,
        'backdrop-saturate-150': !isCollapsed,
      },
    ]"
    @mousedown="handleMouseDown"
  >
    <!-- 收起按钮 -->
    <div
      v-if="isCollapsed"
      class="h-full w-8 flex transform cursor-pointer items-center justify-center border border-gray-200 rounded-tr-2xl from-white to-gray-50 bg-gradient-to-r shadow-inner"
      :class="{
        'w-64px': isLandscape,
      }"
      @click="toggleCollapse"
      @mousedown.stop
    >
      <div class="i-carbon:chevron-right text-base text-blue-600 transition-colors lg:text-lg hover:text-blue-700" />
    </div>

    <!-- 工具栏内容 -->
    <div
      v-show="!isCollapsed"
      class="flex items-center" :class="{
        'gap-4rpx lg:gap-2': !isLandscape,
        'gap-4rpx lg:gap-1': isLandscape,
      }"
    >
      <!-- 收起按钮（展开状态时显示） -->
      <button
        class="border border-gray-200 from-white to-gray-50 bg-gradient-to-r text-slate-600 transition-all hover:border-gray-300 hover:from-gray-50 hover:to-gray-100 hover:text-slate-700"
        :class="baseButtonClass"
        @click="toggleCollapse"
      >
        <div :class="iconClass" class="i-carbon:chevron-left" />
      </button>

      <div :class="separatorClass" />
      <!-- 对错半对标记 -->
      <wd-tooltip content="正确标记" placement="top">
        <button :class="getMarkButtonClass('correct')" @click="handleCorrectMark">
          <div :class="iconClass" class="i-fluent:checkmark-24-regular" />
        </button>
      </wd-tooltip>

      <wd-tooltip content="错误标记" placement="top">
        <button :class="getMarkButtonClass('wrong')" @click="handleWrongMark">
          <div :class="iconClass" class="i-fluent:dismiss-24-regular" />
        </button>
      </wd-tooltip>

      <wd-tooltip content="半对标记" placement="top">
        <button :class="getMarkButtonClass('half')" @click="handleHalfMark">
          <svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
            <!-- 对勾的第一段：短的向下斜线 -->
            <line
              x1="16"
              y1="32"
              x2="28"
              y2="44"
              stroke="currentColor"
              stroke-width="3"
              stroke-linecap="round"
              fill="none"
            />
            <!-- 对勾的第二段：长的向上斜线 -->
            <line
              x1="28"
              y1="44"
              x2="48"
              y2="20"
              stroke="currentColor"
              stroke-width="3"
              stroke-linecap="round"
              fill="none"
            />
            <!-- 右侧的斜线（向下倾斜） -->
            <line
              x1="30"
              y1="25"
              x2="46"
              y2="40"
              stroke="currentColor"
              stroke-width="3"
              stroke-linecap="round"
              fill="none"
            />
          </svg>
        </button>
      </wd-tooltip>

      <div :class="separatorClass" />
      <!-- 橡皮擦 -->
      <wd-tooltip content="擦除" placement="top">
        <button
          :class="getToolButtonClass(MarkingTool.ERASER)"
          @click="switchTool(MarkingTool.ERASER)"
        >
          <div :class="iconClass" class="i-fluent:eraser-24-regular" />
        </button>
      </wd-tooltip>

      <!-- 文字工具 -->
      <wd-tooltip content="添加文字" placement="top">
        <button :class="getToolButtonClass(MarkingTool.TEXT)" @click="switchTool(MarkingTool.TEXT)">
          <div :class="iconClass" class="i-fluent:text-24-regular" />
        </button>
      </wd-tooltip>

      <!-- 任意笔画 -->
      <wd-tooltip content="自由绘制" placement="top">
        <button :class="getToolButtonClass(MarkingTool.PEN)" @click="switchTool(MarkingTool.PEN)">
          <div :class="iconClass" class="i-fluent:pen-24-regular" />
        </button>
      </wd-tooltip>

      <div :class="separatorClass" />

      <!-- 撤回 -->
      <!-- <wd-tooltip content="撤回一步" placement="top">
        <button :class="getActionButtonClass('undo')" :disabled="!canUndo" @click="handleUndo">
          <div class="i-fluent:arrow-undo-24-regular h-4 w-4" />
        </button>
      </wd-tooltip> -->

      <!-- 特殊标记 -->
      <wd-tooltip content="标记为优秀卷" placement="top">
        <button
          :class="getSpecialButtonClass('excellent')"
          @click="toggleSpecialMark('excellent')"
        >
          优秀
        </button>
      </wd-tooltip>

      <wd-tooltip content="标记为典例卷" placement="top">
        <button
          :class="getSpecialButtonClass('typical')"
          @click="toggleSpecialMark('typical')"
        >
          典例
        </button>
      </wd-tooltip>

      <wd-tooltip :content="problemTooltipContent" placement="top">
        <button
          :class="getSpecialButtonClass('problem')"
          @click="toggleSpecialMark('problem')"
        >
          问题
        </button>
      </wd-tooltip>
    </div>
  </div>
</template>
