<script setup lang="ts">
import type { KonvaMarkingData, useSimpleKonvaLayer } from '../../composables/renderer/useMarkingKonva'
import { DictCode, useDict } from '@/composables/useDict'

import { useMarkingData } from '../../composables/useMarkingData'
import { markingSettings } from '../../composables/useMarkingSettings'
import { useSimpleMarkingTool } from '../../composables/useSimpleMarkingTool'
import ProblemSheetDialog from '../dialog/ProblemSheetDialog.vue'
import KonvaImageRenderer from './KonvaImageRenderer.vue'
import TraceToolbar from './TraceToolbar.vue'

interface Question {
  id: string
  title: string
  fullScore: number
  imageUrls: string[]
}

interface Props {
  question: Question
  questionIndex: number
  scale?: number
  imageLayout?: 'horizontal' | 'vertical'
  showToolbar?: boolean
  initialMarkingData?: KonvaMarkingData[]
}

const props = withDefaults(defineProps<Props>(), {
  questionIndex: 0,
  scale: 1,
  imageLayout: 'horizontal',
  showToolbar: true,
})

const emit = defineEmits<{
  'marking-change': [imageIndex: number, data: KonvaMarkingData]
}>()

const { currentTool } = useSimpleMarkingTool()
const markingData = useMarkingData()

// 图片渲染器引用和layer管理器
const imageRendererRefs = ref<Map<number, InstanceType<typeof KonvaImageRenderer>>>(new Map())
const layerManagers = ref<Map<number, ReturnType<typeof useSimpleKonvaLayer>>>(new Map())

// 每个图片的标记数据
const markingDataList = ref<KonvaMarkingData[]>(
  props.question.imageUrls.map(
    (_, index) =>
      props.initialMarkingData?.[index] || {
        version: '1.0',
        shapes: [],
        specialMarks: [],
        annotations: [],
      },
  ),
)

// 计算属性
const imagesLayoutClass = computed(() => ({
  'images-horizontal': props.imageLayout === 'horizontal',
  'images-vertical': props.imageLayout === 'vertical',
}))

const currentMarkingData = computed({
  get: () => {
    return markingData.currentMarkingSubmitData.value[props.questionIndex]
  },
  set: (value) => {
    markingData.currentMarkingSubmitData.value[props.questionIndex] = value
  },
})

const specialMarks = computed(() => {
  const data = currentMarkingData.value
  return {
    excellent: data?.isExcellent ?? false,
    typical: data?.isTypical ?? false,
    problem: data?.isProblem ?? false,
  }
})

const operateLayerStack = ref<number[]>([])

const canUndo = computed(() => {
  return Array.from(layerManagers.value.values()).some(manager => manager.canUndo)
})

const hasMarks = computed(() => {
  return Array.from(layerManagers.value.values()).some(manager => manager.hasMarks)
})

/**
 * 设置图片渲染器引用
 */
function setImageRendererRef(el: any, index: number) {
  if (el) {
    imageRendererRefs.value.set(index, el)
  }
  else {
    imageRendererRefs.value.delete(index)
  }
}

/**
 * 处理layer准备就绪
 */
function handleLayerReady(imageIndex: number, manager: ReturnType<typeof useSimpleKonvaLayer>) {
  layerManagers.value.set(imageIndex, manager as any)

  // 监听标记数据变化
  watch(
    manager.markingData,
    (newData) => {
      markingDataList.value[imageIndex] = { ...newData }
      currentMarkingData.value.remark = markingDataList.value
      operateLayerStack.value.push(imageIndex)
      emit('marking-change', imageIndex, newData)
    },
    { deep: true },
  )
}

/**
 * 添加正确标记 - 只切换工具，实际添加在点击时处理
 */
function addCorrectMark() {
  // 工具已经在TraceToolbar中切换，这里不需要额外操作
}

/**
 * 添加错误标记 - 只切换工具，实际添加在点击时处理
 */
function addWrongMark() {
  // 工具已经在TraceToolbar中切换，这里不需要额外操作
}

/**
 * 添加半对标记 - 只切换工具，实际添加在点击时处理
 */
function addHalfMark() {
  // 工具已经在TraceToolbar中切换，这里不需要额外操作
}

/**
 * 清空所有标记
 */
function clearAllMarks() {
  layerManagers.value.forEach((manager) => {
    manager.clearAllMarks()
  })
}

/**
 * 撤销操作
 */
function undo() {
  const imageIndex = operateLayerStack.value.pop()
  if (imageIndex !== undefined) {
    layerManagers.value.get(imageIndex)?.undo()
  }
}

// 问题卷对话框引用
const problemSheetDialogRef = ref<InstanceType<typeof ProblemSheetDialog>>()

const { getDictOptionsComputed } = useDict()
const { options: problemTypeOptions } = getDictOptionsComputed(DictCode.SCAN_ANOMALY_STATUS)

const problemTypeText = computed(() => {
  return (
    problemTypeOptions.value.find(item => item.value === currentMarkingData.value.problemType)
      ?.label ?? ''
  )
})

const currentSpecialMarkText = computed(() => {
  if (currentMarkingData.value.isExcellent) {
    return '优秀试卷'
  }
  if (currentMarkingData.value.isTypical) {
    return '典型试卷'
  }
  if (currentMarkingData.value.isProblem) {
    return `问题试卷 - ${problemTypeText.value}`
  }
  return ''
})

