<template>
  <el-dialog
    custom-class="question-edit-dialog"
    :visible.sync="modalIsShow"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    append-to-body
    fullscreen
    destroy-on-close
    :show-close="false"
    @open="visibleChange"
  >
    <div slot="title" class="box-justify">
      <div>
        <h2>{{ isEdit ? "编辑试题" : "创建试题" }}</h2>
        <span>课程代码：{{ questionModel.courseCode }}</span>
        <span>课程名称：{{ questionModel.courseName }}</span>
      </div>
      <div>
        <el-button
          size="small"
          type="primary"
          :loading="loading"
          @click="confirm"
          >确定</el-button
        >
        <el-button size="small" @click="cancel">取消</el-button>
      </div>
    </div>
    <div class="part-box question-edit">
      <el-form label-width="100px">
        <el-form-item v-if="isEdit" label="题型">
          <el-button type="primary" size="small">
            {{ question.sourceDetailName }}
          </el-button>
        </el-form-item>
        <el-form-item v-else label="题型">
          <el-button
            v-for="item in sourceDetailList"
            :key="item.id"
            :type="
              questionModel.sourceDetailId === item.id ? 'primary' : 'default'
            "
            size="small"
            :disabled="loading"
            @click="switchType(item)"
            >{{ item.name }}</el-button
          >
          <el-button
            v-if="sourceDetailAllList.length > limitShowCount"
            size="small"
            :icon="showMore ? 'el-icon-arrow-up' : 'el-icon-more'"
            @click="switchMoreSourceDetail"
          ></el-button>
          <el-button
            size="small"
            icon="el-icon-plus"
            @click="toAddSourceDetail"
          ></el-button>
          <p class="tips-info">
            说明：如果是综合类试题（套题）可以选择题型为阅卷理解进行录入操作。
          </p>
        </el-form-item>
      </el-form>
      <!-- question-body -->
      <component
        :is="structTypeComp"
        :key="questionKey"
        ref="QuestionEditDetail"
        :question="questionModel"
      ></component>
    </div>
    <div slot="footer"></div>

    <!-- ModifySourceDetail -->
    <modify-source-detail
      ref="ModifySourceDetail"
      :instance="curSourceInfo"
      @modified="sourceDetailAdded"
    ></modify-source-detail>
  </el-dialog>
</template>

<script>
import { QUESTION_TYPES } from "@/constants/constants";
import { STRUCT_TYPE_COMP_DICT } from "./model/questionModel";
import BooleanQuestion from "./edit/BooleanQuestion.vue";
import FillBlankQuestion from "./edit/FillBlankQuestion.vue";
import SelectQuestion from "./edit/SelectQuestion.vue";
import TextAnswerQuestion from "./edit/TextAnswerQuestion.vue";
import NestedQuestion from "./edit/NestedQuestion.vue";
import BankedClozeQuestion from "./edit/BankedClozeQuestion.vue";
import { randomCode } from "@/plugins/utils";
import {
  updateQuestionApi,
  sourceDetailPageListApi,
  questionDetailApi,
} from "../api";
import ModifySourceDetail from "./ModifySourceDetail.vue";

const initQuestionModel = {
  courseId: null,
  courseCode: "",
  courseName: "",
  sourceDetailId: null,
  questionType: "",
};

