<template>
  <div class="line-scan scan">
    <div class="scan-task task-list">
      <div
        :class="[
          'task-item',
          {
            'task-current': curStudent.isCurrent,
            'task-over': curStudent.isClient
          }
        ]"
      >
        <span>{{ curStudent.name }}</span>
        <span>{{ curStudent.examNumber }}</span>
      </div>
    </div>
    <div class="scan-image">
      <div class="scan-main scan-waiting" v-if="isWaiting">
        <p class="scan-waiting-icon"></p>
        <p class="scan-waiting-tips">等待采集试卷</p>
      </div>
      <div class="scan-main scan-picture" v-else>
        <img class="img-contain" :src="curImage.url" :alt="curImage.name" />
      </div>
    </div>
    <div class="scan-history">
      <div
        class="history-item"
        v-for="(task, tindex) in historyList"
        :key="tindex"
      >
        <p class="history-item-title">
          <span>{{ task.name }}</span
          ><span>{{ task.examNumber }}</span>
        </p>
        <div class="history-item-body">
          <img :src="task.url" :alt="task.name" />
        </div>
      </div>
    </div>

    <!-- reset current image scan area dialog -->
    <scan-area-dialog
      :cur-image="curImage"
      :cur-collect-config="curCollectConfig"
      @confirm="studentConfigChange"
      ref="ScanAreaDialog"
    ></scan-area-dialog>
    <!-- scan exception dialog -->
    <scan-exception-dialog
      :cur-image="curImage"
      :cur-exception="curException"
      @on-reset="resetConfig"
      @on-rescan="restartInitFile"
      @confirm="examNumberValid"
      ref="ScanExceptionDialog"
    ></scan-exception-dialog>
  </div>
</template>

<script>
const fs = require("fs");
import { getStudentByExamNumber } from "../api";
import {
  decodeImageCode,
  getEarliestFile,
  saveOutputImage
} from "../../../plugins/imageOcr";
import { deepCopy } from "../../../plugins/utils";
import ScanAreaDialog from "../components/ScanAreaDialog";
import ScanExceptionDialog from "../components/ScanExceptionDialog";
import { mapState } from "vuex";

