<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
    @open="visibleChange"
  >
    <div slot="title" class="box-justify">
      <div>
        <h2>{{ isEdit ? "编辑试题" : "创建试题" }}</h2>
        <span>课程代码：{{ question.courseCode }}</span>
        <span>课程名称：{{ question.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 } 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 {};
      },
    },
  },
  data() {
    return {
      modalIsShow: false,
      sourceDetailAllList: [],
      sourceDetailList: [],
      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) await this.getSourceDetailList();
      this.initData();
    },
    initData() {
      this.loading = false;
      this.hasModifyQuestion = false;

      if (this.isEdit) {
        this.sourceDetailList = this.sourceDetailAllList;
      } else {
        if (this.sourceDetailAllList.length > this.limitShowCount) {
          this.sourceDetailList = this.sourceDetailAllList.slice(
            0,
            this.limitShowCount
          );
        } else {
          this.sourceDetailList = this.sourceDetailAllList;
        }
      }

      this.questionKey = randomCode();
      this.questionModel = Object.assign({}, initQuestionModel, this.question);
      if (!this.question.questionType) {
        const curSourceDetail = this.sourceDetailList[0];
        this.questionModel.questionType = curSourceDetail.questionType;
        this.questionModel.sourceDetailId = curSourceDetail.id;
      }
    },
    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() {
      await this.getSourceDetailList();
      if (this.isEdit) {
        this.sourceDetailList = this.sourceDetailAllList;
        return;
      }

      this.showMore = !this.showMore;
      this.switchMoreSourceDetail();
    },
    async switchType(item) {
      if (this.isEdit) return;
      if (this.questionModel.sourceDetailId === item.id) return;
      if (this.questionModel.questionType === item.questionType) {
        this.questionModel.sourceDetailId = item.id;
        return;
      }

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

      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;

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

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

      this.hasModifyQuestion = true;

      if (this.isEdit) {
        this.$emit("modified");
        this.close();
        return;
      }

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