<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
    @open="visibleChange"
  >
    <div slot="title" class="box-justify">
      <div>
        <h2>编辑试题</h2>
        <span
          >课程：{{ formModel.courseName }}（{{ formModel.courseCode }}）</span
        >
      </div>
      <div>
        <el-button
          size="small"
          type="primary"
          :disabled="hasTaskRunning || buildLoading"
          :loading="confirmLoading"
          @click="confirm"
          >确定</el-button
        >
        <el-button size="small" @click="cancel">取消</el-button>
      </div>
    </div>
    <div class="part-box">
      <el-form label-width="100px">
        <el-form-item class="inline-top" label="题型：">
          {{ formModel.questionType | questionTypeFilter }}
        </el-form-item>
        <el-form-item
          v-if="IS_SELECTION_QUESTION"
          class="inline-top margin-left-10"
          label="选项个数："
        >
          {{ formModel.optionCount }}
        </el-form-item>
        <el-form-item
          v-if="IS_FILL_QUESTION"
          class="inline-top margin-left-10"
          label="填空个数："
        >
          {{ formModel.blankCount }}
        </el-form-item>
        <el-form-item label="知识点：">
          <el-tag
            v-for="content in quesProperties"
            :key="content.key"
            effect="dark"
            type="primary"
            style="margin-right: 5px; margin-bottom: 5px"
          >
            {{ content.courseProperty && content.courseProperty.name }}
            <span style="margin: 0 3px">/</span>
            {{ content.firstProperty && content.firstProperty.name }}
            <span
              v-if="content.secondProperty && content.secondProperty.name"
              style="margin: 0 3px"
              >/</span
            >
            {{ content.secondProperty && content.secondProperty.name }}
          </el-tag>
          <el-input
            v-model="formModel.knowledgeNotes"
            placeholder="请录入知识点补充说明"
            type="textarea"
            clearable
          ></el-input>
        </el-form-item>

        <el-form-item style="margin: 0">
          <el-button
            type="danger"
            :loading="hasTaskRunning || buildLoading"
            :disabled="confirmLoading"
            @click="toProduct"
            >重新生成</el-button
          >
        </el-form-item>
      </el-form>
    </div>
    <!-- question-body -->
    <div class="part-box question-edit">
      <component
        :is="structTypeComp"
        :key="questionKey"
        ref="QuestionEditDetail"
        :question="questionModel"
        :can-edit-question-info="false"
      ></component>
    </div>
  </el-dialog>
</template>

<script>
import { STRUCT_TYPE_COMP_DICT } from "./edit/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 { randomCode } from "@/plugins/utils";
import {
  buildGptQuestionApi,
  gptRebuildQuestionListApi,
  updateGptQuestionApi,
  gptTaskDetailApi,
} from "../api";
import timeMixin from "@/mixins/timeMixin";

