<template>
  <div class="mark-param-group">
    <div class="box-justify part-box part-box-pad">
      <div>
        <p v-if="unsetQuestionNos" class="tips-info tips-error">
          试题{{
            unsetQuestionNos
          }}未设置评卷员，请点击列表里设置评卷员选择评卷员
        </p>
      </div>
      <div>
        <el-button type="primary" @click="toPrev(1)">上一步</el-button>
        <el-button type="primary" @click="toNext(1)">下一步</el-button>
      </div>
    </div>

    <div class="part-box part-box-pad">
      <el-table
        :data="subjectiveTaskList"
        border
        :span-method="openMergeMarker ? objectSpanMethod : undefined"
      >
        <el-table-column label="大题名称" prop="mainTitle"> </el-table-column>
        <el-table-column label="大题号" prop="mainNumber" width="80">
        </el-table-column>
        <el-table-column label="小题号" prop="subNumber" width="80">
        </el-table-column>
        <el-table-column label="评卷员" min-width="200">
          <template slot-scope="scope">
            <el-tag
              v-for="user in scope.row.markers"
              :key="user.markUserQuestionId"
              class="tag-spin tag-wrap"
              size="medium"
              effect="dark"
              closable
              @close="toDeleteMarker(scope.row, user)"
            >
              {{ user.name }}（{{ user.loginName }}）
            </el-tag>
            <el-button
              type="text"
              class="btn-primary"
              @click="toSetMarker(scope.row)"
            >
              设置评卷员
            </el-button>
          </template>
        </el-table-column>
        <el-table-column label="评卷方式" width="100">
          <template slot-scope="scope">
            {{ scope.row.doubleRate > 0 ? "双评" : "单评" }}
          </template>
        </el-table-column>
        <el-table-column label="仲裁阈值" width="100">
          <template v-if="scope.row.doubleEnable" slot-scope="scope">
            {{ scope.row.arbitrateThreshold }}
          </template>
        </el-table-column>
        <el-table-column label="合分策略" width="100">
          <template v-if="scope.row.doubleEnable" slot-scope="scope">
            {{ SCORE_POLICY_TYPE[scope.row.scorePolicy] }}
          </template>
        </el-table-column>
        <el-table-column label="双评比例" width="100">
          <template v-if="scope.row.doubleEnable" slot-scope="scope">
            {{ scope.row.doubleRate }}%
          </template>
        </el-table-column>
        <el-table-column label="评卷区" width="80" align="center">
          <template slot-scope="scope">
            <i
              v-if="scope.row.pictureConfigs?.length"
              class="el-icon-success color-success"
            ></i>
          </template>
        </el-table-column>
        <el-table-column class-name="action-column" label="操作" width="160px">
          <template slot-scope="scope">
            <el-button
              class="btn-primary"
              type="text"
              @click="toSetMarkType(scope.row)"
              >评卷方式设置</el-button
            >
            <el-button
              class="btn-primary"
              type="text"
              :disabled="!paperList.length"
              @click="toSetArea(scope.row)"
              >评卷区</el-button
            >
          </template>
        </el-table-column>
      </el-table>

      <!-- subjective answer -->
      <el-form class="mt-2" label-width="150px">
        <el-form-item label="请上传标答PDF文档：">
          <mark-param-subjective-answer></mark-param-subjective-answer>
        </el-form-item>
      </el-form>
    </div>

    <!-- ModifyMarkType -->
    <modify-mark-type
      ref="ModifyMarkType"
      :instance="curRow"
      @modified="markTypeModified"
    ></modify-mark-type>
    <!-- ModifyMarkMarker -->
    <modify-mark-marker
      ref="ModifyMarkMarker"
      :instance="curRow"
      :course-id="basicInfo.courseId"
      :question-list="curRowQuestions"
      @modified="markMarkerModified"
    ></modify-mark-marker>
    <!-- ModifyMarkArea -->
    <modify-mark-area
      ref="ModifyMarkArea"
      :base-info="basicInfo"
      :group="curRow"
      :paper-list="paperList"
      @modified="areaModified"
    ></modify-mark-area>
  </div>
</template>

<script>
import { mapState, mapMutations } from "vuex";
import ModifyMarkType from "./ModifyMarkType.vue";
import ModifyMarkArea from "./ModifyMarkArea.vue";
import ModifyMarkMarker from "./ModifyMarkMarker.vue";
import MarkParamSubjectiveAnswer from "./MarkParamSubjectiveAnswer.vue";
import {
  examStructureFindJpg,
  markSubjectiveBindMarker,
  markSubjectiveUpdateMarkType,
  markSubjectiveUpdateMarkArea,
  markSubjectiveUnbindMarker,
} from "../../api";
import { cardDetail } from "../../../card/api";
import { SCORE_POLICY_TYPE } from "@/constants/enumerate";

