<template>
  <el-dialog
    class="element-prop-edit edit-dialog"
    :visible.sync="openElementEditDialog"
    :title="title"
    top="10vh"
    width="640px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :before-close="cancel"
    append-to-body
  >
    <component
      v-if="openElementEditDialog"
      ref="ElementPropEditComp"
      :is="curEditComponent"
      :instance="curElement"
      :key="curElement.id"
      @modified="modified"
    ></component>

    <div slot="footer">
      <el-button type="primary" :disabled="loading" @click="submit"
        >确认</el-button
      >
      <el-button @click="cancel">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";
import { getElementName, getFillQuestionName } from "../elementModel";
import EditComposition from "../elements/composition/EditComposition";
import EditExplain from "../elements/explain/EditExplain";
import EditFillLine from "../elements/fill-line/EditFillLine";
import EditFillQuestion from "../elements/fill-question/EditFillQuestion";
import EditText from "../elements/text/EditText";
import EditImage from "../elements/image/EditImage";
import EditLine from "../elements/line/EditLine";
import EditLines from "../elements/lines/EditLines";
import EditGrids from "../elements/grids/EditGrids";

export default {
  name: "element-prop-edit",
  components: {
    EditComposition,
    EditExplain,
    EditFillLine,
    EditFillQuestion,
    EditText,
    EditImage,
    EditLine,
    EditLines,
    EditGrids,
  },
  data() {
    return { loading: false };
  },
  computed: {
    ...mapState("card", ["curElement", "topics", "openElementEditDialog"]),
    title() {
      if (this.curElement.type === "FILL_QUESTION")
        return getFillQuestionName(this.curElement);

      return this.curElement.type
        ? getElementName(this.curElement.type)
        : "属性编辑";
    },
    curEditComponent() {
      if (!this.curElement.type) return;
      let type = this.curElement.type.toLowerCase().replace("_", "-");
      if (type.indexOf("line-") === 0) type = "line";
      return `edit-${type}`;
    },
  },
  methods: {
    ...mapMutations("card", ["setOpenElementEditDialog"]),
    ...mapActions("card", [
      "addElement",
      "modifyElement",
      "modifyElementChild",
      "rebuildPages",
      "scrollToElementPage",
    ]),
    cancel() {
      this.setOpenElementEditDialog(false);
    },
    open() {
      this.setOpenElementEditDialog(true);
    },
    submit() {
      if (this.loading) return;
      this.loading = true;
      setTimeout(() => {
        this.loading = false;
      }, 500);
      this.$refs.ElementPropEditComp.submit();
    },
    equalTopicType(topic1, topic2) {
      if (topic1.type === topic2.type) {
        if (topic1.type !== "FILL_QUESTION") {
          return true;
        }

        return (
          topic1.isBoolean === topic2.isBoolean &&
          topic1.isMultiply === topic2.isMultiply
        );
      }
      return false;
    },
    checkTopicType(element) {
      const relateTopics = this.topics.filter(
        (item) =>
          item.topicNo === element.topicNo &&
          item.parent &&
          item.parent.id !== element.id
      );
      if (!relateTopics.length) return true;

      return !relateTopics.some(
        (topic) => !this.equalTopicType(element, topic)
      );
    },
    checkTopicNo(element) {
      if (element.type === "COMPOSITION") return true;

      const relateTopics = this.topics.filter(
        (item) =>
          item.topicNo === element.topicNo &&
          item.parent &&
          item.parent.id !== element.id
      );
      if (!relateTopics.length) return true;

      let er = [
        element.startNumber,
        element.startNumber + element.questionsCount - 1,
      ];

      const unvalid = relateTopics.some((item) => {
        const topic = item.type === "EXPLAIN" ? item.parent : item;
        const tr = [
          topic.startNumber,
          topic.startNumber + topic.questionsCount - 1,
        ];
        return (
          (er[0] <= tr[0] && er[1] >= tr[0]) ||
          (er[0] <= tr[1] && er[1] >= tr[1]) ||
          (er[0] >= tr[0] && er[1] <= tr[1])
        );
      });

      return !unvalid;
    },
    modified(element) {
      if (!element["container"]) {
        if (!this.checkTopicType(element)) {
          this.$message.error("同一大题号的所有试题题型必须相同");
          return;
        }
        // 在不校验大题号重复的情况下,需要校验小题号重复
        if (!this.checkTopicNo(element)) {
          this.$message.error("小题号重复,请重新设置小题号");
          return;
        }
      }
      // 编辑试题
      // 属性存在的条件:parent:大题的小题,container:题目内的子元素
      if (this.curElement["_edit"]) {
        if (element["container"]) {
          this.modifyElementChild(element);
        } else {
          this.modifyElement(element);
        }
      } else {
        this.addElement(element);
      }
      this.cancel();
      this.$nextTick(() => {
        this.rebuildPages();
        this.$nextTick(() => {
          this.scrollToElementPage(element);
        });
      });
    },
  },
};
</script>