<template>
  <div v-loading="loading" class="answer">
    <header class="header">
      <div class="back round" @click="goBack">
        <i class="el-icon-arrow-left"></i>
        <span>返回</span>
      </div>
      <div class="question-info">
        <div class="round">
          <SvgIcon icon-class="list" />
          <span>{{ curQuestionIndex + 1 }} / {{ questionList.length }}</span>
        </div>
        <div v-if="!isTeacherAnnotations" class="round primary">
          <SvgIcon icon-class="hourglass" />{{ secondFormatConversion(time) }}
        </div>
      </div>
    </header>

    <main class="main">
      <StartQuestion
        v-if="
          curQuestionIndex === -1 && !(user_answer_record_info.is_exist_answer_record === 'true' && answer_mode === 2)
        "
        :question-length="questionList.length"
        :answer-time-limit-minute="answer_time_limit_minute"
        @startAnswer="startAnswer"
      />

      <AnswerReport v-else-if="isSubmit" :record-report="recordReport" @selectQuestion="selectQuestion" />

      <template v-for="({ id }, i) in questionList" v-else>
        <component
          :is="curQuestionPage"
          v-if="i === curQuestionIndex"
          :key="id"
          ref="exercise"
          :data="currentQuestion"
        />
      </template>
    </main>

    <footer class="footer">
      <el-popover v-model="isPopover" placement="top-start" trigger="click">
        <div v-if="isEnable(remark.is_remarked) && !isTeacher" class="remark-container">
          <div class="remark-info">
            <el-avatar :size="24" :src="remark.remark_person_image_url" />
            <span class="remark-name">{{ remark.remark_person_name }}</span>
            <span class="remark-time">{{ remark.remark_time }}</span>
          </div>
          <div class="remark">
            {{ remark.remark }}
          </div>
          <div class="file">
            <el-image v-for="{ file_url, file_id } in remark.file_list" :key="file_id" :src="file_url" fit="contain" />
          </div>
        </div>

        <div v-else class="annotations-container">
          <div class="title">增加批注</div>
          <div class="score">
            <span>分数</span>
            <el-input-number v-model="remark.score" :min="0" :step="1" />
          </div>
          <el-input v-model="remark.remark" type="textarea" rows="6" resize="none" class="remark" />
          <div>图片/视频</div>

          <el-upload action="no" accept="video/*,image/*" :show-file-list="false" :http-request="upload">
            <div class="upload">
              <i class="el-icon-plus avatar-uploader-icon"></i>
              <span>Upload</span>
            </div>
          </el-upload>
          <ul class="file-list">
            <li v-for="({ file_name, file_id }, i) in remark.file_list" :key="file_id" @click="removeFile(i)">
              <span>{{ file_name }}</span>
              <SvgIcon icon-class="delete" />
            </li>
          </ul>

          <div class="popover-footer">
            <el-button @click="isPopover = false">取消</el-button>
            <el-button type="primary" @click="fillQuestionAnswerRemark">确定</el-button>
          </div>
        </div>

        <div
          v-show="isAnnotations"
          slot="reference"
          :class="['annotations', { has: isEnable(remark.is_remarked) && !isTeacher }]"
        >
          <template v-if="isEnable(remark.is_remarked) && !isTeacher">
            <span>有一条教师批注</span>
          </template>
          <template v-else><i class="el-icon-plus"></i><span>批注</span></template>
        </div>
      </el-popover>

      <div>
        <template
          v-if="
            curQuestionIndex === -1 && !(user_answer_record_info.is_exist_answer_record === 'true' && answer_mode === 2)
          "
        >
          <el-button type="primary" round @click="startAnswer">开始答题</el-button>
        </template>

        <template v-else-if="isSubmit">
          <el-button v-if="answer_mode === 1" round type="primary" @click="startAnswer">开始答题</el-button>
        </template>

        <template v-else>
          <el-button round @click="fillQuestionAnswer('pre')">上一题</el-button>
          <el-button
            v-if="curQuestionIndex === questionList.length - 1 && !isTeacherAnnotations"
            type="primary"
            round
            @click="submitAnswer"
          >
            提交
          </el-button>
          <el-button
            v-else-if="curQuestionIndex < questionList.length - 1 || !isTeacherAnnotations"
            type="primary"
            round
            @click="fillQuestionAnswer('next')"
            >下一题</el-button
          >
        </template>
      </div>
    </footer>
  </div>
