<template>
  <div class="mark-paper-marker">
    <div class="box-justify part-box part-box-pad">
      <div>
        <p class="tips-info">1.请点击右上角新增按钮创建评卷分组；</p>
        <p class="tips-info">
          2.如果采用整卷批阅，请将全部主观题选上，然后选择评卷老师。如果采用流水阅卷，请选择试题勾选对应的评卷老师；
        </p>
        <p class="tips-info tips-error">3.开始阅卷后不允许删除评卷分组！</p>
      </div>
      <div>
        <mark-status field="group"></mark-status>
        <el-button class="ml-2" type="primary" @click="toAdd">新增</el-button>
      </div>
    </div>

    <div class="part-box part-box-pad">
      <el-table :data="groupInfo" border>
        <el-table-column type="index" width="50"> </el-table-column>
        <el-table-column label="评卷员">
          <template slot-scope="scope">
            <el-tag
              v-for="user in scope.row.markerList"
              :key="user.id"
              class="tag-spin"
              size="medium"
            >
              {{ user.name }}（{{ user.orgName }}）
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="评卷方式">
          <template slot-scope="scope">
            <el-radio-group v-model="scope.row.doubleRate">
              <el-radio
                v-for="(val, key) in MARK_TYPE"
                :key="key"
                :label="key * 1"
                >{{ val }}</el-radio
              >
            </el-radio-group>
            <span v-if="scope.row.doubleRate === 1">
              仲裁阀值：<el-input-number
                v-model="scope.row.arbitrateThreshold"
                class="width-80"
                size="small"
                :min="0"
                :max="999999"
                :step="0.01"
                step-strictly
                :controls="false"
              >
              </el-input-number>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="评阅题目">
          <template slot-scope="scope">
            {{ scope.row.questions | questionsFilter }}
          </template>
        </el-table-column>
        <el-table-column label="评卷区" width="80" align="center">
          <template slot-scope="scope">
            <i
              v-if="scope.row.pictureConfigList.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="toEdit(scope.row)"
              >编辑</el-button
            >
            <el-button
              class="btn-primary"
              type="text"
              :disabled="!paperList.length"
              @click="toSetArea(scope.row)"
              >评卷区</el-button
            >
            <el-button
              class="btn-danger"
              type="text"
              @click="toDelete(scope.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>
    <mark-paper-class
      v-if="
        checkPrivilege('button', 'OpenClassReading', 'UploadStructure') &&
        dataReady
      "
      ref="MarkPaperClass"
      :datas="{
        groupInfo,
        classInfo: datas.classInfo,
        basicPaperInfo: datas.basicPaperInfo,
      }"
    ></mark-paper-class>

    <!-- ModifyMarkerQuestion -->
    <modify-marker-question
      ref="ModifyMarkerQuestion"
      :course-code="datas.basicPaperInfo.courseCode"
      :instance="curGroupInfo"
      :disabled-question-ids="disabledQuestionIds"
      :paper-structure="subjectiveQuestionList"
      @modified="groupModified"
    ></modify-marker-question>
    <!-- ModifyMarkArea -->
    <modify-mark-area
      ref="ModifyMarkArea"
      :base-info="datas.basicPaperInfo"
      :group="curGroupInfo"
      :paper-list="paperList"
      @modified="areaModified"
    ></modify-mark-area>
  </div>
</template>

<script>
import MarkStatus from "./MarkStatus.vue";
import ModifyMarkerQuestion from "./ModifyMarkerQuestion.vue";
import ModifyMarkArea from "./ModifyMarkArea.vue";
import markPaperClass from "./markPaperClass.vue";
import { examStructureFindJpg } from "../../api";
import { cardDetail } from "../../../card/api";