export default {
  name: "line-scan",
  components: { ScanAreaDialog, ScanExceptionDialog },
  data() {
    return {
      isWaiting: true,
      students: [],
      curStudent: {},
      curCollectConfig: {},
      curException: {
        showAction: true,
        message: ""
      },
      historyLimit: 30,
      historyList: [
        {
          name: "张一二三",
          examNumber: "1901040084",
          url:
            "http://127.0.0.1:9000/api/file/image/download/31/1/734/1?random=676176fc-24cd-407a-a7bc-fabc49bd2dbc"
        },
        {
          name: "张一二三",
          examNumber: "1901040084",
          url:
            "http://127.0.0.1:9000/api/file/image/download/31/1/733/1?random=e2966291-ffba-4b19-985d-0cad9ae1b75b"
        },
        {
          name: "张一二三",
          examNumber: "1901040084",
          url:
            "http://127.0.0.1:9000/api/file/image/download/31/1/731/1?random=b305c27c-76d0-4477-a1ef-c9b8554a4671"
        }
      ],
      setT: "",
      holding: false,
      curImage: {
        url: "",
        name: ""
      }
    };
  },
  computed: {
    ...mapState("client", ["curSubject", "clientConfig", "curLevel"]),
    user() {
      return this.$store.state.user;
    }
  },
  mounted() {
    if (!this.curSubject || !this.curSubject.collectConfig) {
      this.$Message.error("请先完成采集设置！");
      return;
    }
    // this.getInitFile();
    // this.test();
  },
  methods: {
    async test() {
      this.curImage = getEarliestFile();
      const codeAreas = {
        codeArea: {
          x: 0,
          y: 0,
          width: 717.12,
          height: 673.92,
          rotate: 0,
          scaleX: 1,
          scaleY: 1,
          codeRotate: 90
        },
        coverArea: {
          x: 518.4,
          y: 345.6,
          width: 4147.2,
          height: 2764.8,
          rotate: 0,
          scaleX: 1,
          scaleY: 1
        },
        tailorArea: {
          x: 518.4,
          y: 345.6,
          width: 4147.2,
          height: 2764.8,
          rotate: 0,
          scaleX: 1,
          scaleY: 1
        },
        imageRotate: 0
      };
      const examNumber = await decodeImageCode(
        this.curImage.url,
        codeAreas.codeArea
      ).catch(error => {
        const content = `图像：${this.curImage.name}，解析错误，错误信息：${error}`;

        this.$Notice.error({ title: "错误提示", desc: content, duration: 0 });
      });
      console.log(examNumber);
    },
    getInitFile() {
      this.curImage = getEarliestFile(this.GLOBAL.input);

      if (this.curImage.url) {
        if (this.setT) clearTimeout(this.setT);
        this.isWaiting = false;
        this.$nextTick(() => {
          this.startDecodeTask(this.curSubject.collectConfig.codeArea);
        });
      } else {
        this.setT = setTimeout(() => {
          this.getInitFile();
        }, 1000);
      }
    },
    restartInitFile() {
      this.isWaiting = true;
      this.curStudent = {};
      if (this.setT) clearTimeout(this.setT);
      this.curImage = { url: "", name: "" };

      this.$nextTick(() => {
        this.getInitFile();
      });
    },
    async startDecodeTask(codeArea) {
      const examNumber = await decodeImageCode(
        this.curImage.url,
        codeArea
      ).catch(error => {
        const content = `图像：${this.curImage.name}，解析错误，错误信息：${error}`;
        this.$Notice.error({ title: "错误提示", desc: content, duration: 0 });
      });

      if (examNumber) {
        this.examNumberValid(examNumber);
      } else {
        // 未解析到考号异常
        this.curException = {
          showAction: true,
          message: "该图片无法识别，请处理！",
          collectConfig: this.getCurCollectConfig()
        };
        this.$refs.ScanExceptionDialog.open();
      }
    },
    async examNumberValid(examNumber, type = "AUTO") {
      const validRes = await this.checkStudentValid(examNumber);
      if (validRes.valid) {
        // 保存扫描到的试卷
        this.toSaveStudent(examNumber, type);
      } else {
        // 考号不合法异常
        this.curException = {
          showAction: false,
          message: validRes.message
        };
        this.$refs.ScanExceptionDialog.open();
      }
    },
    async checkStudentValid(examNumber) {
      let validInfo = { valid: true, message: "" };
      const curStudent = await getStudentByExamNumber(
        examNumber
      ).catch(() => {});

      if (!curStudent) {
        validInfo = {
          valid: false,
          message: "无该考生，请处理！"
        };
      } else {
        this.curStudent = {
          ...curStudent,
          imgPath: this.curImage.url,
          isClient: false,
          isCurrent: true,
          isManual: false,
          collectConfig: null
        };
      }
      return validInfo;
    },
    async toSaveStudent(examNumber, type) {
      const result = await saveOutputImage(
        this.curImage.url,
        {
          workId: this.user.workId,
          subjectId: this.curSubject.id,
          examNumber
        },
        this.getCurCollectConfig()
      ).catch(error => {
        const content = `${this.curStudent.name}的试卷保存失败，请重新扫描！`;
        this.$Notice.error({ title: "错误提示", desc: content, duration: 0 });
      });

      if (result) {
        this.curStudent = Object.assign(this.curStudent, {
          isClient: true,
          formalImgPath: result.outputFormalPath,
          sliceImgPath: result.outputSlicelPath,
          isManual: type === "MANUAL"
        });
        await this.appendUploadTask();
        this.updateHistory(this.curStudent);
      }
      // 删除扫描文件，继续开始下一个任务
      fs.unlinkSync(this.curImage.url);
      this.restartInitFile();
    },
    async appendUploadTask() {
      await this.$parent.addUploadTask({
        id: null,
        examId: this.user.examId,
        examName: this.user.examName,
        subjectId: this.curSubject.id,
        subjectName: this.curSubject.name,
        examNumber: this.curStudent.examNumber,
        studentName: this.curStudent.name,
        siteCode: this.curStudent.siteCode,
        roomCode: this.curStudent.roomCode,
        formalImgPath: this.curStudent.formalImgPath,
        sliceImgPath: this.curStudent.sliceImgPath,
        isManual: this.curStudent.isManual,
        imageEnc: this.clientConfig.imageEnc,
        level: this.curLevel,
        clientUserId: this.user.id,
        clientUsername: this.user.name,
        clientUserLoginTime: this.user.loginTime
      });
    },
    getCurCollectConfig() {
      return this.curStudent.collectConfig || this.curSubject.collectConfig;
    },
    // history
    updateHistory(curStudent) {
      const student = deepCopy(curStudent);
      if (this.historyList.length >= this.historyLimit) {
        this.historyList.pop();
      }
      this.historyList.unshift(student);
    },
    // scan-exception
    resetConfig() {
      this.curCollectConfig = this.getCurCollectConfig();
      this.$refs.ScanAreaDialog.open();
    },
    studentConfigChange(setting) {
      this.curStudent.collectConfig = setting;
      this.startDecodeTask(setting.codeArea);
    },
    goBack() {
      this.$confirm({
        content: "当前正处于采集状态，确定要退出吗?",
        onOk: () => {
          this.$router.go(-1);
        }
      });
    }
  },
  beforeDestroy() {
    if (this.setT) clearTimeout(this.setT);
  }
};
</script>
