<template>
  <container :title="status.title" v-loading="loading">
    <template v-slot:header-aside v-if="isStartExam">
      <template v-if="isCompleted">
        {{ $t('viewerWork.fraction') }}：{{ exam.score.total }}{{ $t('viewerWork.fractionUnit') }}
      </template>
      <template v-else>
        <div v-if="hasCountdown">倒计时：{{ countdownDurationText }}</div>
        <div v-else>{{ $t('viewerWork.examTime') }}：{{ status.start_time }} ~ {{ status.terminate_time }}</div>
      </template>
    </template>
    <div class="exam">
      <template v-if="status.examination_status === '00'">
        <div style="text-align: center; margin-top: 40px; margin-bottom: -60px">
          {{ $t('viewerWork.examTime') }}：{{ status.start_time }} ~ {{ status.terminate_time }}
        </div>
        <div class="no-exam">{{ $t('viewerWork.examEmpty') }}</div>
      </template>
      <template v-else-if="isSubmited && !isCompleted && !isMultipleExams">
        <div class="no-exam">{{ $t('viewerWork.examSubmitedTips') }}</div>
      </template>
      <template v-else>
        <!-- 考试期间，未开始考试 -->
        <div class="exam-welcome" v-if="!isStartExam">
          <div class="inner">
            <div>{{ $t('viewerWork.examTime') }}：{{ status.start_time }} ~ {{ status.terminate_time }}</div>
            <div v-if="hasCountdown">本场考试时间：{{ durationText }}。<br />时间用尽自动交卷，请您注意答题时间。</div>
          </div>
          <el-button type="primary" :disabled="!isExamTime" @click="onStartExam">{{ startExamButtonText }}</el-button>
        </div>
        <!-- 考试试题 -->
        <div class="exam-form" v-else>
          <el-form :disabled="!canEditable">
            <template v-for="items in questions">
              <exam-item
                v-for="(item, index) in items"
                :index="index"
                :type="item.type"
                :data="item"
                :value="item.formModel"
                :disabled="!canEditable"
                :showResult="isCompleted"
                :key="item.id"
              ></exam-item>
            </template>
          </el-form>
          <div class="exam-buttons">
            <!-- 允许多次提交 -->
            <template v-if="isMultipleExams">
              <el-button type="primary" @click="handlePrev" v-if="hasPrev">{{ $t('viewerWork.prevPapers') }}</el-button>
              <el-button type="primary" @click="handleNext" v-if="hasNext">{{ $t('viewerWork.nextPapers') }}</el-button>
              <el-button type="primary" @click="handleNewExam" v-if="hasResubmit && isExamTime">
                {{ $t('viewerWork.anotherSubmitText') }}
              </el-button>
            </template>
            <template v-if="!(isSubmited && isMultipleExams)">
              <el-tooltip effect="dark" :content="$t('viewerWork.examSubmitButtonTips')" placement="right">
                <el-button type="primary" :disabled="!canEditable" :loading="submitLoading" @click="onSubmit">{{
                  submitText
                }}</el-button>
              </el-tooltip>
            </template>
          </div>
        </div>
      </template>
    </div>
  </container>
</template>

<script>
import Base64 from 'Base64'

// components
import Container from '../common/container.vue'
import ExamItem from './examItem.vue'
// api
import * as api from '../../api'
import tool from '@/tool/index'

