<template>
  <div class="grade-action">
    <!-- 头部信息 ------ -->
    <!-- 试卷状态 -->
    <!-- 状态：已评，待评，打回，仲裁，改大裆，改大裆打小档 -->
    <div class="action-paper-state" v-if="stepType === 'reject'">
      <p class="paper-state-cont">
        {{ curPaperOrTask.isRejectedByLeader ? "科组长打回" : "自动打回" }}
      </p>
      <p class="paper-state-intro">
        <span v-if="curPaperOrTask.rejectedCount"
          >共打回{{ curPaperOrTask.rejectedCount }}次</span
        >
      </p>
    </div>
    <div class="action-paper-state" v-else>
      <p class="paper-state-cont">{{ stepLabel }}</p>
    </div>
    <!-- 试卷信息 -->
    <div class="action-paper-info">
      <p>
        <span v-if="IS_MARKER">任务密号：</span>
        <span v-else>试卷密号：</span>
        <span v-if="curPaperOrTask.sn && !isBatchAction">
          NO.{{ curPaperOrTask.sn }}
        </span>
        <span v-else>--</span>
      </p>
    </div>
    <!-- 改档信息 -->
    <div class="action-grade-change" v-if="rights.gradeChange">
      <p>
        <span>原始粗档位：</span
        ><span>{{ curPaperOrTask.originLevel | levelNameFilter }}</span>
      </p>
      <p>
        <span v-if="IS_MARKER">建议粗档位：</span>
        <span v-else>申请粗档位：</span>
        <span>{{ curPaperOrTask.redoLevel | levelNameFilter }}</span>
      </p>
    </div>
    <div
      :class="[
        'action-grade-change-status',
        { 'action-grade-change-status-error': curPaperOrTask.auditStatus === 0 }
      ]"
      v-if="rights.gradeChange && IS_ADMIN"
    >
      <p>{{ curPaperOrTask.auditStatus === 1 ? "同意改档" : "不同意改档" }}</p>
    </div>

    <!-- 大档位信息 -->
    <!-- 已评/待评（已评档位），改大裆打小档（已评档位） -->
    <div
      class="action-grade-info"
      v-if="rights.roughGradeInfo && curRoughLevel.name"
    >
      <h3 class="grade-info-name">
        {{ curRoughLevel.name | levelNameFilter }}
      </h3>
      <div class="grade-info-range">
        <p>档位范围</p>
        <p>
          <span>{{ curRoughLevel.minScore }}</span>
          <span>~</span>
          <span>{{ curRoughLevel.maxScore }}</span>
        </p>
      </div>
    </div>

    <!-- 小档位信息 -->
    <!-- 已评（已评档位），打回（建议档位） -->
    <h3
      class="action-grade-info-title"
      v-if="IS_MARKER && stepType === 'reject'"
    >
      <span>原细分档档位：{{ curPaperOrTask.originLevel || "" }}</span>
      <span
        v-if="
          paramsSet.levelConfig &&
            paramsSet.levelConfig.autoCallbackShowDeviation &&
            curPaperOrTask.deviationDirection &&
            curPaperOrTask.deviationDirection !== '0'
        "
        :class="[
          'grade-info-deviation',
          {
            'grade-info-deviation-error':
              curPaperOrTask.deviationDirection * 1 > 0
          }
        ]"
        >{{ curPaperOrTask.deviationDirection * 1 > 0 ? "偏高" : "偏低" }}</span
      >
    </h3>
    <h3
      class="action-grade-info-title"
      v-if="curPaperOrTask.rejected && curPaperOrTask.isRejectedByLeader"
    >
      建议细分档位：
    </h3>
    <div class="action-grade-info" v-if="rights.gradeInfo && curLevel.name">
      <h3 class="grade-info-name">{{ curLevel.name }}</h3>
      <div class="grade-info-range">
        <p>分数范围</p>
        <p>
          <span>{{ curLevel.minScore }}</span>
          <span>~</span>
          <span>{{ curLevel.maxScore }}</span>
        </p>
      </div>
    </div>
    <!-- 小档位信息 -->
    <div
      class="action-grade-info action-mark-info"
      v-if="rights.gradeInfo && !curLevel.name"
    >
      <p class="grade-info-name grade-info-none">未分档</p>
    </div>

    <!-- 选择小档位  -->
    <div class="action-grade-list" v-if="rights.levelList">
      <div
        class="action-grade-item"
        v-for="(level, index) in levelList"
        :key="index"
      >
        <div
          :class="[
            'action-grade-item-content',
            {
              'action-item-content-disabled': btnClicked,
              'is-active': keyInput == level.name
            }
          ]"
          @click="selectLevel(level)"
        >
          <p>{{ level.name }}</p>
          <p>{{ level.minScore }}~{{ level.maxScore }}</p>
        </div>
      </div>
    </div>
    <!-- 选择大档位 -->
    <h3
      class="action-grade-info-title"
      v-if="IS_MARK_LEADER && markLeaderOnlyRight && rights.roughLevelList"
    >
      当前操作：{{ markLeaderOnlyRight.name }}
    </h3>
    <div class="action-grade-list" v-if="rights.roughLevelList">
      <div
        class="action-grade-item"
        v-for="(level, index) in roughLevelList"
        :key="index"
      >
        <div
          :class="[
            'action-grade-item-content',
            {
              'action-item-content-disabled': btnClicked,
              'is-active': keyInput == level.name
            }
          ]"
          @click="selectRoughLevel(level)"
        >
          <p>{{ level.name | levelNameFilter }}</p>
          <p>{{ level.minScore }}~{{ level.maxScore }}</p>
          <p v-if="level.minSubScore || level.maxSubScore">
            {{ level.minSubScore }}~{{ level.maxSubScore }}
          </p>
        </div>
      </div>
    </div>
    <div
      v-if="
        ribbonSet.keyboardMark && (rights.roughLevelList || rights.levelList)
      "
      class="action-grade-keyboard"
    >
      <div class="keyboard-input">{{ keyInput }}</div>
      <div class="keyboard-clear" @click="clearKeyInput">
        <Icon type="md-trash" />
      </div>
    </div>
    <!-- 跳过 -->
    <div
      class="action-grade-pass"
      v-if="rights.gradePass && IS_MARKER"
      @click="toPass"
    >
      跳过
    </div>

    <!-- marker confirm grade change -->
    <div
      class="action-grade-change-confirm"
      v-if="IS_MARKER && rights.gradeChange"
    >
      <Button type="primary" @click="gradeChangeConfirm">确认改档</Button>
    </div>

    <!-- 评卷记录 -->
    <div class="action-grade-history" v-if="rights.gradeHis">
      <h3>评卷记录</h3>
      <div class="grade-history-list">
        <div
          class="grade-history-item"
          v-for="his in gradingHistory"
          :key="his.id"
        >
          <p>{{ his.loginName }}</p>
          <p>{{ his.value }}</p>
        </div>
      </div>
    </div>

    <!-- 查询 -->
    <div class="action-search" v-if="rights.search">
      <Select
        class="search-select"
        v-model="filter.codeType"
        placeholder="密号类型"
      >
        <Option
          v-for="item in codeTypes"
          :key="item.key"
          :value="item.key"
          :label="item.val"
        ></Option>
      </Select>
      <Input
        class="search-input"
        v-model.trim="filter.code"
        placeholder="输入密号"
        clearable
      >
      </Input>
      <Button size="small" type="primary" class="search-btn" @click="searchCode"
        >查询</Button
      >
    </div>
  </div>