export default {
  name: "mark-paper-group",
  components: {
    ModifyMarkerQuestion,
    ModifyMarkArea,
    MarkStatus,
    markPaperClass,
  },
  props: {
    datas: {
      type: Object,
      default() {
        return {
          basicPaperInfo: {},
          paperStructureInfo: [],
          groupInfo: [],
          classInfo: [],
        };
      },
    },
  },
  data() {
    return {
      questionCount: 0,
      groupQuestionCount: 0,
      groupInfo: [],
      disabledQuestionIds: [],
      curGroupInfo: {},
      subjectiveQuestionList: [],
      subjectiveQuestionCount: 0,
      objectiveQuestionCount: 0,
      MARK_TYPE: {
        0: "单评",
        1: "双评",
      },
      paperList: [],
      cardPages: [],
      dataReady: false,
    };
  },
  filters: {
    questionsFilter(val) {
      return val
        .map((item) => `${item.mainNumber}-${item.subNumber}`)
        .join(",");
    },
  },
  mounted() {
    this.initData();
    this.getPaperList();
    this.getCardPages();
  },
  methods: {
    async getPaperList() {
      this.paperList = [];
      const data = await examStructureFindJpg({
        examId: this.datas.basicPaperInfo.examId,
        courseCode: this.datas.basicPaperInfo.courseCode,
        paperNumber: this.datas.basicPaperInfo.paperNumber,
        paperType: this.datas.basicPaperInfo.paperType,
      });
      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.datas.basicPaperInfo.cardId);
      const cardContent = JSON.parse(detData.content);
      this.cardPages = cardContent.pages;
    },
    initData() {
      this.groupInfo = this.datas.groupInfo.map((item, index) => {
        return { ...item, groupNumber: index + 1 };
      });
      this.questionCount = this.datas.paperStructureInfo.length;
      this.updateDisableQuestionIds();

      this.subjectiveQuestionList = this.datas.paperStructureInfo.filter(
        (item) => item.qType === "subjective"
      );
      this.subjectiveQuestionCount = this.subjectiveQuestionList.length;
      this.objectiveQuestionCount =
        this.questionCount - this.subjectiveQuestionCount;

      this.dataReady = true;
      this.$emit("on-ready");
    },
    updateDisableQuestionIds(filterId) {
      let groupInfo = this.groupInfo;
      if (filterId)
        groupInfo = this.groupInfo.filter((item) => item.id !== filterId);
      let disabledQuestionIds = [];
      groupInfo.forEach((item) => {
        disabledQuestionIds = [
          ...disabledQuestionIds,
          ...item.questions.map((item) => item.id),
        ];
      });
      this.disabledQuestionIds = disabledQuestionIds;
      if (!filterId) this.groupQuestionCount = disabledQuestionIds.length;
    },
    updateGroupNumber() {
      this.groupInfo.forEach((group, index) => {
        group.groupNumber = index + 1;
      });
    },
    toAdd() {
      this.updateDisableQuestionIds();
      if (this.groupQuestionCount === this.subjectiveQuestionCount) {
        this.$message.error("当前已经没有主观题目可供设置！");
        return;
      }

      this.curGroupInfo = {
        id: this.$randomCode(),
        groupNumber: null,
        markerList: [],
        doubleRate: 0,
        arbitrateThreshold: 1,
        questions: [],
        pictureConfigList: [],
      };
      this.$refs.ModifyMarkerQuestion.open();
    },
    toEdit(row) {
      this.curGroupInfo = row;
      this.updateDisableQuestionIds(row.id);
      this.$refs.ModifyMarkerQuestion.open();
    },
    toSetArea(row) {
      this.curGroupInfo = row;
      this.$refs.ModifyMarkArea.open();
    },
    toDelete(row) {
      const pos = this.groupInfo.findIndex((item) => item.id === row.id);
      this.groupInfo.splice(pos, 1);
      this.updateDisableQuestionIds();
      this.updateGroupNumber();
    },
    groupModified(row) {
      const pos = this.groupInfo.findIndex((item) => item.id === row.id);
      if (!row.pictureConfigList.length) {
        row.pictureConfigList = this.autoParsePictureConfigList(row.questions);
      }

      if (pos === -1) {
        this.groupInfo.push(row);
      } else {
        this.groupInfo.splice(pos, 1, row);
      }
      this.updateDisableQuestionIds();
      this.updateGroupNumber();

      // 分班阅卷相关
      this.$refs.MarkPaperClass && this.$refs.MarkPaperClass.groupChange();
    },
    autoParsePictureConfigList(questions) {
      if (!questions.length) return [];
      let pictureConfigList = [];
      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;
            pictureConfigList.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)) &&
              !pictureConfigList.find((item) => item.qStruct === qStruct)
            ) {
              pictureConfigList.push(pConfig);
            }
          }
        });
      });
      pictureConfigList.forEach((item) => {
        delete item.qStruct;
      });

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

        if (
          prevConfig.i === item.i &&
          prevConfig.y + prevConfig.h >= 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);
      // 自动扩展区域。
      let scaleRate = 0.002;
      combinePictureConfigList = combinePictureConfigList.map((item) => {
        return {
          i: item.i,
          x: item.x - scaleRate,
          y: item.y - scaleRate,
          w: item.w + 2 * scaleRate,
          h: item.h + 2 * scaleRate,
        };
      });

      return combinePictureConfigList;
    },
    areaModified(row) {
      const pos = this.groupInfo.findIndex((item) => item.id === row.id);
      if (pos === -1) return;
      this.groupInfo.splice(pos, 1, row);
    },
    checkData() {
      let errorMessages = [];

      if (this.subjectiveQuestionCount > this.groupQuestionCount) {
        errorMessages.push("当前还有题目未设置分组");
      }

      this.groupInfo.forEach((item, index) => {
        if (item.doubleRate === 1 && !item.arbitrateThreshold) {
          errorMessages.push(`序号${index + 1}设置中，仲裁阀值不能为空`);
        }
      });

      // if (this.$refs.MarkPaperClass) {
      //   errorMessages.push(...this.$refs.MarkPaperClass.checkData());
      // }

      if (errorMessages.length) {
        this.$message.error(errorMessages.join("。"));
        return;
      }

      this.updateData();
      this.$emit("next-step");
    },
    getData() {
      let data = {
        groupInfo: this.groupInfo.map((item) => {
          return { ...item };
        }),
      };

      if (this.$refs.MarkPaperClass) {
        const { openClassReading, classInfo } =
          this.$refs.MarkPaperClass.getData();
        data.classInfo = classInfo;
        data.basicPaperInfo = Object.assign(this.datas.basicPaperInfo, {
          openClassReading,
        });
      }
      return data;
    },
    updateData() {
      this.$emit("data-change", this.getData());
    },
  },
};
</script>
