<template>
  <container :title="detail.paper_title" v-loading="loading">
    <template v-slot:header-aside v-if="isExamComplete">分数：{{exam.score.total}}分</template>
    <div class="exam">
      <template v-if="isSubmited && !isExamComplete">
        <div class="no-exam">试卷批改中，请耐心等待</div>
      </template>
      <template v-else>
        <!-- 考试期间，未开始考试 -->
        <div class="exam-welcome" v-if="!isStartExam">
          <div v-if="detail.paper_deadline">考试截止时间：{{detail.paper_deadline}}</div>
          <el-button
            type="primary"
            :disabled="!isExamTime"
            @click="onStartExam"
          >{{startExamButtonText}}</el-button>
        </div>
        <!-- 考试试题 -->
        <div class="exam-form" v-if="isStartExam">
          <el-form :disabled="isSubmited">
            <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="isSubmited"
                :key="item.id"
              ></exam-item>
            </template>
            <div class="exam-buttons">
              <el-tooltip effect="dark" content="提交之后就不能修改了哦" placement="right">
                <el-button type="primary" :loading="submitLoading" @click="onSubmit">{{submitText}}</el-button>
              </el-tooltip>
            </div>
          </el-form>
        </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'

// 章节测试题
export default {
  name: 'ChapterExam',
  components: { Container, ExamItem },
  props: {
    // 当前选中的章节
    chapter: {
      type: Object,
      default() {
        return {}
      }
    },
    // 课程详情接口返回的数据
    data: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      loading: false,
      detail: {},
      questions: [],
      messageInstance: null,
      exam: {},
      isStartExam: false, // 是否开始考试
      autoSubmitTimer: null, // 自动提交定时器
      submitLoading: false
    }
  },
  watch: {
    chapter: {
      immediate: true,
      handler(data) {
        this.detail = data.paper
        this.questions = data.paper
          ? this.genQuestions(data.paper.examination)
          : []
      }
    }
  },
  computed: {
    // 学期ID
    sid() {
      return this.$route.params.sid
    },
    // 课程ID
    cid() {
      return this.$route.params.cid
    },
    // 当前页面的ID
    pid() {
      return this.$route.params.id
    },
    // 是否是考试时间
    isExamTime() {
      if (!this.detail.paper_deadline) {
        return true
      }
      // 大于开始时间，小于结束时间
      const endTime = +new Date(this.exam.paper_deadline)
      const currentTime = new Date().getTime()
      return currentTime < endTime
    },
    // 考试按钮
    startExamButtonText() {
      return this.isExamTime ? '开始考试' : '考试结束'
    },
    // 考试完成
    isExamComplete() {
      // 考试完成，批改完成并且公布成绩
      return this.exam.is_published === 1 && this.exam.type === 2
    },
    // 是否提交
    isSubmited() {
      return this.exam.type === 1 || this.exam.type === 2
    },
    // 提交按钮文本
    submitText() {
      return this.isSubmited ? '已提交' : '提交'
    }
  },
  methods: {
    // 开始考试
    onStartExam() {
      this.isStartExam = true
      // 自动提交答题
      this.autoSubmit()
    },
    // 组装问题数据
    genQuestions(list) {
      if (!list) {
        return []
      }
      return list.map(data => {
        let { radioList, checkboxList, shortAnswerList } = 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)
        })
        return [...radioList, ...checkboxList, ...shortAnswerList]
      })
    },
    // 获取考试结果
    getExamResult() {
      api
        .getCourseExamResult(this.sid, this.cid, this.pid, { paper_type: 0 })
        .then(response => {
          // 设置问题列表数据
          if (response.code !== 8001) {
            this.isStartExam = true
            this.exam = response
            this.questions = this.genQuestions(response.sheet)
            // 自动提交
            if (this.isStartExam && !this.isSubmited && !this.isExamComplete) {
              this.autoSubmit()
            }
          }
        })
    },
    // 提交校验
    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('还有题目未做，不能提交')
        return
      }
      // 提交的答案数据
      const answers = this.handleSubmitData()
      // 提交参数
      const params = { answers: JSON.stringify(answers), type: 1 }
      // 请求接口
      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)
            }
            return result
          },
          { radioList: [], checkboxList: [], shortAnswerList: [] }
        )
      })
    },
    // 请求提交接口
    handleSubmitRequest(params) {
      this.submitLoading = true
      params.paper_type = 0
      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.autoSubmitTimer && clearInterval(this.autoSubmitTimer)
            this.getExamResult()
          } else {
            this.$message.error(response.data.error)
          }
        })
        .catch(error => {
          this.$message.error(error.message)
        })
        .finally(() => {
          this.submitLoading = false
        })
    }
  },
  beforeMount() {
    // 获取考试结果
    this.getExamResult()
  },
  destroyed() {
    this.autoSubmitTimer && clearInterval(this.autoSubmitTimer)
  }
}
</script>

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