</template>

<script>
import { markHistoryList } from "@/api";
import { CODE_TYPE } from "@/constants/enumerate";
import { mapState, mapMutations } from "vuex";
import { levelNameTransform } from "@/plugins/utils";

// 三种情况：
// 管理员(ADMIN)，科组长(MARK_LEADER)，评卷员(MARKER)

// MARK_LEADER / ADMIN: curPaperOrTask => paper
// MARKER: curPaperOrTask => task
//
/*
[paper template]
{
  "id": 165,
  "sn": "029947536",
  "examNumber": "1901040084",
  "level": "A",
  "score": null,
  "redoLevel": null,
  "updatedOn": 1591767742000,
  "imgSrc": "",
  "thumbSrc": "",
  "markByLeader": false,
  "markedLogic": true,
  "areaCode": "2",
  "inspectScore": null,
  "inspectLevel": null,
  "inspector": null,
  "sheetSrc": null,
  "stage": "LEVEL",
  "test": 0,
  "paperTest": 0,
  "markResults": [],
  "rejected": false,
  "arbitrated": false,
  "sample": false,
  "tagged": false,
  "missing": false,
  "manual": false
}
[marktask template]
{
  id: 58,
  sn: "18111595446",
  redoLevel: null,
  level: null,
  roughLevel: "5",
  score: null,
  result: null,
  originLevel: "",
  markerId: 16,
  loginName: "sm1",
  marker: "sm1",
  updatedOn: null,
  imgSrc: "",
  thumbSrc: "",
  markByLeader: false,
  oldRejected: false,
  paperId: 107,
  randomSeqNew: 11595446,
  randomSeq: null,
  serialNumber: null,
  displayNumber: false,
  shift: false,
  shiftScore: false,
  isRejectedByLeader: false,
  rejectedCount: 0,
  dateMineResult: null,
  deviationDirection: null,
  sample: false,
  rejected: false,
  mark: false,
  key: "i9k7nqr8s2kb60uo",
  title: "NO.18111595446",
  selected: false
};
*/