</template>

<script>
import { secondFormatConversion } from '@/utils/transform';
import {
  GetExerciseQuestionIndexList,
  GetShareRecordInfo,
  StartAnswer,
  FillQuestionAnswer,
  SubmitAnswer,
  GetQuestionInfo_AnswerRecord,
  FillQuestionAnswerRemark,
  GetAnswerRecordReport,
} from '@/api/exercise';
import { subjectiveQuestionList } from './answer';
import { fileUpload } from '@/api/app';

import StartQuestion from './components/StartQuestion.vue';
import AnswerReport from './components/AnswerReport.vue';
import PreviewQuestionTypeMixin from '../data/PreviewQuestionTypeMixin';

export default {
  name: 'AnswerPage',
  components: {
    StartQuestion,
    AnswerReport,
  },
  mixins: [PreviewQuestionTypeMixin],
  data() {
    const { id, share_record_id, answer_record_id, exercise_id, question_index } = this.$route.query;
    let questionIndex = Number(question_index);

    return {
      exercise_id: id || exercise_id, // 练习题id
      share_record_id, // 分享记录id
      answer_record_id: answer_record_id ?? '', // 答题记录id
      secondFormatConversion,
      isTeacher: this.$store.getters.isTeacher, // 是否是教师
      user_answer_record_info: {
        correct_answer_show_mode: 1, // 正确答案显示模式
      }, // 当前用户的答题记录信息
      // 问题列表
      questionList: [],
      // 当前问题
      currentQuestion: {},
      // 当前问题索引
      curQuestionIndex: -1,
      question_index: questionIndex >= 0 ? questionIndex : -1, // 跳转的问题索引
      loading: false,
      // 倒计时
      countDownTimer: null,
      answer_mode: 1, // 答题模式
      answer_time_limit_minute: 30, // 答题时间限制
      time: 1800,
      isSubmit: false,
      isView: false, // 练习模式下是否查看
      curQuestionPage: '', // 当前问题页面
      remark: {
        is_remarked: 'false',
        score: 0,
        remark: '',
        remark_person_image_url: '',
        remark_person_name: '',
        remark_time: '',
        file_list: [],
      }, // 批注
      isPopover: false,
      recordReport: {
        answer_record: {
          answer_duration: 0,
          right_count: 0,
          error_count: 0,
          is_remarked: 'false',
        },
        question_list: [],
      }, // 答题报告
    };
  },
  computed: {
    // 是否教师批改
    isTeacherAnnotations() {
      return this.question_index >= 0 && this.isTeacher;
    },
    // 是否显示批注
    isAnnotations() {
      return this.remark.is_remarked === 'true' || this.isTeacherAnnotations;
    },
    // 是否考试模式
    isExamMode() {
      return this.answer_mode === 2;
    },
  },
  watch: {
    curQuestionIndex() {
      this.getQuestionInfo_AnswerRecord();
    },
    isSubmit(val) {
      if (val) {
        this.getAnswerRecordReport();
      }
    },
  },
  created() {
    this.init();
  },
  beforeDestroy() {
    if (this.countDownTimer) clearInterval(this.countDownTimer);
  },
  methods: {
    // 初始化
    init() {
      if (this.exercise_id) {
        this.getExerciseQuestionIndexList();
      }

      if (this.share_record_id && !this.exercise_id) {
        this.loading = true;
        GetShareRecordInfo({ share_record_id: this.share_record_id }).then(
          ({ user_answer_record_info, share_record: { exercise_id, answer_mode, answer_time_limit_minute } }) => {
            this.user_answer_record_info = user_answer_record_info;
            this.exercise_id = exercise_id;
            this.getExerciseQuestionIndexList();
            this.answer_time_limit_minute = answer_time_limit_minute;
            this.time = answer_time_limit_minute * 60;
            this.loading = false;
            // 如果是考试模式，且已经存在答题记录，则直接显示答题报告
            if (this.user_answer_record_info.is_exist_answer_record === 'true' && !this.isTeacher) {
              this.answer_record_id = this.user_answer_record_info.answer_record_id;
              this.answer_mode = answer_mode;
              // 如果是考试模式，且已经存在答题记录，则直接显示答题报告
              if (this.isExamMode) this.isSubmit = true;
            }
            if (!this.isTeacher) {
              this.getAnswerRecordReport();
            }
          },
        );
      }
    },
    // 获取答题报告
    getAnswerRecordReport() {
      if (!this.answer_record_id) return;
      GetAnswerRecordReport({ answer_record_id: this.answer_record_id })
        .then(({ answer_record, question_list }) => {
          if (answer_record.is_remarked === 'true') {
            this.isSubmit = true;
            this.curQuestionIndex = 0;
          }
          this.recordReport = {
            answer_record,
            question_list,
          };
        })
        .catch(() => {});
    },
    getExerciseQuestionIndexList() {
      GetExerciseQuestionIndexList({ exercise_id: this.exercise_id }).then(({ index_list }) => {
        this.questionList = index_list.map((item) => ({
          ...item,
          isFill: this.isTeacherAnnotations,
        }));
        if (this.question_index >= 0) {
          this.curQuestionIndex = this.question_index;
        }
      });
    },
    goBack() {
      if (this.isView) {
        this.isSubmit = true;
        this.isView = false;
        return;
      }
      this.$router.push('/personal_question');
    },
    // 倒计时
    countDown() {
      this.countDownTimer = setInterval(() => {
        this.time -= 1;
        if (this.time === 0) {
          clearInterval(this.countDownTimer);
        }
      }, 1000);
    },
    startAnswer() {
      if (!this.share_record_id) {
        this.curQuestionIndex = 0;
        return;
      }
      StartAnswer({ exercise_id: this.exercise_id, share_record_id: this.share_record_id }).then(
        ({ answer_mode, answer_record_id }) => {
          this.answer_record_id = answer_record_id;
          this.countDown();
          this.answer_mode = answer_mode;
          this.curQuestionIndex = 0;
          this.isSubmit = false;
        },
      );
    },
    preQuestion() {
      if (this.curQuestionIndex === 0) return;
      this.curQuestionIndex -= 1;
    },
    nextQuestion() {
      if (this.curQuestionIndex === this.questionList.length - 1) return;
      this.curQuestionIndex += 1;
    },
    /**
     * 填写答案
     * @param {'pre' | 'next'} type 上一题/下一题
     */
    fillQuestionAnswer(type) {
      if (type === 'pre' && this.curQuestionIndex <= 0) return;
      if (type === 'next' && this.curQuestionIndex > this.questionList.length - 1) return;
      if (!this.answer_record_id) {
        this.curQuestionIndex = type === 'pre' ? this.curQuestionIndex - 1 : this.curQuestionIndex + 1;
        return;
      }
      // 如果已填写，直接跳转
      if (this.questionList[this.curQuestionIndex].isFill) {
        if (type === 'pre') return this.preQuestion();
        if (type === 'next') return this.nextQuestion();
      }

      return FillQuestionAnswer({
        answer_record_id: this.answer_record_id,
        question_id: this.questionList[this.curQuestionIndex].id,
        answer: JSON.stringify(this.$refs.exercise[0].answer),
      }).then(() => {
        this.questionList[this.curQuestionIndex].isFill = true;
        if (subjectiveQuestionList.includes(this.currentQuestion.type) || this.isExamMode) {
          if (type === 'pre') return this.preQuestion();
          if (type === 'next') return this.nextQuestion();
        }
        // 显示答案
        this.$refs.exercise[0].showAnswer(
          this.answer_mode === 1,
          this.user_answer_record_info.correct_answer_show_mode === 1,
        );
      });
    },
    // 得到答题记录题目信息
    getQuestionInfo_AnswerRecord() {
      GetQuestionInfo_AnswerRecord({
        answer_record_id: this.answer_record_id,
        question_id: this.questionList[this.curQuestionIndex].id,
      }).then(({ question, user_answer: { is_fill_answer, content }, remark }) => {
        // 批注
        this.remark = remark;

        // 题目内容
        if (question.content) {
          this.currentQuestion = JSON.parse(question.content);
          this.curQuestionPage =
            this.questionList.length === 0 || this.curQuestionIndex < 0
              ? ''
              : this.previewComponents[this.questionList[this.curQuestionIndex].type];
        }

        // 如果已经填写过答案，直接显示答案
        if (is_fill_answer === 'true') {
          this.$nextTick().then(() => {
            this.$refs.exercise?.[0].showAnswer(
              this.answer_mode === 1 && !this.isTeacherAnnotations,
              this.user_answer_record_info.correct_answer_show_mode === 1 && !this.isTeacherAnnotations,
              content.length > 0 ? JSON.parse(content) : null,
            );
          });
        }
      });
    },
    // 提交答题
    submitAnswer() {
      if (!this.answer_record_id) return;

      this.$confirm('是否确认提交答题？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          clearInterval(this.countDownTimer);
          // 如果已经填写过答案，直接提交
          if (this.questionList[this.curQuestionIndex].isFill) {
            SubmitAnswer({ answer_record_id: this.answer_record_id })
              .then(() => {
                this.isSubmit = true;
              })
              .catch(() => {});
            return;
          }

          this.fillQuestionAnswer('next').then(() => {
            SubmitAnswer({ answer_record_id: this.answer_record_id })
              .then(() => {
                this.isSubmit = true;
              })
              .catch(() => {});
          });
        })
        .catch(() => {});
    },
    selectQuestion(i) {
      this.isSubmit = false;
      this.isView = true;
      this.curQuestionIndex = i;
    },
    upload(file) {
      fileUpload('Mid', file).then(({ file_info_list }) => {
        if (file_info_list.length > 0) {
          const { file_id, file_url, file_name } = file_info_list[0];
          this.remark.file_list.push({ file_id, file_url, file_name });
        }
      });
    },
    removeFile(i) {
      this.remark.file_list.splice(i, 1);
    },
    // 填写批注
    fillQuestionAnswerRemark() {
      FillQuestionAnswerRemark({
        answer_record_id: this.answer_record_id,
        question_id: this.questionList[this.curQuestionIndex].id,
        file_id_list: this.remark.file_list.map(({ file_id }) => file_id),
        score: this.remark.score,
        remark: this.remark.remark,
      }).then(() => {
        this.$message.success('批注成功');
        this.isPopover = false;
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.answer {
  display: flex;
  flex-direction: column;
  row-gap: 16px;
  height: 100%;
  padding: 16px;
  background-color: #fff;
  border-radius: 24px;
  box-shadow: 0 6px 30px 5px #0000000d;

  .header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 38px;
    font-size: 14px;

    .back {
      cursor: pointer;
    }

    .question-info {
      display: flex;
      column-gap: 12px;
    }
  }

  .main {
    flex: 1;
  }

  .footer {
    position: relative;
    display: flex;
    justify-content: center;

    .annotations {
      position: absolute;
      left: 0;
      display: flex;
      column-gap: 8px;
      align-items: center;
      padding: 7px 16px;
      font-size: 14px;
      cursor: pointer;
      background-color: $fill-color;
      border-radius: 20px;

      &.has {
        color: $danger-color;
        background-color: #ffece8;
      }
    }

    .el-button {
      padding: 9px 40px;
    }
  }
}
</style>

<style lang="scss">
.el-popover {
  display: flex;
  flex-direction: column;
  row-gap: 8px;
  padding: 8px 8px 14px;
  font-size: 14px;

  .remark-container {
    display: flex;
    flex-direction: column;
    row-gap: 8px;

    .remark-info {
      display: flex;
      column-gap: 8px;
      align-items: center;

      .remark-name {
        flex: 1;
      }

      .remark-time {
        font-size: 12px;
        color: #999;
      }
    }

    .file {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;

      .el-image {
        width: 80px;
        height: 80px;
        background-color: #d9d9d9;
      }
    }
  }

  .annotations-container {
    display: flex;
    flex-direction: column;
    row-gap: 8px;

    .title {
      color: #000;
    }

    .score {
      display: flex;
      column-gap: 8px;
      align-items: center;

      :first-child {
        color: #999;
      }
    }

    .remark {
      width: 350px;
    }

    .upload {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-around;
      width: 80px;
      height: 80px;
      padding: 8px;
      background-color: $fill-color;
      border: 1px solid $border-color;
    }

    .file-list {
      display: flex;
      flex-direction: column;
      row-gap: 4px;

      > li {
        display: flex;
        column-gap: 4px;

        :first-child {
          flex: 1;
        }

        :last-child {
          cursor: pointer;
        }
      }
    }

    .popover-footer {
      display: flex;
      justify-content: flex-end;
    }
  }
}
</style>