export default {
  name: "GptQuestionEditDialog",
  components: {
    FillBlankQuestion,
    SelectQuestion,
    TextAnswerQuestion,
    BooleanQuestion,
  },
  mixins: [timeMixin],
  props: {
    question: {
      type: Object,
      default() {
        return { id: "" };
      },
    },
  },
  data() {
    return {
      modalIsShow: false,
      curTaskId: null,
      hasTaskRunning: false,
      questionModel: {
        questionType: "SINGLE_ANSWER_QUESTION",
      },
      formModel: {},
      quesProperties: [],
      questionKey: "",
      editMode: "question",
      buildLoading: false,
      confirmLoading: false,
    };
  },
  computed: {
    structTypeComp() {
      return STRUCT_TYPE_COMP_DICT[this.questionModel.questionType];
    },
    IS_SELECTION_QUESTION() {
      return ["SINGLE_ANSWER_QUESTION", "MULTIPLE_ANSWER_QUESTION"].includes(
        this.questionModel.questionType
      );
    },
    IS_FILL_QUESTION() {
      return this.questionModel.questionType === "FILL_BLANK_QUESTION";
    },
  },
  beforeDestroy() {
    this.clearSetTs();
  },
  methods: {
    async visibleChange() {
      this.curTaskId = this.question.taskId;
      const res = await gptTaskDetailApi(this.question.taskId).catch(() => {});
      if (!res || !res.data) return;

      const { prompt } = res.data;
      this.formModel = {
        courseId: this.question.courseId,
        courseCode: this.question.courseCode,
        courseName: this.question.courseName,
        questionType: prompt.questionType,
        questionCount: 1,
        optionCount: prompt.optionCount,
        blankCount: prompt.blankCount,
        propertyIdList: this.question.propertyIds,
        knowledgeNotes: prompt.knowledgeNotes,
      };

      let quesProperties = [];
      this.question.propertyInfos.forEach((item) => {
        let nitem = {};
        nitem.key = item.map((elem) => elem.id).join("_");
        nitem.courseProperty = item[0];
        nitem.firstProperty = item[1];
        if (item[2]) nitem.secondProperty = item[2];
        quesProperties.push(nitem);
      });
      this.quesProperties = quesProperties;

      this.initData(this.question);
    },
    initData(question) {
      const courseInfo = {
        courseId: this.formModel.courseId,
        courseCode: this.formModel.courseCode,
        courseName: this.formModel.courseName,
      };
      let questionModel = {
        ...question,
        ...courseInfo,
        editMode: this.editMode,
      };

      if (questionModel.subQuestions && questionModel.subQuestions.length) {
        questionModel.subQuestions = questionModel.subQuestions.map((q) => {
          let nq = { ...q, ...courseInfo, editMode: this.editMode };
          return nq;
        });
      }
      this.questionModel = questionModel;

      this.questionKey = randomCode();
    },
    async cancel() {
      if (this.hasTaskRunning) {
        const confirm = await this.$confirm(
          "当前正在生成试题，确定要退出吗?",
          "提示",
          {
            type: "warning",
          }
        ).catch(() => {});
        if (confirm !== "confirm") return;

        this.clearSetTs();
      }
      this.modalIsShow = false;
    },
    open() {
      this.modalIsShow = true;
    },
    async toProduct() {
      this.buildLoading = true;

      const res = await buildGptQuestionApi({
        ...this.formModel,
        insteadQuestionId: this.question.id,
      }).catch(() => {});
      this.buildLoading = false;
      if (!res) return;

      this.curTaskId = res.data;
      this.hasTaskRunning = true;
      this.addSetTime(() => {
        this.checkTaskStatus();
      }, 3 * 1000);
    },
    async checkTaskStatus() {
      this.clearSetTs();

      if (!this.curTaskId) return;

      const res = await gptTaskDetailApi({
        courseId: this.formModel.courseId,
        taskId: this.curTaskId,
      }).catch(() => {});
      if (!res || !res.data) return;

      if (res.data.status === "FAILED") {
        this.hasTaskRunning = false;
        this.$message.error("重新生成试题失败，请重新尝试！");
        this.getResult();
        return;
      }
      if (res.data.status === "FINISH") {
        this.hasTaskRunning = false;
        this.$message.success("重新生成试题成功！");
        this.getResult();
        return;
      }
      this.hasTaskRunning = res.data.status === "RUNNING";
      this.addSetTime(() => {
        this.checkTaskStatus();
      }, 3 * 1000);
    },
    async getResult() {
      const res = await gptRebuildQuestionListApi(this.curTaskId).catch(
        () => {}
      );
      if (!res) return;
      this.initData(res.data);
    },
    async confirm() {
      const valid = await this.$refs.QuestionEditDetail.validate().catch(
        () => {}
      );
      if (!valid) return;

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

      let questionModel = this.$refs.QuestionEditDetail.getData();
      const res = await updateGptQuestionApi({
        ...questionModel,
        propertyIdList: this.formModel.propertyIdList,
      }).catch(() => {});
      this.confirmLoading = false;
      if (!res) return;

      this.$message.success("保存成功");
      this.$emit("modified");
      this.modalIsShow = false;
    },
  },
};
</script>