const initRights = {
  roughGradeInfo: false,
  gradeInfo: false,
  levelList: false,
  roughLevelList: false,
  gradePass: false,
  gradeHis: false,
  search: false
};

export default {
  name: "grade-action-rough",
  props: {
    curPaperOrTask: {
      type: Object,
      default() {
        return {};
      }
    },
    levels: {
      type: Array,
      default() {
        return [];
      }
    },
    paramsSet: {
      type: Object,
      default() {
        return {};
      }
    },
    isBatchAction: {
      type: Boolean,
      default: false
    },
    // 是否处于粗分档
    isRoughLevel: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      curUserRoleType: this.$ls.get("user", { role: "" }).role,
      curPaperOrTaskLevel: "",
      rights: {
        ...initRights
      },
      cacheRights: null,
      roleRight: {
        ADMIN: {
          done: ["roughGradeInfo", "gradeInfo", "gradeHis", "search"],
          reject: ["roughGradeInfo", "gradeInfo", "gradeHis", "search"],
          arbitrate: ["gradeHis", "search"],
          shift: [
            "roughGradeInfo",
            "gradeInfo",
            "search",
            "gradeChangeSearch",
            "gradeChange"
          ]
        },
        MARK_LEADER: {
          undo: ["roughGradeInfo", "gradeInfo", "levelList", "roughLevelList"],
          done: [
            "roughGradeInfo",
            "gradeInfo",
            "levelList",
            "roughLevelList",
            "gradeHis"
          ],
          reject: [
            "roughGradeInfo",
            "gradeInfo",
            "levelList",
            "roughLevelList",
            "gradeHis"
          ],
          arbitrate: ["roughGradeInfo", "gradeInfo", "levelList", "gradeHis"],
          shift: ["gradeChange", "roughLevelList"],
          batch: ["levelList"]
        },
        MARKER: {
          done: ["roughGradeInfo", "gradeInfo", "levelList"],
          undo: ["roughGradeInfo", "gradeInfo", "levelList", "gradePass"],
          reject: ["gradeInfo", "levelList", "gradePass"],
          shift: ["gradeChange"],
          shiftScore: ["roughGradeInfo", "gradeInfo", "levelList", "levelPass"],
          batch: ["levelList"]
        },
        STANDARD: ["gradeInfo"]
      },
      filter: {
        codeType: "examNumber",
        code: ""
      },
      codeTypes: [],
      stepDict: {
        undo: "待评",
        done: "已评",
        reject: "打回",
        arbitrate: "待仲裁",
        shift: "改大档",
        shiftScore: "改大档打小档",
        sample: "标准卷",
        batch: "批量操作"
      },
      stepType: "",
      stepLabel: "",
      gradingHistory: [],
      levelList: [],
      curLevel: {},
      roughLevelList: [],
      curRoughLevel: {},
      setT: null,
      btnClicked: false,
      keyInput: null,
      // 科组长权限
      markLeaderOnlyRight: null
    };
  },
  computed: {
    ...mapState("marker", ["ribbonSet", "shortcutKeyStatus", "curSubject"]),
    IS_ADMIN() {
      return this.curUserRoleType === "ADMIN";
    },
    IS_MARKER() {
      return this.curUserRoleType === "MARKER";
    },
    IS_MARK_LEADER() {
      return this.curUserRoleType === "MARK_LEADER";
    }
  },
  watch: {
    curPaperOrTask() {
      this.rebuildRight();
    },
    isBatchAction(val) {
      if (val) {
        this.stepType = "batch";
        this.stepLabel = this.stepDict[this.stepType];
        const roleRights =
          this.roleRight[this.curUserRoleType][this.stepType] || [];
        this.rights = { ...initRights };
        roleRights.map(key => {
          this.rights[key] = true;
        });
      } else {
        this.rebuildRight();
      }
      this.keyInput = null;
    },
    "ribbonSet.keyboardMark": {
      immediate: true,
      handler(val) {
        this.setShortcutStatus({ action: val });
      }
    },
    "shortcutKeyStatus.action": {
      immediate: true,
      handler(val, oldval) {
        // console.log(val, oldval);
        if (val === oldval) return;
        if (val) {
          document.addEventListener("keydown", this.keyEvent);
        } else {
          document.removeEventListener("keydown", this.keyEvent);
        }
      }
    }
  },
  mounted() {
    this.markLeaderOnlyRight = this.$ls.get("user", {
      markLeaderOnlyRight: null
    }).markLeaderOnlyRight;

    this.codeTypes = Object.entries(CODE_TYPE)
      .map(([key, val]) => {
        return {
          key,
          val
        };
      })
      .filter(item => item.key !== "examNumber");
    // .filter(item => this.IS_ADMIN || item.key !== "examNumber");
    this.rebuildRight();
  },
  methods: {
    ...mapMutations("marker", ["setShortcutStatus"]),
    getStepType() {
      const info = this.curPaperOrTask;
      if (info.sample) return "sample";
      if (info.shift && info.shiftScore && !info.level && !info.result)
        return "shift";
      if (!info.shift && info.shiftScore && !info.result) return "shiftScore";
      if (this.curPaperOrTaskLevel) return "done";
      if (info.arbitrated) return "arbitrate";
      if (info.rejected) return "reject";
      if (!info.rejected && !info.arbitrated && !info.level) return "undo";
      return;
    },
    rebuildRight() {
      if (this.setT) clearTimeout(this.setT);
      this.curPaperOrTaskLevel =
        this.curSubject.stage === "LEVEL"
          ? this.curPaperOrTask.level
          : this.curPaperOrTask.roughLevel || this.curPaperOrTask.level;

      let roleRights = [];
      this.stepType = this.getStepType();
      this.stepLabel = this.stepDict[this.stepType];
      if (this.stepType === "sample") {
        roleRights = this.roleRight.STANDARD;
      } else {
        roleRights = this.roleRight[this.curUserRoleType][this.stepType] || [];
      }
      this.rights = { ...initRights };
      roleRights.map(key => {
        this.rights[key] = true;
      });
      this.initLevels();
      if (this.rights.gradeHis) {
        this.getMarkHistory();
      }
      this.btnClicked = false;
      this.keyInput = null;
    },
    initLevels() {
      this.levelList = this.levels.filter(
        item => item.roughCode === this.curPaperOrTask.roughLevel
      );
      this.roughLevelList = this.parseRoughLevels(this.levels);
      const curRoughLevel = this.roughLevelList.find(
        item => item.name === this.curPaperOrTask.roughLevel
      );
      this.curRoughLevel = curRoughLevel || {};

      const levelName = this.curPaperOrTask.rejected
        ? this.curPaperOrTask.redoLevel
        : this.curPaperOrTaskLevel;
      if (levelName) {
        this.curLevel =
          this.levelList.find(item => item.name === levelName) || {};
      } else {
        this.curLevel = {};
      }
    },
    parseRoughLevels(levelList) {
      const levelMap = {};
      levelList.forEach(item => {
        const ind = item.roughCode;
        if (!levelMap[ind]) levelMap[ind] = [];
        levelMap[ind].push(item);
      });
      let roughLevelList = Object.keys(levelMap).map((roughCode, ind) => {
        const group = levelMap[roughCode];
        const levels = group.map(item => item.code);
        const minSs = group.map(item => item.minScore);
        const maxSs = group.map(item => item.maxScore);

        return {
          id: ind + 1,
          name: roughCode,
          minScore: levels[0],
          maxScore: levels.slice(-1)[0],
          minSubScore: Math.min.apply(null, minSs),
          maxSubScore: Math.max.apply(null, maxSs)
        };
      });
      roughLevelList.sort((a, b) => (a.name < b.name ? -1 : 1));
      return roughLevelList;
    },
    async getMarkHistory() {
      // 只有科组长和超管才会展示评卷记录
      const data = await markHistoryList(
        this.curPaperOrTask.id,
        this.curSubject.stage
      );
      this.gradingHistory = data.map(item => {
        let level = item.result || "未评";
        if (this.stepType === "reject" && !item.result) {
          level = `${levelNameTransform(level)}(${levelNameTransform(
            item.originLevel
          )})`;
        }
        return {
          id: item.id,
          markerId: item.markerId,
          name: item.marker,
          loginName: item.loginName,
          value: level
        };
      });
    },
    selectLevel(level) {
      if (this.isBatchAction) {
        if (this.btnClicked) return;
        this.btnClicked = true;
        this.setT = setTimeout(() => {
          this.btnClicked = false;
        }, 500);
        this.$emit("on-batch-level", level);
        return;
      }

      if (this.IS_MARKER && this.curPaperOrTaskLevel === level.name) return;
      if (this.btnClicked) return;
      this.btnClicked = true;

      if (this.IS_MARK_LEADER) {
        this.setT = setTimeout(() => {
          this.btnClicked = false;
        }, 500);

        this.$emit(
          "on-leader-level",
          {
            paperIds: this.curPaperOrTask.id + "",
            curLevel: this.curPaperOrTaskLevel,
            selectedLevel: level.name,
            markLeaderOnlyRight: this.markLeaderOnlyRight
          },
          this.gradingHistory.map(item => {
            return {
              id: item.markerId,
              name: item.loginName
            };
          })
        );
        return;
      }

      this.$emit("on-select-level", level);
    },
    selectRoughLevel(level) {
      if (this.curPaperOrTask.roughLevel === level.name) return;

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

      this.setT = setTimeout(() => {
        this.btnClicked = false;
      }, 500);
      // 科组长改档 / 评卷同意改档:只使用selectedLevel
      const curLevel =
        this.stepType === "shift"
          ? this.curPaperOrTask.redoLevel
          : this.curPaperOrTask.roughLevel;
      this.$emit("on-leader-change-level", {
        paperId: this.curPaperOrTask.paperId,
        curLevel,
        selectedLevel: level.name
      });
    },
    gradeChangeConfirm() {
      this.selectRoughLevel({ name: this.curPaperOrTask.redoLevel });
    },
    toPass() {
      this.$emit("on-pass");
    },
    searchCode() {
      if (!this.filter.code || !this.filter.codeType) {
        this.$Message.error("请设置密号类型和密号！");
        return;
      }
      this.$emit("on-code-search", this.filter);
    },
    // keyboard submit
    keyEvent(e) {
      this.$Message.destroy();
      if (this.btnClicked) return;
      // if (!this.ribbonSet.keyboardMark) return;
      if (!e.altKey && !e.shiftKey && !e.ctrlKey) {
        if (e.key === "Enter" && this.ribbonSet.needEnterSubmit) {
          e.preventDefault();
          this.toKeySubmit();
          return;
        }

        if (!/^[a-z0-9]$/.test(e.key)) return;

        const keyInput = e.key.toUpperCase();
        if (this.getKeyInputLevel(keyInput)) {
          e.preventDefault();
          this.keyInput = keyInput;

          if (!this.ribbonSet.needEnterSubmit) {
            this.toKeySubmit();
          }
        } else {
          this.$Message.error("按键无效");
        }
      }
    },
    getKeyInputLevel(key) {
      return (
        this.levelList.find(item => item.name === key) ||
        this.roughLevelList.find(item => item.name === key)
      );
    },
    toKeySubmit() {
      if (!this.keyInput) {
        this.$Message.error("请选择档位");
        return;
      }
      const level = this.getKeyInputLevel(this.keyInput);
      if (/^[a-z]$/.test(level.name)) {
        this.selectLevel(level);
      } else {
        this.selectRoughLevel(level);
      }
    },
    clearKeyInput() {
      this.keyInput = null;
    }
  },
  beforeDestroy() {
    if (this.setT) clearTimeout(this.setT);
    if (this.ribbonSet.keyboardMark)
      document.removeEventListener("click", this.keyEvent);
  }
};
</script>