// 课后考试
export default {
  name: 'CourseExam',
  components: { Container, ExamItem },
  props: {
    // 当前选中的章节
    chapter: { type: Object, default: () => {} },
    // 课程详情接口返回的数据
    data: { type: Object, default: () => {} }
  },
  data() {
    return {
      loading: false,
      detail: {},
      status: {},
      questions: [],
      messageInstance: null,
      exam: {},
      autoSubmitTimer: null, // 自动提交定时器
      checkStatusTimer: null, // 考试状态定时器
      submitLoading: false,
      isMultipleExams: false, // 是否可以多次考试
      maxExams: 3, // 最多考试几次
      countdownDuration: 0, // 倒计时剩余时间
      countdownTimer: null,
      isStartExam: false
    }
  },
  watch: {
    offset: {
      immediate: true,
      handler() {
        this.init()
      }
    },
    examCount: {
      immediate: true,
      handler(value) {
        this.isStartExam = !!value
      }
    }
  },
  computed: {
    // 学期ID
    sid() {
      return this.$route.params.sid
    },
    // 课程ID
    cid() {
      return this.$route.params.cid
    },
    // 当前页面的ID
    pid() {
      return this.data.course_examination
    },
    // 是否是考试时间
    isExamTime() {
      // 大于开始时间，小于结束时间
      return this.status.examination_status === '20'
    },
    // 考试按钮
    startExamButtonText() {
      return this.status.examination_status === '90' ? '考试结束' : '开始考试'
    },
    // 是否提交
    isSubmited() {
      return this.exam.type === 1 || this.exam.type === 2
    },
    // 考试完成
    isCompleted() {
      // 考试完成，批改完成并且公布成绩
      return this.exam.is_published === 1 && this.exam.type === 2
    },
    // 可以编辑
    canEditable() {
      return !this.isSubmited && this.isExamTime
    },
    // 提交按钮文本
    submitText() {
      return this.isSubmited ? this.$t('viewerWork.submitedText') : this.$t('viewerWork.submitText')
    },
    // 试卷页码
    offset() {
      const { query } = this.$route
      return parseInt(query.offset) || 0
    },
    // 是否显示上一套试题
    hasPrev() {
      return !!this.offset
    },
    // 是否显示下一套试题
    hasNext() {
      return this.offset < this.examCount - 1
    },
    // 是否显示再考一次
    hasResubmit() {
      if (this.examCount >= this.maxExams) {
        return false
      }
      // 判断状态是否还有未提交的试题
      for (const exam of this.examList) {
        if (!['1', '2'].includes(exam.status)) {
          return false
        }
      }
      return true
    },
    // 已存在的试题列表
    examList() {
      return this.data.exist_examination
    },
    // 试卷数量
    examCount() {
      return this.examList ? this.examList.length : 0
    },
    // 是否有倒计时
    hasCountdown() {
      return !!this.status.duration && this.canEditable
    },
    // 倒计时文字
    countdownDurationText() {
      return tool.convertTime.durationToTimeString(this.countdownDuration)
    },
    durationText() {
      return tool.convertTime.durationToTimeString2(this.status.duration)
    }
  },
  methods: {
    // 初始化
    async init() {
      this.clearTimer()
      // 自动获取考试状态
      await this.autoCheckExamStatus()
      // 获取试题
      this.isStartExam && this.getExam()
    },
    // 开始考试
    onStartExam() {
      this.isStartExam = true
      this.getExam()
    },
    // 获取考试状态
    async getExamStatus() {
      await api.getCourseExamStatus(this.sid, this.cid, this.pid).then(response => {
        // examination_status
        // 00: 考场未开放，不允许进入
        // 10：考场开放，允许进入
        // 20：开始答题
        // 90：考试已结束
        this.status = response
        if (this.isSubmited || response.examination_status === '90') {
          this.checkStatusTimer && clearInterval(this.checkStatusTimer)
        }
      })
    },
    // 自动获取考试状态
    async autoCheckExamStatus() {
      // 获取试题状态
      await this.getExamStatus()
      this.checkStatusTimer && clearInterval(this.checkStatusTimer)
      this.checkStatusTimer = setInterval(this.getExamStatus, 1000)
    },
    // 获取试题
    getExam() {
      this.loading = true
      api
        .getCourseExamResult(this.sid, this.cid, this.pid, { offset: this.offset })
        .then(response => {
          this.exam = response
          this.questions = this.genQuestions(response.sheet)
          // 自动提交
          this.canEditable && this.autoSubmit()
          // 更新菜单
          this.isMultipleExams && this.$emit('update')
          // 倒计时剩余时间
          this.countdownDuration = this.status.duration - this.exam.duration
          // 开始倒计时
          this.hasCountdown && this.setCountdown()
        })
        .finally(() => {
          this.loading = false
        })
    },
    // 组装问题数据
    genQuestions(list) {
      if (!list) {
        return []
      }
      return list.map(data => {
        let { radioList = [], checkboxList = [], shortAnswerList = [], judgeList = [] } = data
        // 单选
        radioList = radioList.map(item => {
          const temp = {
            type: 1,
            formModel: { id: item.id, user_answer: item.user_answer || '' }
          }
          return Object.assign({}, item, temp)
        })
        // 多选
        checkboxList = checkboxList.map(item => {
          const temp = {
            type: 2,
            formModel: { id: item.id, user_answer: item.user_answer || [] }
          }
          return Object.assign({}, item, temp)
        })
        // 问答
        shortAnswerList = shortAnswerList.map(item => {
          const temp = {
            type: 3,
            formModel: {
              id: item.id,
              user_answer: item.user_answer ? Base64.decode(item.user_answer.replace(/ /gi, '+')) : '',
              attachments: item.attachments || []
            }
          }
          return Object.assign({}, item, temp)
        })
        // 判断题
        judgeList = judgeList.map(item => {
          const temp = {
            type: 4,
            formModel: { id: item.id, user_answer: item.user_answer || '' }
          }
          return Object.assign({}, item, temp)
        })
        return [...radioList, ...checkboxList, ...judgeList, ...shortAnswerList]
      })
    },

    // 提交校验
    checkSubmit() {
      for (let i = 0; i < this.questions.length; i++) {
        const questions = this.questions[i]
        for (let k = 0; k < questions.length; k++) {
          const value = questions[k].formModel.user_answer
          if (Array.isArray(value) ? !value.length : !value) {
            return false
          }
        }
      }
      return true
    },
    // 提交
    onSubmit() {
      // 校验
      if (!this.checkSubmit()) {
        this.messageInstance && this.messageInstance.close()
        this.messageInstance = this.$message.error(this.$t('viewerWork.examSubmitError'))
        return
      }
      // 提交的答案数据
      const answers = this.handleSubmitData()
      // 提交参数
      const params = { answers: JSON.stringify(answers), type: 1 }
      // 请求接口
      this.submitLoading = true
      this.handleSubmitRequest(params)
    },
    // 自动提交
    autoSubmit() {
      // 10秒提交一次
      this.autoSubmitTimer && clearInterval(this.autoSubmitTimer)
      this.autoSubmitTimer = setInterval(() => {
        // 提交的答案数据
        const answers = this.handleSubmitData()
        const params = { answers: JSON.stringify(answers), type: 0 }
        // 请求接口
        this.handleSubmitRequest(params)
      }, 10000)
    },
    // 处理请求接口答案数据
    handleSubmitData() {
      return this.questions.map(questions => {
        return questions.reduce(
          (result, item) => {
            // 单选题
            if (item.type === 1) {
              result.radioList.push(item.formModel)
            }
            // 多选题
            if (item.type === 2) {
              result.checkboxList.push(item.formModel)
            }
            // 简答题
            if (item.type === 3) {
              const formModel = Object.assign({}, item.formModel, {
                user_answer: Base64.encode(item.formModel.user_answer)
              })
              result.shortAnswerList.push(formModel)
            }
            // 判断题
            if (item.type === 4) {
              result.judgeList.push(item.formModel)
            }
            return result
          },
          { radioList: [], checkboxList: [], shortAnswerList: [], judgeList: [] }
        )
      })
    },
    // 请求提交接口
    handleSubmitRequest(params) {
      params.offset = this.offset
      api
        .submitCourseExam(this.sid, this.cid, this.pid, params)
        .then(response => {
          if (params.type === 0) {
            console.log('暂存成功')
            return
          }
          if (response.code === 200) {
            this.$message.success(this.$t('viewerWork.examSubmitSuccess'))
            this.autoSubmitTimer && clearInterval(this.autoSubmitTimer)
            this.getExam()
          } else {
            this.$message.error(response.data.error)
          }
        })
        .catch(error => {
          if (!params.type) return
          this.$message.error(error.message)
          this.autoSubmitTimer && clearInterval(this.autoSubmitTimer)
          this.getExam()
        })
        .finally(() => {
          this.submitLoading = false
        })
    },
    // 上一套试卷
    handlePrev() {
      const offset = this.offset - 1
      this.$router.push({ query: { offset } })
    },
    handleNext() {
      const offset = this.offset + 1
      this.$router.push({ query: { offset } })
    },
    handleNewExam() {
      this.$router.push({ query: { offset: this.examCount } })
    },
    // 清除定时器
    clearTimer() {
      this.autoSubmitTimer && clearInterval(this.autoSubmitTimer)
      this.checkStatusTimer && clearInterval(this.checkStatusTimer)
      this.countdownTimer && clearInterval(this.countdownTimer)
    },
    // 设置倒计时
    setCountdown() {
      this.countdownTimer && clearInterval(this.countdownTimer)
      this.countdownTimer = setInterval(() => {
        this.countdownDuration--
        if (this.countdownDuration <= 0) {
          this.countdownTimer && clearInterval(this.countdownTimer)
        }
      }, 1000)
    }
  },
  beforeMount() {
    // // 自动获取考试状态
    // this.autoCheckExamStatus()
    // // 获取试题
    // this.getExam()
  },
  destroyed() {
    this.clearTimer()
  }
}
</script>

<style lang="scss" scoped>
.exam-buttons {
  padding: 40px 0;
  text-align: center;
  .el-button {
    min-width: 160px;
    margin: 40px auto;
  }
}
.no-exam {
  padding: 100px;
  font-size: 30px;
  text-align: center;
}
.exam-welcome {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 30px;
  ::v-deep .el-button {
    margin-top: 30px;
  }
}
</style>
