<script setup lang="ts">
import { level_type_advance, level_type_begin, result_right } from '@/components/word-game'
import type { Question } from '@/components/word-game'
import { globalBack } from '@/router'
import hud from '@/utils/hud'
import useAudio from '@/hooks/useCommonAudio'
import { OSS_URL } from '@/utils'
import wordTestApi from '@/api/subject/wordTest'
import RecordDetailPop from '@/page/subject/learnWord/word-table/test/components/RecordDetailPop.vue'

const props = withDefaults(
  defineProps<{
    countDown?: any
    subtitle: any
    params: any
    keyboardOpen?: any
    emptyText?: any
  }>(),
  {
    countDown: false,
    subtitle: '',
    params: {},
    keyboardOpen: false,
    emptyText: '暂无单词',
  },
)

defineOptions({ name: 'WordGame' })

// 音频base_url
const soundBaseUrl = `${OSS_URL}/xuexiaole_clinet/sound`

const progress = ref(0)
// 是否结束
const end = ref(false)
// 是否显示答题报告
const showReport = ref(false)
const reportData = ref({} as any)

// 开始时间
let startTime = undefined as any

// 靠上一个界面请求后传递数据过来
const questions = ref([] as Question[])

// 当前的题目索引
const curQuestionIndex = ref(0)

// 正确的题目数量
const rightCount = ref(0)

// 当前的题目
const curQuestion = computed(() => {
  return questions.value[curQuestionIndex.value] || {}
})

// 耗时
const time = ref(0)
const durationTime = computed(() => {
  if (!time.value) return 0
  const h = parseInt(String((time.value / 60 / 60) % 24), 10)
  const m = parseInt(String((time.value / 60) % 60), 10)
  const s = parseInt(String(time.value % 60), 10)

  if (time.value === undefined) return

  if (h > 0) {
    return `${h}h ${m}m`
  } else if (m > 0) {
    return `${m}m ${s}s`
  } else if (s > 0) {
    return `${s}s`
  } else {
    return '0'
  }
})

// 最好连击
const comboNum = ref(0)

// 退出的确认
function confirmExit() {
  if (!end.value) {
    hud.alert({
      content: '确认退出？',
      ok: async () => {
        if (props.params?.testType === 7) {
          requestComplete()
        }
        globalBack()
      },
    })
  } else {
    globalBack()
  }
}

// 开始倒计时定时器
let durationTimer = undefined as any
function startDurationTimer() {
  stopDurationTimer()

  durationTimer = setInterval(() => {
    time.value++
  }, 1000)
}

// 结束定时器
function stopDurationTimer() {
  clearInterval(durationTimer)
}

const showCombo = ref(false)
watch(
  () => showCombo.value,
  nv => {
    if (nv) {
      setTimeout(() => {
        showCombo.value = false
      }, 1000)
    }
  },
)

// 是否为最后一题
const last = computed(() => curQuestionIndex.value === questions.value?.length - 1)

// 进入下一题
function toNextQuestion() {
  if (last.value) return
  curQuestionIndex.value++
  // 下一题又开始了
  startTime = Date.now()
}

// 处理结果
async function handlePostResult(result: any, surrender: any, duration: any) {
  // 进度条
  progress.value = Math.trunc(((curQuestionIndex.value + 1) / questions.value.length) * 100)

  if (result === result_right) {
    // 回答正确
    rightCount.value++
    // 增加连击数
    comboNum.value++
    if (comboNum.value > 1) {
      showCombo.value = true
    }
  } else {
    // 回答错误
    comboNum.value = 0
  }

  // 拿到当前题目
  const q = curQuestion.value

  // 是否答对
  const isRight = result === result_right

  // 获取题目类型
  let questionType = 0
  if (q.levelType === level_type_advance) {
    questionType = 1
  }

  const willEnd = progress.value === 100
  if (willEnd) {
    hud.loading('正在保存中')
  }

  try {
    // 保存单题目的结果
    await wordTestApi.saveWordTest({
      duration,
      questionType,
      levelId: q.levelId,
      saveTime: Date.now(),
      sessionId: q.sessionId,
      surrender: surrender ? 1 : 0,
      testResult: isRight ? 1 : 0,
      wordId: q.wordId,
      imageUrl: q.titlePicture,
      meaningId: q.meaningId,
      titleFrom: q.titleFrom,
      levelType: q.levelType,
    })
  } finally {
    if (willEnd) {
      // 如果是最后一题
      end.value = true
    }
  }
}

function submitError() {
  hud.alert({
    title: '保存失败',
    content: '是否重新保存？',
    hideClose: true,
    maskClose: false,
    cancelText: '退出',
    ok: async () => {
      submit()
    },
    cancel: () => globalBack(),
  })
}

// 播放
const sound = useAudio()

async function requestComplete() {
  // 发送请求
  return await wordTestApi.completeWordTest({
    id: questions.value[0].sessionId,
    rightNum: rightCount.value,
    totalNum: questions.value.length,
    comboNum: comboNum.value,
    duration: time.value * 1000,
    endTime: Date.now(),
    sessionId: questions.value[0].sessionId,
  })
}

