<template>
  <div class="page-through-question-box">
    <van-nav-bar title="闯关答题" left-arrow @click-left="handleBackFun" />
    <!-- 题目卡片 -->
    <div v-if="answerThroughNumber" class="through-question-div">
      <div class="through-question-card">
        <div class="through-question-number">第{{ answerThroughNumber }}关</div>
      </div>
    </div>
    <!-- 题目卡片 -->
    <div class="through-question-div">
      <div v-if="examQuestionList.length > 0" class="through-question-card">
        <!-- 标题、分数、题页 -->
        <div class="through-question-head">
          <div class="through-question-head-left">
            <div class="through-question-head-left-icon"></div>
            <div class="through-question-head-left-txt">
              {{ examQuestionList[answerIndex].typeTxt || "undefind" }}
            </div>
          </div>
          <div class="through-question-head-right">
            <span class="through-question-head-right-now">{{
              answerIndex + 1
            }}</span>
            <span>/</span>
            <span>{{ examQuestionList.length }}</span>
          </div>
        </div>
        <!-- 描述 -->
        <div class="through-question-describe">
          {{
            examQuestionList[answerIndex].questionContent ||
              examQuestionList[answerIndex].content
          }}
        </div>
        <!-- 答题列表 -->
        <!-- 单选题、多选题、判断题 的选项区域 -->
        <div
          v-if="
            examQuestionList[answerIndex].type === questionType.TrueOrFalse ||
              examQuestionList[answerIndex].type ===
                questionType.singleChoice ||
              examQuestionList[answerIndex].type === questionType.multipleChoice
          "
          class="through-question-options"
        >
          <div
            v-for="(item, index) in examQuestionList[answerIndex].answers"
            :key="index"
            :class="{
              'through-question-options-item': true,
              'through-question-options-item-checked': answerValue.includes(
                item
              ),
              'through-question-options-false':
                answerValue.includes(item) && answerStatus === 2
            }"
            @click="handleExamQuestionOptionsItemFun(item)"
          >
            {{ formatQuestionIndex(index) }}. {{ item }}
          </div>
        </div>
        <!-- 填空题的答题区域 -->
        <div
          v-if="examQuestionList[answerIndex].type === questionType.gapFilling"
          class="through-question-gapFilling"
          :class="{ 'through-question-gapFilling-false': answerStatus === 2 }"
        >
          <textarea
            v-for="(item, index) in examQuestionList[answerIndex]
              .questionInputNum"
            :key="index"
            :ref="'questionInputRef' + index"
            v-model="inputValue[index]"
            :disabled="[1, 2].includes(answerStatus)"
            maxlength="200"
            rows="1"
            @change="handleExamQuestionOptionsItemFun(inputValue, index)"
          />
        </div>
        <div
          v-if="answerRecruitId === 'daily-questions'"
          class="through-question-button-box"
        >
          <div class="through-question-single-button-box"></div>
          <div class="through-question-single-button-box">
            <van-button
              class="through-question-button"
              type="primary"
              color="#0088e9"
              :disabled="answerValue.length === 0"
              @click="handleSureFun"
              >确定</van-button
            >
          </div>
          <div class="through-question-single-button-box">
            <van-button
              v-show="examQuestionList[answerIndex].userAnswer.length"
              class="through-question-button"
              type="primary"
              color="#0088e9"
              @click="handleNextFun"
              >{{
                this.examQuestionList.length - 1 > this.answerIndex
                  ? "下一题"
                  : "完成"
              }}</van-button
            >
          </div>
        </div>
        <div v-else class="through-question-button-box">
          <div class="through-question-single-button-box">
            <van-button
              v-show="answerStatus === 0"
              class="through-question-button"
              type="primary"
              color="#0088e9"
              :disabled="answerValue.length === 0"
              @click="handleSureFun"
              >确定</van-button
            >
          </div>
          <div class="through-question-single-button-box">
            <van-button
              v-show="answerStatus === 2"
              class="through-question-button"
              type="primary"
              color="#0088e9"
              @click="handleNextFun"
              >{{
                this.examQuestionList.length - 1 > this.answerIndex
                  ? "下一题"
                  : "完成"
              }}</van-button
            >
          </div>
        </div>
      </div>
      <div v-else class="through-question-card">
        <div v-if="isInited" class="through-question-card-nodata">暂无数据</div>
        <div
          v-else
          class="through-question-card-nodata through-question-card-loading"
        >
          加载中...
        </div>
      </div>
    </div>
    <!-- 题目卡片 -->
    <div
      v-if="examQuestionList.length > 0"
      v-show="answerStatus === 2"
      class="through-question-div"
    >
      <div class="through-question-card">
        <div class="through-question-result">
          正确答案：{{
            formatQuestionFinalAnswerIndex(
              examQuestionList[answerIndex].finalAnswer
            )
          }}
        </div>
        <div class="through-question-analysis">
          答案解析：{{ this.examQuestionList[this.answerIndex].answerAnalysis }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { Dialog } from "vant";
import { mapState } from "vuex";
export default {
  name: "through-question-doing",
  components: {},
  data() {
    return {
      questionType: {
        singleChoice: "DanXuan", // 单选题
        multipleChoice: "DuoXuan", // 多选题
        gapFilling: "TianKong", // 填空题
        TrueOrFalse: "PanDuan" // 判断题
      }, // 试题类型
      examQuestionList: [], // 试题列表
      answerIndex: null, // 当前试题的下标索引
      answerValue: [], // 当前试题的所答
      inputValue: [], // 填空题时输入框的值
      isInited: false, // 是否已初始化完毕
      answerTime: {
        startTime: 0,
        endTime: 0
      }, // 答题的开始、结束时间
      answerStatus: 0 // 当前答题状态： 0未作答 1已做答且正确 2已做答但错误  3已完成当前的所有题目作答
    };
  },
  created() {
    this.initDataFun(); // 初始化数据信息
  },
  watch: {},
  computed: {
    ...mapState({
      answerRecruitId: state => state.answer.answerRecruitId,
      userInfo: state => state.user.userInfo,
      chooseEngneeringWork: state => state.user.chooseEngneeringWork,
      answerThroughNumber: state => state.answer.answerThroughNumber
    })
  },
  methods: {
    // 初始化数据信息
    initDataFun() {
      this.examStartFun(); // 方法：开始考试
    },
    // 方法：开始考试
    examStartFun() {
      if (!this.answerRecruitId) {
        Dialog.alert({
          message: "试题信息有误，请重新进入当前页面",
          theme: "round-button"
        }).then(() => {
          this.$router.back();
        });
        return;
      }
      this.$store.commit("toggleLoading", true);
      let params = {
        type: this.chooseEngneeringWork.value
      };
      this.$_http
        .post(
          this.$pathParams(this.$_API.POST_JTXT_GET_EXAMS_START, {
            examId: this.answerRecruitId
          }),
          this.userInfo,
          { params }
        )
        .then(res => {
          if (res.data) {
            let httpResultData = [];
            res.data.forEach((item, index) => {
              this.getExamQuestionsListFun(
                item,
                httpResultData,
                index === res.data.length - 1
              );
            });
          }
        })
        .catch(() => {
          this.$store.commit("toggleLoading", false);
        });
    },
    // 查询：试题信息
    async getExamQuestionsListFun(questionId, httpResultData, isLast) {
      this.$_http
        .get(
          this.$pathParams(this.$_API.GET_JTXT_GET_EXAMS_ONE_QUESTIONS_LIST, {
            questionId: questionId
          })
        )
        .then(res => {
          let resData = { ...res.data };
          httpResultData.push(this.setPersonDataFun(resData));
          if (isLast) {
            // 临时解决多个异步请求进行的问题
            this.examQuestionList = httpResultData;
            this.handleExamQuestionItemFun(this.examQuestionList[0], 0); // 设置第一题开始
            let curTime = new Date();
            this.answerTime.startTime = curTime; // 赋值开始时间
            this.isInited = true;
            this.$store.commit("toggleLoading", false);
          }
        })
        .catch(() => {
          this.$store.commit("toggleLoading", false);
        });
    },
    // 方法：过滤试题的类型，添加用户作答的字段
    setPersonDataFun(httpResultDataItme) {
      let results = this.formatQuestionType(
        httpResultDataItme.type,
        httpResultDataItme.content
      );
      httpResultDataItme.typeTxt = results.typeTxt;
      httpResultDataItme.questionContent = results.questionContent;
      httpResultDataItme.questionInputNum = results.questionInputNum;
      httpResultDataItme.userAnswer = [];
      return httpResultDataItme;
    },
    // 方法：过滤试题的类型、填空题的题目、填空题的回答框个数
    formatQuestionType(type, content) {
      let typeTxt = "";
      let questionContent = "";
      let questionInputNum = 0;
      switch (type) {
        case this.questionType.singleChoice:
          typeTxt = "单选题";
          break;
        case this.questionType.multipleChoice:
          typeTxt = "多选题";
          break;
        case this.questionType.gapFilling:
          typeTxt = "填空题";
          questionInputNum = this.getPlaceholderCount(content);
          questionContent = content.replace("$PH$", "()");
          break;
        case this.questionType.TrueOrFalse:
          typeTxt = "判断题";
          break;
        default:
          break;
      }
      return {
        typeTxt: typeTxt,
        questionContent: questionContent,
        questionInputNum: questionInputNum
      };
    },
    // 方法：统计字符串中包含的特定字符个数
    getPlaceholderCount(strSource) {
      // 统计字符串中包含{}或{xxXX}的个数
      let countNum = 0;
      strSource.replace("$PH$", function(m, i) {
        // m为找到的{xx}元素、i为索引
        countNum++;
      });
      return countNum;
    },
    // 方法：过滤正确答案的选项的编号
    formatQuestionFinalAnswerIndex(finalAnswer) {
      let txt = "";
      switch (this.examQuestionList[this.answerIndex].type) {
        case this.questionType.singleChoice:
        case this.questionType.multipleChoice:
        case this.questionType.TrueOrFalse:
          finalAnswer.forEach((item, index) => {
            txt = txt + item;
          });
          break;
        case this.questionType.gapFilling:
          finalAnswer.forEach((item, index) => {
            txt = txt + (index > 0 ? "、" : "") + item;
          });
          break;
        default:
          break;
      }
      return txt;
    },
    // 操作：点击了某个题序
    handleExamQuestionItemFun(item, index) {
      if (this.answerIndex === index || !this.examQuestionList.length) {
        return;
      }
      this.answerStatus = 0;
      this.answerIndex = index;
      switch (item.type) {
        case this.questionType.singleChoice:
        case this.questionType.multipleChoice:
        case this.questionType.TrueOrFalse:
          this.answerValue = [...new Set(item.userAnswer)];
          break;
        case this.questionType.gapFilling:
          this.answerValue = [...new Set(item.userAnswer)];
          this.inputValue = this.answerValue || [];
          break;
        default:
          break;
      }
    },
    // 操作：作答了某个选项
    handleExamQuestionOptionsItemFun(value, index) {
      // 答错了的不允许修改
      if (this.answerStatus === 2) {
        return;
      }
      let answerQuestionType = this.examQuestionList[this.answerIndex].type;
      switch (answerQuestionType) {
        // 判断题、单选题
        case this.questionType.TrueOrFalse:
        case this.questionType.singleChoice:
          this.answerValue = [value];
          break;
        // 多选题
        case this.questionType.multipleChoice:
          // 遍历所答的数组，看是否有重复的
          let repetitiveIndex = null;
          for (let i = 0; i < this.answerValue.length; i++) {
            let it = this.answerValue[i];
            if (value === it) {
              repetitiveIndex = i;
              break;
            }
          }
          // 如果有重复的就移除
          if (repetitiveIndex !== null) {
            this.answerValue.splice(repetitiveIndex, 1);
          } else {
            this.answerValue.push(value);
          }
          break;
        // 填空题
        case this.questionType.gapFilling:
          this.$refs["questionInputRef" + index][0].blur(); // 清除input的焦点
          this.answerValue = value;
          break;
        default:
          break;
      }
    },
    // 操作：确定
    handleSureFun() {
      if (!this.examQuestionList.length) {
        return;
      }
      this.examQuestionList[this.answerIndex].userAnswer = this.answerValue;
      this.answerStatus = this.getAnswerItemResultFun(
        this.examQuestionList[this.answerIndex]
      )
        ? 1
        : 2;
      if (this.answerStatus === 1) {
        this.handleNextFun();
      } else if (this.answerStatus === 2) {
        Dialog.alert({
          message: "本题答错，闯关失败",
          theme: "round-button"
        }).then(() => {
          this.$router.back();
        });
      }
    },
    // 方法：判断当前题目是否正确
    getAnswerItemResultFun(item) {
      // let isSure = false;
      // let sureNum = 0;
      // item.finalAnswer.forEach(it => {
      //   item.userAnswer.forEach(answerItem => {
      //     if (it === answerItem) {
      //       sureNum++;
      //     }
      //   });
      // });
      // if (sureNum === item.finalAnswer.length) {
      //   isSure = true;
      // }
      // return isSure;
      let isSure = false;
      let lastAnswer = [""];
      lastAnswer[0] = this.getUserAnswerSortFun(item);
      if (lastAnswer[0] === item.finalAnswer[0]) {
        isSure = true;
      }
      return isSure;
    },
    // 获取用户所选选项的升序编号答案
    getUserAnswerSortFun(item) {
      let newUnserAnswer = [];
      item.answers.forEach((itemOne, indexOne) => {
        item.userAnswer.forEach(itemTwo => {
          if (itemOne === itemTwo) {
            newUnserAnswer.push(this.formatQuestionIndex(indexOne));
          }
        });
      });
      newUnserAnswer.sort();
      return newUnserAnswer.join("");
    },
    // 操作：下一题
    handleNextFun() {
      let nextIndex = this.answerIndex + 1;
      if (nextIndex >= this.examQuestionList.length) {
        this.examsEndFun(); // 结束考试
        return;
      }
      this.handleExamQuestionItemFun(
        this.examQuestionList[nextIndex],
        nextIndex
      );
    },
    // 方法：结束考试
    examsEndFun() {
      let curTime = new Date();
      this.answerTime.endTime = curTime; // 赋值开始时间
      this.$store.commit("toggleLoading", true);
      let grades = this.getUserExamAllPointsFun(); // 方法：计算成绩
      let answers = this.getUserExamAllAnswersFun(); // 方法：获取当前用户所有题目作答的答案
      let params = {
        userId: this.userInfo.userName,
        examId: this.answerRecruitId,
        points: grades, // 成绩：积分
        startTime: "", // this.answerTime.startTime,
        endTime: "", // this.answerTime.endTime
        userAnswers: answers
      };
      this.$_http
        .post(
          this.$pathParams(this.$_API.POST_JTXT_GET_EXAMS_END, {
            examId: this.answerRecruitId
          }),
          params
        )
        .then(res => {
          this.$store.commit("toggleLoading", false);
          this.$router.replace({
            name: "throughQuestionEnd",
            params: {
              allQuestionsNum: this.examQuestionList.length,
              grades: grades
            }
          });
        })
        .catch(() => {
          this.$store.commit("toggleLoading", false);
          Dialog.close();
          Dialog({ message: "结束考试异常，请联系系统管理员" });
          this.$router.back();
        });
    },
    // 方法：计算成绩
    getUserExamAllPointsFun() {
      let grades = 0;
      this.examQuestionList.forEach(item => {
        let isSure = this.getAnswerItemResultFun(item);
        if (isSure) {
          grades++; // 默认每题一分
        }
      });
      return grades;
    },
    // 方法：获取题目的答案
    getUserExamAllAnswersFun() {
      let answers = [];
      this.examQuestionList.forEach((item, index) => {
        // answers[index] = item.userAnswer.join("||");
        answers[index] = this.getUserAnswerSortFun(item);
      });
      return answers;
    },
    // 操作：返回
    handleBackFun() {
      this.$router.back();
    }
  }
};
</script>

<style lang="scss" scoped>
@import "~@/styles/mixin";
.page-through-question-box {
  width: 100%;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  font-size: 0.6rem;
  .through-question-div {
    padding: 0.5rem 0.5rem;
    .through-question-card {
      padding: 0.5rem 0.5rem;
      background-color: #fff;
      border-radius: 4px;
      box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
      .through-question-head {
        display: flex;
        justify-content: space-between;
        align-items: center;
        flex-wrap: nowrap;
        border-bottom: 1px solid #0088e9;
        padding-bottom: 0.25rem;
        height: 1.25rem;
        font-size: 0.65rem;
        .through-question-head-left {
          display: flex;
          align-items: center;
          flex-wrap: nowrap;
          .through-question-head-left-icon {
            width: 0.25rem;
            height: 1rem;
            background-color: #0088e9;
          }
          .through-question-head-left-txt {
            margin-left: 0.25rem;
            margin-right: 0.25rem;
            font-weight: bold;
          }
        }
        .through-question-head-right {
          span {
            color: #666;
          }
          .through-question-head-right-now {
            font-weight: bold;
            color: #000;
          }
        }
      }
      .through-question-describe {
        padding: 0.5rem 0;
        font-size: 0.65rem;
      }
      .through-question-options {
        .through-question-options-item {
          width: 100%;
          padding: 0.5rem 0.25rem;
          background-color: #f3f3f3;
          margin-bottom: 0.5rem;
          border: 1px solid transparent;
        }
        .through-question-options-item-checked {
          border-color: #0088e9;
          color: #0088e9;
        }
        .through-question-options-false {
          border-color: red !important;
          background-color: #fedada !important;
        }
      }
      .through-question-gapFilling {
        padding-top: 0.5rem;
        textarea {
          width: 100%;
          padding: 0.25rem 0.25rem;
          background-color: #f3f3f3;
          margin-bottom: 0.5rem;
          border: 1px solid transparent;
          &:active,
          &:focus {
            border-color: #0088e9;
          }
        }
      }
      .through-question-gapFilling-false {
        textarea {
          border-color: red !important;
          background-color: #fedada !important;
        }
      }
      .through-question-button-box {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        .through-question-single-button-box {
          width: 30%;
          padding: 0.5rem 0.5rem;
          display: flex;
          flex-direction: row;
          justify-content: center;
          align-items: center;
          .through-question-button {
            width: 6rem;
            height: auto;
            padding: 0.5rem 0.5rem;
            font-size: 0.65rem;
            margin-top: 0.75rem;
          }
        }
      }
      .through-question-result {
        border-bottom: 1px solid #0088e9;
        padding-bottom: 0.25rem;
        font-size: 0.6rem;
      }
      .through-question-analysis {
        padding-top: 0.25rem;
      }
      .through-question-card-loading,
      .through-question-card-nodata {
        width: 100%;
        height: 5rem;
        color: #333;
        font-size: 0.7rem;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .through-question-card-loading {
        color: #0088e9;
      }
      .through-question-number {
        padding: 0.25rem 0;
        font-size: 0.7rem;
        text-align: center;
      }
    }
  }
}
</style>