export default {
  name: "QuestionEditDialog",
  components: {
    FillBlankQuestion,
    SelectQuestion,
    TextAnswerQuestion,
    BooleanQuestion,
    NestedQuestion,
    BankedClozeQuestion,
    ModifySourceDetail,
  },
  props: {
    question: {
      type: Object,
      default() {
        return { id: "" };
      },
    },
    editMode: {
      type: String,
      default: "question",
    },
  },
  data() {
    return {
      modalIsShow: false,
      sourceDetailAllList: [],
      sourceDetailList: [],
      curSourceDetail: {},
      limitShowCount: 10,
      showMore: false,
      questionModel: {
        questionType: "SINGLE_ANSWER_QUESTION",
      },
      detailName: "",
      questionKey: "",
      loading: false,
      hasModifyQuestion: false,
      curSourceInfo: {},
    };
  },
  computed: {
    isEdit() {
      return !!this.question.id;
    },
    title() {
      return this.isEdit ? "编辑试题" : "创建试题";
    },
    structTypeComp() {
      return STRUCT_TYPE_COMP_DICT[this.questionModel.questionType];
    },
  },
  methods: {
    async visibleChange() {
      if (this.question.id) {
        const res = await questionDetailApi(this.question.id);

        const courseInfo = {
          courseId: res.data.course.id,
          courseCode: res.data.course.code,
          courseName: res.data.course.name,
        };
        let questionModel = {
          ...res.data,
          ...courseInfo,
          score: this.question.score,
          editMode: this.editMode,
        };
        if (questionModel.subQuestions && questionModel.subQuestions.length) {
          questionModel.subQuestions = questionModel.subQuestions.map(
            (q, qindex) => {
              let nq = { ...q, ...courseInfo, editMode: this.editMode };
              if (this.editMode === "paper")
                nq.score = this.question.subScoreList[qindex];
              return nq;
            }
          );
        }
        this.questionModel = questionModel;
      } else {
        await this.getSourceDetailList();

        this.questionModel = Object.assign(
          {},
          initQuestionModel,
          this.question
        );
      }

      this.initData();
    },
    initData() {
      this.loading = false;
      this.hasModifyQuestion = false;
      if (this.isEdit) {
        this.sourceDetailList = this.sourceDetailAllList;

        this.curSourceDetail = {
          id: this.questionModel.sourceDetailId,
          questionType: this.questionModel.questionType,
        };
      } else {
        if (this.sourceDetailAllList.length > this.limitShowCount) {
          this.sourceDetailList = this.sourceDetailAllList.slice(
            0,
            this.limitShowCount
          );
        } else {
          this.sourceDetailList = this.sourceDetailAllList;
        }
        if (!this.questionModel.sourceDetailId && !this.curSourceDetail.id) {
          this.curSourceDetail = this.sourceDetailList[0];
        }
        this.questionModel.questionType = this.curSourceDetail.questionType;
        this.questionModel.sourceDetailId = this.curSourceDetail.id;
      }
      this.questionKey = randomCode();
    },
    close() {
      this.modalIsShow = false;
    },
    open() {
      this.modalIsShow = true;
    },
    cancel() {
      if (this.hasModifyQuestion) this.$emit("modified");
      this.close();
    },
    async getSourceDetailList() {
      const res = await sourceDetailPageListApi({
        pageNumber: 1,
        pageSize: 100,
        courseId: this.question.courseId,
        rootOrgId: this.$store.state.user.rootOrgId,
      });
      this.sourceDetailAllList = res.data.content || [];
      let questionTypeSerial = {};
      QUESTION_TYPES.forEach((item, index) => {
        questionTypeSerial[item.code] = index;
      });
      this.sourceDetailAllList.sort(
        (a, b) =>
          questionTypeSerial[a.questionType] -
          questionTypeSerial[b.questionType]
      );
    },
    switchMoreSourceDetail() {
      if (this.showMore) {
        this.sourceDetailList = this.sourceDetailAllList.slice(
          0,
          this.limitShowCount
        );
      } else {
        this.sourceDetailList = this.sourceDetailAllList;
      }
      this.showMore = !this.showMore;
    },
    toAddSourceDetail() {
      this.curSourceInfo = {
        courseId: this.question.courseId,
        rootOrgId: this.$store.state.user.rootOrgId,
      };
      this.$refs.ModifySourceDetail.open();
    },
    async sourceDetailAdded(sourceDetail) {
      await this.getSourceDetailList();
      this.showMore = !this.showMore;
      this.switchMoreSourceDetail();
      this.curSourceDetail = sourceDetail;
      this.initData();
    },
    async switchType(item) {
      if (this.isEdit) return;
      if (this.questionModel.sourceDetailId === item.id) return;
      if (this.questionModel.questionType === item.questionType) {
        this.curSourceDetail = item;
        this.questionModel.sourceDetailId = item.id;
        return;
      }

      const confirm = await this.$confirm("确认更改题型吗?", "提示", {
        type: "warning",
      }).catch(() => {});
      if (confirm !== "confirm") return;

      this.curSourceDetail = item;
      this.questionKey = randomCode();
      this.questionModel = Object.assign({}, this.questionModel, {
        questionType: item.questionType,
        sourceDetailId: item.id,
      });
    },
    async confirm() {
      const valid = await this.$refs.QuestionEditDetail.validate().catch(
        () => {}
      );
      if (!valid) return;

      if (this.loading) return;
      this.loading = true;

      let questionModel = this.$refs.QuestionEditDetail.getData();
      questionModel.sourceDetailId = this.questionModel.sourceDetailId;
      if (this.question.editMode === "paper") {
        this.$emit("modified", questionModel);
        this.loading = false;
        this.close();
        return;
      }
      const res = await updateQuestionApi(questionModel).catch(() => {});
      this.loading = false;
      if (!res) return;

      this.$message.success(this.title + "成功");

      this.hasModifyQuestion = true;

      if (this.isEdit) {
        this.$emit(
          "modified",
          Object.assign({}, this.questionModel, questionModel)
        );
        this.close();
        return;
      }

      const confirm = await this.$confirm("是否继续出题吗?", "提示", {
        type: "warning",
      }).catch(() => {});
      if (confirm !== "confirm") {
        this.$emit("modified");
        this.close();
      } else {
        this.initData();
      }
    },
  },
};
</script>
