<template>
  <div class="nested-question">
    <el-form
      ref="modalFormComp"
      :model="modalForm"
      :rules="rules"
      label-width="100px"
    >
      <el-form-item prop="quesBody" label="大题题干">
        <v-editor
          v-model="modalForm.quesBody"
          :enable-answer-point="IS_CLOZE"
          @answer-point-changed="answerPointsChange"
          @change="quesBodyChange"
        ></v-editor> </el-form-item
    ></el-form>

    <div class="tips-info">
      <p>小题数：{{ modalForm.subQuestions.length }}</p>
    </div>

    <el-collapse v-model="activeNames">
      <el-collapse-item
        v-for="(subq, index) in modalForm.subQuestions"
        :key="subq.questionKey"
        :name="index"
      >
        <div slot="title" class="subq-header">
          <h3>
            第{{ index + 1 }}小题（{{ subq.questionType | questionType }}）
          </h3>
          <div>
            <el-button
              v-if="!deleleDisabled"
              class="btn-danger"
              size="mini"
              type="text"
              icon="el-icon-delete"
              title="删除"
              @click.stop="removeSubQuestion(index)"
            ></el-button>
          </div>
        </div>

        <component
          :is="getStructTypeComp(subq.questionType)"
          ref="QuestionEditDetail"
          :question="subq"
        ></component>
      </el-collapse-item>
    </el-collapse>

    <el-popover
      v-if="!IS_CLOZE && !IS_LISTENING_QUESTION"
      popper-class="nested-subq-popover"
      trigger="hover"
    >
      <div class="nested-subq-list">
        <div
          v-for="item in BASE_QUESTION_TYPES"
          :key="item.code"
          class="nested-subq-item"
          @click="addSubQuestion(item.code)"
        >
          {{ item.name }}
        </div>
      </div>

      <el-button
        slot="reference"
        type="primary"
        size="small"
        icon="el-icon-circle-plus-outline"
        >新增小题</el-button
      >
    </el-popover>
    <!-- 听力题只能添加单选题 -->
    <el-button
      v-if="IS_LISTENING_QUESTION"
      type="primary"
      size="small"
      icon="el-icon-circle-plus-outline"
      @click="addSubQuestion('SINGLE_ANSWER_QUESTION')"
      >新增小题</el-button
    >
  </div>
</template>

<script>
import { isAnEmptyRichText } from "@/utils/utils";
import { randomCode } from "@/plugins/utils";
import {
  getInitQuestionModel,
  STRUCT_TYPE_COMP_DICT,
} from "../model/questionModel";
import BooleanQuestion from "./BooleanQuestion.vue";
import FillBlankQuestion from "./FillBlankQuestion.vue";
import SelectQuestion from "./SelectQuestion.vue";
import TextAnswerQuestion from "./TextAnswerQuestion.vue";
import { BASE_QUESTION_TYPES } from "@/constants/constants";

export default {
  name: "NestedQuestion",
  components: {
    FillBlankQuestion,
    SelectQuestion,
    TextAnswerQuestion,
    BooleanQuestion,
  },
  props: {
    question: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    return {
      modalForm: {},
      BASE_QUESTION_TYPES,
      activeNames: [],
      rules: {
        quesBody: [
          {
            validator: (rule, value, callback) => {
              if (!this.IS_CLOZE) return callback();

              if (!value || isAnEmptyRichText(value)) {
                return callback(new Error(`请输入题干`));
              }
              callback();
            },
            trigger: "change",
          },
        ],
      },
    };
  },
  computed: {
    deleleDisabled() {
      return this.IS_CLOZE;
    },
    IS_CLOZE() {
      return this.modalForm.questionType === "CLOZE";
    },
    IS_LISTENING_QUESTION() {
      return this.modalForm.questionType === "LISTENING_QUESTION";
    },
  },
  created() {
    this.initData();
  },
  methods: {
    initData() {
      this.modalForm = this.$objAssign(
        getInitQuestionModel(this.question.questionType),
        this.question
      );
    },
    getStructTypeComp(questionType) {
      return STRUCT_TYPE_COMP_DICT[questionType];
    },
    addSubQuestion(questionType, index = null) {
      let newQuestion = getInitQuestionModel(questionType);
      newQuestion.questionKey = randomCode();
      newQuestion.courseId = this.question.courseId;
      const nindex =
        index === null ? this.modalForm.subQuestions.length : index + 1;
      this.modalForm.subQuestions.splice(nindex, 0, newQuestion);
      if (!this.activeNames.includes(newQuestion.questionKey) && !this.IS_CLOZE)
        this.activeNames.push(newQuestion.questionKey);
    },
    async removeSubQuestion(index) {
      if (this.deleleDisabled) return;

      const res = await this.$confirm("确定要删除该小题吗?", "提示", {
        type: "warning",
      }).catch(() => {});
      if (res !== "confirm") return;

      const delQuestionKey = this.modalForm.subQuestions[index].questionKey;
      this.activeNames = this.activeNames.filter((k) => k !== delQuestionKey);
      this.modalForm.subQuestions.splice(index, 1);
    },
    answerPointsChange(answerPointsChanged) {
      let subQuestions = [];
      answerPointsChanged.forEach((item) => {
        const order = Number(item);
        if (order === 0) {
          let newQuestion = getInitQuestionModel("SINGLE_ANSWER_QUESTION");
          newQuestion.questionKey = randomCode();
          newQuestion.courseId = this.question.courseId;
          subQuestions.push(newQuestion);
        } else {
          subQuestions.push(this.modalForm.subQuestions[order - 1]);
        }
      });
      this.modalForm.subQuestions = subQuestions;
    },
    quesBodyChange() {
      this.$refs.modalFormComp.validateField(`quesBody`, () => {});
    },
    async validate() {
      let errorQuestionIndexs = [];
      for (let i = 0; i < this.$refs.QuestionEditDetail.length; i++) {
        const compInst = this.$refs.QuestionEditDetail[i];
        const res = await compInst.validate().catch(() => {});
        if (!res) {
          errorQuestionIndexs.push(i + 1);
        }
      }
      if (errorQuestionIndexs.length) {
        this.$message.error(
          `请完成第${errorQuestionIndexs.join()}小题的编辑！`
        );
        return Promise.reject();
      }

      return true;
    },
    getData() {
      this.modalForm.subQuestions = this.$refs.QuestionEditDetail.map(
        (compInst) => compInst.getData()
      );
      return this.modalForm;
    },
  },
};
</script>
