<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import SpellCard from '../components/SpellCard.vue'
import { api, type QuizQuestion, type QuizTrack } from '../api/request'
import {
  clearQuizSession,
  loadQuizSession,
  submitQuizAnswer,
  useQuizAutoSave,
  type QuizSessionSnapshot,
} from '../composables/useQuizSession'
import { useQuizTimer } from '../composables/useQuizTimer'
import { consumePracticeFocusWordId } from '../utils/practiceFocus'
import { spellQuestionFromWord } from '../utils/spellQuestion'

const route = useRoute()
const track = computed<QuizTrack>(() =>
  route.query.track === 'book' ? 'book' : 'accumulation'
)
const pageTitle = computed(() =>
  track.value === 'book' ? '词书拼写练习' : '积累拼写练习'
)

const { startQuestionTimer, consumeDurationSeconds } = useQuizTimer()

const questions = ref<QuizQuestion[]>([])
const currentIndex = ref(0)
const submittedAnswer = ref('')
const showResult = ref(false)
const isCorrect = ref(false)
const loading = ref(true)
const finished = ref(false)
const sessionCorrect = ref(0)
const sessionWrong = ref(0)
const empty = ref(false)
const restored = ref(false)
const spellCardRef = ref<InstanceType<typeof SpellCard> | null>(null)

const current = () => questions.value[currentIndex.value]

function buildSnapshot(): QuizSessionSnapshot | null {
  if (!questions.value.length) return null
  return {
    questions: questions.value,
    currentIndex: currentIndex.value,
    sessionCorrect: sessionCorrect.value,
    sessionWrong: sessionWrong.value,
    finished: finished.value,
    submittedAnswer: submittedAnswer.value,
    showResult: showResult.value,
    isCorrect: isCorrect.value,
  }
}

const { persist, flushPending } = useQuizAutoSave(
  'spell',
  buildSnapshot,
  {
    getDraftAnswer: () => spellCardRef.value?.getDraft() ?? '',
    onDraftSubmit: (answer) => submitAnswer(answer),
  },
  track.value
)

function applySnapshot(snap: QuizSessionSnapshot) {
  questions.value = snap.questions
  currentIndex.value = snap.currentIndex
  sessionCorrect.value = snap.sessionCorrect
  sessionWrong.value = snap.sessionWrong
  finished.value = snap.finished
  submittedAnswer.value = snap.submittedAnswer ?? ''
  showResult.value = snap.showResult ?? false
  isCorrect.value = snap.isCorrect ?? false
}

onMounted(async () => {
  try {
    const saved = loadQuizSession('spell', track.value)
    if (saved && !saved.finished) {
      applySnapshot(saved)
      restored.value = true
      await flushPending()
    } else {
      clearQuizSession('spell', track.value)
      const { data } = await api.spellQuiz(track.value)
      questions.value = data.questions
      const focusId = consumePracticeFocusWordId()
      if (focusId) {
        try {
          const { data: word } = await api.getWord(focusId)
          const focusQ = spellQuestionFromWord(word)
          if (!questions.value.some((q) => q.word_id === focusId)) {
            questions.value = [focusQ, ...questions.value]
          }
          currentIndex.value = 0
        } catch {
          /* 单词不存在则忽略 */
        }
      }
      if (questions.value.length === 0) {
        empty.value = true
      } else {
        persist()
      }
    }
  } finally {
    loading.value = false
    if (current() && !showResult.value) startQuestionTimer()
  }
})

watch(currentIndex, () => {
  if (!loading.value && !finished.value && current() && !showResult.value) {
    startQuestionTimer()
  }
})

async function submitAnswer(answer: string) {
  if (showResult.value) return
  submittedAnswer.value = answer
  const q = current()
  if (!q) return

  const payload = {
    word_id: q.word_id,
    question_type: q.question_type,
    user_answer: answer,
    correct_answer: q.correct_answer,
    duration_seconds: consumeDurationSeconds(),
  }

  const result = await submitQuizAnswer('spell', payload, track.value)
  if (result.ok && result.is_correct !== undefined) {
    isCorrect.value = result.is_correct
  } else {
    isCorrect.value = answer.toLowerCase() === q.correct_answer.toLowerCase()
  }
  if (isCorrect.value) sessionCorrect.value++
  else sessionWrong.value++

  showResult.value = true
  persist()
}

function onSubmit(answer: string) {
  return submitAnswer(answer)
}

function nextQuestion() {
  if (currentIndex.value >= questions.value.length - 1) {
    finished.value = true
    clearQuizSession('spell', track.value)
    return
  }
  currentIndex.value++
  submittedAnswer.value = ''
  showResult.value = false
  isCorrect.value = false
  startQuestionTimer()
  persist()
}

const accuracy = () => {
  const total = sessionCorrect.value + sessionWrong.value
  return total ? Math.round((sessionCorrect.value / total) * 100) : 0
}
</script>

<template>
  <div class="page">
    <h1 class="page-title">{{ pageTitle }}</h1>

    <p v-if="restored && !loading && !finished && !empty" class="restore-hint">
      已恢复上次未完成的训练进度
    </p>

    <p v-if="loading" style="color: var(--muted)">加载题目...</p>

    <div v-else-if="empty" class="card" style="text-align: center">
      <p>词库暂无单词，请先通过翻译添加单词。</p>
      <router-link to="/translate" class="btn btn-primary" style="margin-top: 12px; display: inline-block">
        去翻译
      </router-link>
    </div>

    <div v-else-if="finished" class="card summary">
      <h2>拼写练习完成 🎉</h2>
      <p>总题数：{{ sessionCorrect + sessionWrong }}</p>
      <p>答对：{{ sessionCorrect }}</p>
      <p>答错：{{ sessionWrong }}</p>
      <p>正确率：{{ accuracy() }}%</p>
      <router-link to="/" class="btn btn-primary" style="margin-top: 16px">返回首页</router-link>
    </div>

    <template v-else-if="current()">
      <SpellCard
        ref="spellCardRef"
        :question="current()!"
        :index="currentIndex"
        :total="questions.length"
        :show-result="showResult"
        :is-correct="isCorrect"
        :submitted-answer="submittedAnswer"
        @submit="onSubmit"
      />
      <button
        v-if="showResult"
        class="btn btn-primary"
        style="margin-top: 12px"
        @click="nextQuestion"
      >
        {{ currentIndex >= questions.length - 1 ? '查看结果' : '下一题' }}
      </button>
    </template>
  </div>
</template>

<style scoped>
.restore-hint {
  font-size: 13px;
  color: var(--primary);
  margin-bottom: 12px;
}
.summary h2 {
  margin-bottom: 12px;
  font-size: 20px;
}
.summary p {
  margin: 6px 0;
  font-size: 15px;
}
</style>