export default {
  name: "mark-param-group",
  components: {
    ModifyMarkType,
    ModifyMarkArea,
    ModifyMarkMarker,
    MarkParamSubjectiveAnswer,
  },
  data() {
    return {
      SCORE_POLICY_TYPE,
      questionCount: 0,
      curRow: {},
      curRowQuestions: [],
      MARK_TYPE: {
        0: "单评",
        1: "双评",
      },
      paperList: [],
      cardPages: [],
      fillQuestionRanges: [],
    };
  },
  computed: {
    ...mapState("markParam", [
      "basicInfo",
      "paperStructureInfo",
      "openMergeMarker",
      "subjectiveTaskList",
    ]),
    unsetQuestionNos() {
      return this.subjectiveTaskList
        .filter((item) => !item.markers.length)
        .map((item) => `${item.mainNumber}-${item.subNumber}`)
        .join(",");
    },
  },
  mounted() {
    this.initFillQuestionRanges();
    this.getPaperList();
    this.getCardPages();
  },
  methods: {
    ...mapMutations("markParam", [
      "setSubjectiveTaskList",
      "updateSubjectiveTaskItem",
    ]),
    async getPaperList() {
      this.paperList = [];
      const data = await examStructureFindJpg({
        examId: this.basicInfo.examId,
        courseId: this.basicInfo.courseId,
        paperNumber: this.basicInfo.paperNumber,
        serialNumber: this.basicInfo.serialNumber,
      });
      const papers = data || [];
      papers.sort((a, b) => a.index - b.index);
      this.paperList = papers.map((paper) => {
        return {
          imgUrl: paper.path,
          areas: [],
        };
      });
    },
    async getCardPages() {
      const detData = await cardDetail(this.basicInfo.cardId);
      const cardContent = JSON.parse(detData.content);
      this.cardPages = cardContent.pages;
    },
    initFillQuestionRanges() {
      if (!this.openMergeMarker) return;

      const qRangeDict = {};
      this.fillQuestionRanges = this.subjectiveTaskList.map((item, index) => {
        if (item.questionType !== 4) return;

        if (qRangeDict[item.mainNumber]) {
          qRangeDict[item.mainNumber].push(index);
        } else {
          qRangeDict[item.mainNumber] = [index];
        }
      });
      this.fillQuestionRanges = Object.values(qRangeDict);
    },
    objectSpanMethod({ rowIndex, columnIndex }) {
      // 第四列为评卷员
      if (columnIndex === 3 || columnIndex === 8) {
        const pos = this.fillQuestionRanges.findIndex((item) =>
          item.includes(rowIndex)
        );
        if (pos === -1) return;
        const range = this.fillQuestionRanges[pos];
        if (range[0] === rowIndex) {
          return {
            rowspan: range.length,
            colspan: 1,
          };
        } else {
          return {
            rowspan: 0,
            colspan: 0,
          };
        }
      }
    },
    getCurrentQuestions(row) {
      let curRowQuestions = [];
      if (this.openMergeMarker && row.questionType === 4) {
        // 填空题按大题批量处理
        const pos = this.subjectiveTaskList.findIndex(
          (item) => item.id === row.id
        );
        if (pos === -1) return;
        const range = this.fillQuestionRanges.find((item) =>
          item.includes(pos)
        );
        if (!range) return;
        curRowQuestions = range.map((index) => {
          const item = this.subjectiveTaskList[index];
          return {
            id: item.id,
            mainNumber: item.mainNumber,
            subNumber: item.subNumber,
          };
        });
      } else {
        // 非填空题按单题处理
        curRowQuestions = [
          {
            id: row.id,
            mainNumber: row.mainNumber,
            subNumber: row.subNumber,
          },
        ];
      }
      return curRowQuestions;
    },
    toSetMarker(row) {
      this.curRow = row;
      this.curRowQuestions = this.getCurrentQuestions(row);
      this.$refs.ModifyMarkMarker.open();
    },
    async markMarkerModified(row) {
      await markSubjectiveBindMarker({
        examId: this.basicInfo.examId,
        paperNumber: this.basicInfo.paperNumber,
        questionIds: this.curRowQuestions.map((item) => item.id),
        markers: row.markers,
      });

      this.curRowQuestions.forEach((item) => {
        this.updateSubjectiveTaskItem({
          id: item.id,
          markers: row.markers,
        });
      });
    },
    toSetArea(row) {
      this.curRow = row;
      this.curRowQuestions = this.getCurrentQuestions(row);
      this.$refs.ModifyMarkArea.open();
    },
    async areaModified(row) {
      await markSubjectiveUpdateMarkArea({
        examId: this.basicInfo.examId,
        paperNumber: this.basicInfo.paperNumber,
        questionIds: this.curRowQuestions.map((item) => item.id),
        pictureConfigs: row.pictureConfigs,
      });
      this.curRowQuestions.forEach((item) => {
        this.updateSubjectiveTaskItem({
          id: item.id,
          pictureConfigs: row.pictureConfigs,
        });
      });
    },
    async toDeleteMarker(row, marker) {
      const confirm = await this.$confirm(`确定要删除当前评卷员吗?`, "提示", {
        type: "warning",
      }).catch(() => {});
      if (confirm !== "confirm") return;

      const markers = row.markers.filter(
        (item) => item.markUserQuestionId !== marker.markUserQuestionId
      );
      await markSubjectiveUnbindMarker(marker.markUserQuestionId);
      this.updateSubjectiveTaskItem({
        id: row.id,
        markers,
      });
    },
    toSetMarkType(row) {
      this.curRow = row;
      this.$refs.ModifyMarkType.open();
    },
    async markTypeModified(row) {
      const pos = this.subjectiveTaskList.findIndex(
        (item) => item.id === row.id
      );
      if (pos === -1) return;
      const datas = {
        questionId: row.id,
        doubleEnable: row.doubleEnable,
        doubleRate: row.doubleRate,
        arbitrateThreshold: row.arbitrateThreshold,
        scorePolicy: row.scorePolicy,
      };
      await markSubjectiveUpdateMarkType(datas);
      this.updateSubjectiveTaskItem({
        ...datas,
        id: row.id,
      });
    },
    autoParsePictureConfigList(questions) {
      if (!questions.length) return [];
      let pictureConfigs = [];
      const structs = questions.map(
        (item) => `${item.mainNumber}_${item.subNumber}`
      );
      this.cardPages.forEach((page, pindex) => {
        page.exchange.answer_area.forEach((area) => {
          const [x, y, w, h] = area.area;
          const qStruct = `${area.main_number}_${area.sub_number}`;

          const pConfig = {
            i: pindex + 1,
            x,
            y,
            w,
            h,
            qStruct,
          };

          if (typeof area.sub_number === "number") {
            if (!structs.includes(qStruct)) return;
            pictureConfigs.push(pConfig);
            return;
          }
          // 复合区域处理，比如填空题，多个小题合并为一个区域
          if (typeof area.sub_number === "string") {
            const areaStructs = area.sub_number
              .split(",")
              .map((subNumber) => `${area.main_number}_${subNumber}`);
            if (
              structs.some((struct) => areaStructs.includes(struct)) &&
              !pictureConfigs.find((item) => item.qStruct === qStruct)
            ) {
              pictureConfigs.push(pConfig);
            }
          }
        });
      });
      pictureConfigs.forEach((item) => {
        delete item.qStruct;
      });
      // console.log(pictureConfigs);

      // 合并相邻区域
      pictureConfigs.sort((a, b) => {
        return a.i - b.i || a.x - b.x || a.y - b.y;
      });
      let combinePictureConfigList = [];
      let prevConfig = null;
      pictureConfigs.forEach((item, index) => {
        if (!index) {
          prevConfig = { ...item };
          combinePictureConfigList.push(prevConfig);
          return;
        }

        const elasticRate = 0.01;
        if (
          prevConfig.i === item.i &&
          prevConfig.y + prevConfig.h + elasticRate >= item.y &&
          prevConfig.w === item.w &&
          prevConfig.x === item.x
        ) {
          prevConfig.h = item.y + item.h - prevConfig.y;
        } else {
          prevConfig = { ...item };
          combinePictureConfigList.push(prevConfig);
        }
      });
      // console.log(combinePictureConfigList);
      return combinePictureConfigList;
    },
    checkData() {
      const errorList = [];
      this.subjectiveTaskList.forEach((item) => {
        const errors = [];
        if (!item.markers?.length) {
          errors.push("评卷员未设置");
        }
        if (!item.pictureConfigs?.length) {
          errors.push("评卷区未设置");
        }
        if (errors.length) {
          errorList.push(
            `${item.mainNumber}-${item.subNumber}：${errors.join("、")}。`
          );
        }
      });
      if (errorList.length) {
        this.$message.error(errorList.join("\n"));
        return false;
      }
      return true;
    },
    toPrev(step = 1) {
      this.$emit("prev", step);
    },
    toNext(step = 1) {
      if (!this.checkData()) return;
      this.$emit("next", step);
    },
  },
};
</script>
