<script setup lang="ts">
import type { DomMarkingData } from '../../composables/renderer/useMarkingDom'
import type { ExamStudentMarkingQuestionResponse } from '@/api'
import { markingSettings } from '../../composables/useMarkingSettings'
import QuestionRenderer from './QuestionRenderer.vue'

interface Props {
  imageSize: number
  questionData: ExamStudentMarkingQuestionResponse[]
}

const props = defineProps<Props>()

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

const scale = defineModel<number>('scale', { default: 1.0 })

// 智能缩放控制 - 内联实现
// 用户手动调节的缩放因子（1.0 = 默认100%，0.5 = 缩小50%，2.0 = 放大200%）
const userScaleFactor = ref(scale.value || 1.0)

// 最终的缩放比例 - 默认100%
const finalScale = computed(() => {
  return userScaleFactor.value
})

// 设置缩放比例（用于手势缩放）
function setScale(newScale: number) {
  // 限制缩放范围：0.1倍到5倍
  const clampedScale = Math.max(0.1, Math.min(5.0, newScale))
  userScaleFactor.value = clampedScale
  scale.value = clampedScale
}

// 缩放级别文本
const scaleText = computed(() => {
  const percentage = Math.round(userScaleFactor.value * 100)
  return `${percentage}%`
})

// 同步外部 scale 变化到内部状态
watch(scale, (newScale) => {
  if (newScale !== undefined && newScale !== userScaleFactor.value) {
    userScaleFactor.value = newScale
  }
})

// 手势缩放相关
const containerRef = ref<HTMLElement>()
const initialDistance = ref(0)
const isGesturing = ref(false)
const initialScale = ref(1.0)

/**
 * 计算两点之间的距离
 */
function getDistance(touch1: Touch, touch2: Touch): number {
  const dx = touch2.clientX - touch1.clientX
  const dy = touch2.clientY - touch1.clientY
  return Math.sqrt(dx * dx + dy * dy)
}

/**
 * 处理触摸开始
 */
function handleTouchStart(e: TouchEvent) {
  if (e.touches.length === 2) {
    // 双指触摸，开始缩放手势
    isGesturing.value = true
    initialDistance.value = getDistance(e.touches[0], e.touches[1])
    initialScale.value = userScaleFactor.value
    e.preventDefault()
  }
}

/**
 * 处理触摸移动
 */
function handleTouchMove(e: TouchEvent) {
  if (e.touches.length === 2 && isGesturing.value) {
    // 计算新的距离
    const currentDistance = getDistance(e.touches[0], e.touches[1])

    // 计算缩放比例变化
    const scaleChange = currentDistance / initialDistance.value

    // 应用新的缩放比例
    const newScale = initialScale.value * scaleChange
    setScale(newScale)

    e.preventDefault()
  }
}

/**
 * 处理触摸结束
 */
function handleTouchEnd(e: TouchEvent) {
  if (e.touches.length < 2) {
    isGesturing.value = false
  }
}

// 计算题目布局类
const questionsLayoutClass = computed(() => ({
  'questions-vertical': true, // 多题总是竖排
  'items-start': markingSettings.value.imagePosition === 'left',
  'items-center': markingSettings.value.imagePosition === 'center',
  'items-end': markingSettings.value.imagePosition === 'right',
}))

// 转换为渲染数据
const questionDataList = computed(() => {
  if (!props.questionData?.length)
    return []

  return props.questionData.map((item, index) => ({
    id: `question_${item.tpl_question_id || index}_${item.scan_info_id}_${index}`,
    title: `${item.question_major || ''}${item.question_minor || ''}`,
    fullScore: item.full_score || 0,
    imageUrls: item.image_urls || [],
  }))
})

/**
 * 处理标记变化
 */
function handleMarkingChange(questionIndex: number, imageIndex: number, data: DomMarkingData) {
  emit('marking-change', questionIndex, imageIndex, data)
}
</script>

<template>
  <div
    ref="containerRef"
    class="multi-question-renderer"
    @touchmove="handleTouchMove"
    @touchstart="handleTouchStart"
    @touchend="handleTouchEnd"
  >
    <!-- 缩放提示 -->
    <div
      v-if="isGesturing"
      class="fixed left-1/2 top-1/2 z-50 rounded-lg bg-black/70 px-4 py-2 text-white -translate-x-1/2 -translate-y-1/2"
    >
      {{ scaleText }}
    </div>

    <div class="flex flex-col flex-nowrap" :class="questionsLayoutClass">
      <QuestionRenderer
        v-for="(question, questionIndex) in questionDataList"
        :key="question.id"
        :question="question"
        :question-index="questionIndex"
        :scale="finalScale"
        :image-layout="markingSettings.imageLayout"
        :show-toolbar="markingSettings.showTraceToolbar"
        :initial-marking-data="
          questionData[questionIndex].remark
            ? JSON.parse(questionData[questionIndex].remark)
            : undefined
        "
        class="question-item w-fit"
        @marking-change="(imageIndex, data) => handleMarkingChange(questionIndex, imageIndex, data)"
      />
    </div>
  </div>
</template>

<style scoped>
.multi-question-renderer {
  width: 100%;
  height: 100%;
  overflow: auto;
  padding: 8rpx 16rpx;
  padding-bottom: 96rpx;
  touch-action: pan-x pan-y;
}

.questions-container {
  display: flex;
  align-items: flex-start;
}

.questions-vertical {
  flex-direction: column;
  gap: 24px;
  padding-left: 12px;
}

.questions-single {
  justify-content: center;
  align-items: center;
  min-height: 100%;
}

.question-item {
  flex-shrink: 0;
}
</style>