const specialMarkTypeMap = {
  excellent: '优秀试卷',
  typical: '典型试卷',
  problem: '问题试卷',
} as const

async function toggleSpecialMark(type: 'excellent' | 'typical' | 'problem') {
  if (currentSpecialMarkText.value) {
    await uni.showModal({
      title: '提示',
      content: `当前已经被标记为 ${currentSpecialMarkText.value}，是否改为${specialMarkTypeMap[type]}？`,
    })
  }

  if (type === 'problem') {
    // 弹出问题卷对话框
    try {
      problemSheetDialogRef.value?.syncFormData({
        problemType: currentMarkingData.value.problemType ?? '',
        problemRemark: currentMarkingData.value.problemRemark ?? '',
      })
      const result = await problemSheetDialogRef.value?.start()
      if (result) {
        // 将问题卷信息保存到当前阅卷数据中
        Object.assign(markingData.currentMarkingSubmitData.value[props.questionIndex]!, {
          isExcellent: false,
          isTypical: false,
          isProblem: true,
          problemType: result.problemType,
          problemRemark: result.problemRemark,
        })
      }
    }
    catch (error) {
      if (error !== 'cancel') {
        console.error('标记问题卷失败:', error)
        uni.showToast({
          title: '标记问题卷失败',
          icon: 'none',
        })
      }
    }
    return
  }

  Object.assign(markingData.currentMarkingSubmitData.value[props.questionIndex]!, {
    isExcellent: type === 'excellent',
    isTypical: type === 'typical',
    isProblem: false,
    problemType: undefined,
    problemRemark: undefined,
  })
}

// 工具变化时，新的简化系统不需要额外同步
// currentTool 已经是响应式的，各layer会自动响应

onMounted(() => {
  markingData.currentMarkingSubmitData.value[props.questionIndex] = {
    score: -1,
    remark: props.question.imageUrls.map(() => ({})),
    status: 'draft',
    isExcellent: false,
    isTypical: false,
    isProblem: false,
    problemType: '',
    problemRemark: '',
  }
})

// 暴露方法给父组件
defineExpose({
  clearAllMarks,
  undo,
})
</script>

<template>
  <div
    v-if="
      markingData.mode.value !== 'multi'
        || !markingSettings.hideMarked
        || currentMarkingData?.score === -1
    "
    class="question-renderer"
    :class="{
      'ring-2 ring-red-500':
        markingData.mode.value === 'multi'
        && markingData.firstNotScoredIndex.value === questionIndex,
    }"
  >
    <div v-if="question.title" class="question-header">
      <div class="question-title">
        <span class="question-title-text">{{ question.title }}</span>
      </div>
    </div>
    <div class="images-container" :class="imagesLayoutClass">
      <div
        v-for="(imageUrl, imageIndex) in question.imageUrls"
        :key="`${question.id}_${imageIndex}`"
        class="image-wrapper relative"
      >
        <KonvaImageRenderer
          :ref="(el) => setImageRendererRef(el, imageIndex)"
          :image-url="imageUrl"
          :scale="scale"
          :marking-data="markingDataList[imageIndex]"
          :current-tool="currentTool"
          class="image-item"
          @layer-ready="(manager) => handleLayerReady(imageIndex, manager)"
        />

        <!-- 第一个图片显示分数 -->
        <div
          v-if="
            imageIndex === 0
              && currentMarkingData?.score !== undefined
              && currentMarkingData?.score !== -1
          "
          class="score-badge absolute right-2 top-2 z-10"
        >
          <span class="current-score text-3xl text-red-600 font-bold">{{
            currentMarkingData.score
          }}</span>
          <span class="total-score text-lg text-red-500 font-semibold">/{{ question.fullScore }}</span>
        </div>
      </div>
    </div>
    <TraceToolbar
      v-if="showToolbar && markingData.firstNotScoredIndex.value === questionIndex"
      v-model:current-tool="currentTool"
      :can-undo="canUndo"
      :has-marks="hasMarks"
      :special-marks="specialMarks"
      :current-marking-data="currentMarkingData"
      :is-landscape="markingData.isLandscape.value"
      @add-correct-mark="addCorrectMark"
      @add-wrong-mark="addWrongMark"
      @add-half-mark="addHalfMark"
      @undo="undo"
      @clear-all="clearAllMarks"
      @toggle-special-mark="toggleSpecialMark"
    />

    <!-- 问题卷对话框 -->
    <ProblemSheetDialog ref="problemSheetDialogRef" />
  </div>
</template>

<style scoped>
.images-container {
  display: flex;
  align-items: flex-start;
}

.images-horizontal {
  flex-direction: row;
  gap: 16px;
  flex-wrap: nowrap;
}

.images-vertical {
  flex-direction: column;
  gap: 16px;
}

.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

.image-item {
  flex-shrink: 0;
}

.image-wrapper {
  flex-shrink: 0;
}

.score-badge {
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
  display: flex;
  align-items: baseline;
  gap: 2px;
}

.current-score {
  line-height: 1;
}

.total-score {
  line-height: 1;
}
</style>