async function submit() {
  if (!hud.isLoading()) {
    hud.loading('正在保存中')
  }
  try {
    // 发送请求
    reportData.value = await requestComplete()

    // 显示报告
    showReport.value = true

    // 播放音频
    const rightRate = Math.trunc((rightCount.value / questions.value.length) * 10000)
    if (rightRate >= 10000) {
      sound.play(`${soundBaseUrl}/show_seal.mp3`)
    } else if (rightRate > 0) {
      sound.play(`${soundBaseUrl}/star_success.mp3`)
    } else {
      sound.play(`${soundBaseUrl}/show_fail.mp3`)
    }

    setTimeout(() => {
      sound.play(`${soundBaseUrl}/show_nextBtn.mp3`)
    }, 1500)
  } catch (error) {
    submitError()
  } finally {
    hud.hideLoading()
  }
}

watch(
  () => end.value,
  () => {
    if (!end.value) return

    // 停止定时器
    stopDurationTimer()

    // 提交最终请求
    submit()
  },
)

function loadQuestions() {
  hud.load({
    task: async () => {
      try {
        // 清空数据
        time.value = 0
        rightCount.value = 0
        comboNum.value = 0
        progress.value = 0
        end.value = false
        showReport.value = false
        curQuestionIndex.value = 0
        questions.value = []

        // 发送请求
        startTime = Date.now()
        const res = await wordTestApi.getWordTestWords({
          startTime,
          ...props.params,
        })
        questions.value = [...(res.chooseTitle || []), ...(res.spellTitle || [])]
        if (questions.value.length > 0) {
          curQuestionIndex.value = 0
          startDurationTimer()
        } else {
          hud.alert({
            content: props.emptyText,
            ok: () => globalBack(),
            hideClose: true,
            hideCancel: true,
            maskClose: false,
          })
          // hud.error(props.emptyText)
          // globalBack()
        }
      } catch (error) {
        hud.alert({
          content: '加载失败',
          ok: () => globalBack(),
          hideClose: true,
          hideCancel: true,
          maskClose: false,
        })
      }
    },
    option: '加载',
    hideSuccess: true,
  })
}

onMounted(() => {
  loadQuestions()
})

onUnmounted(() => {
  stopDurationTimer()
})
</script>

<template>
  <div class="word-test">
    <BackBar class="back-bar" show-only @click="confirmExit" />
    <new-progress-bar class="progress-bar" :progress="progress" />
    <div class="title-bar">
      <heart-bg />
      <div class="title-item">耗时：{{ durationTime }}</div>
      <div class="title-item">
        正确：<span :class="{ 'right-count': rightCount }">{{ rightCount }}</span
        >/{{ questions?.length }}
      </div>
      <div class="title-item">最好连击：{{ comboNum }}</div>
    </div>
    <div class="content">
      <word-single-choice
        v-if="curQuestion.levelType === level_type_begin"
        :data="curQuestion as any"
        :last="last"
        :end="end"
        :count-down="countDown"
        @post-result="handlePostResult"
        @next="toNextQuestion"
      />
      <word-spelling-bee
        v-if="curQuestion.levelType === level_type_advance"
        :end="end"
        :open="keyboardOpen"
        :data="curQuestion as any"
        :last="last"
        :count-down="countDown"
        @post-result="handlePostResult"
        @next="toNextQuestion"
      />
      <WinningStreakAnimation v-if="showCombo" :num="comboNum" />
    </div>
    <div class="bottom-title">{{ subtitle }}</div>
    <div id="learn-audio"></div>
  </div>
  <RecordDetailPop
    v-model="showReport"
    v-bind="reportData as any"
    islastPop
    @back="globalBack"
    @next="loadQuestions"
  />
</template>

<style lang="scss" scoped>
.word-test {
  position: relative;
  height: 100%;
  overflow: auto;
  padding-top: 2.67vh;
  @include main_bg;

  .right-count {
    color: #42c20b;
  }

  .title-bar {
    position: relative;
    width: 1085px;
    height: 7.67vh;
    background-color: #a0fcf8;
    border-top-left-radius: 40px;
    border-top-right-radius: 40px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    overflow: hidden;

    .title-item {
      flex: 1;
      text-align: center;
      font-size: 3.33vh;
      font-family: $font-text;
      color: rgba(0, 0, 0, 0.65);
      z-index: 1;
    }
  }

  .content {
    padding: 0 32px;
    position: relative;
    top: -0.08vh;
  }

  .back-bar {
    position: absolute;
    top: 2.67vh;
    left: $space-6;
    z-index: 1;
  }

  .progress-bar {
    position: absolute;
    top: 2.67vh;
    right: 32px;
    z-index: 1;
  }

  .bottom-title {
    text-align: center;
    color: #4b4b68;
    font-size: 2.33vh;
    height: 2.67vh;
    line-height: 2.67vh;
    margin-top: 1vh;
    font-family: $font-text;
  }
}
</style>
