<template>
  <div>
    <Upload
      ref="uploadComp"
      :headers="headers"
      :data="{ fileType: fileType }"
      :before-upload="handleBeforeUpload"
      :action="
        '/api/ecs_oe_student/offlineExam/submitPaper?examRecordDataId=' +
          course.examRecordDataId
      "
      :max-size="1024 * 30"
      :format="uploadFileFormat"
      :accept="uploadFileAccept"
      :on-format-error="handleFormatError"
      :on-exceeded-size="handleMaxSize"
      :on-success="handleSuccess"
      :on-error="handleError"
      :show-upload-list="false"
    >
      <i-button
        icon="ios-cloud-upload-outline"
        class="qm-primary-button"
        style="width: 100%;"
      >
        上传作答
      </i-button>
    </Upload>
    <div v-if="file !== null && loadingStatus">
      待上传文件: {{ file.name }}
      <i-button :loading="loadingStatus">
        {{ loadingStatus ? "上传中..." : "上传" }}
      </i-button>
    </div>
  </div>
</template>

<script>
export default {
  name: "EcsOfflineUpload",
  data() {
    return {
      headers: {
        token: window.sessionStorage.getItem("token"),
        key: window.localStorage.getItem("key")
      },
      file: null,
      fileType: null,
      loadingStatus: false,
      uploadFileFormat: [],
      uploadFileAccept: ""
    };
  },
  props: {
    course: Object
  },
  async created() {
    const res = await this.$http.get(
      "/api/ecs_exam_work/exam/examOrgProperty/" +
        this.course.examId +
        `/OFFLINE_UPLOAD_FILE_TYPE`
    );

    this.uploadFileFormat = res.data || [];
    this.uploadFileFormat = this.uploadFileFormat.map(v => v.toLowerCase());
    this.uploadFileAccept = this.uploadFileFormat
      .map(v => "application/" + v)
      .join();
  },
  methods: {
    fileFormatCheck(file, resolve, reject) {
      function getMimetype(signature) {
        switch (signature) {
          case "89504E47":
            return "image/png";
          case "47494638":
            return "image/gif";
          case "25504446":
            return "application/pdf";
          case "FFD8FFDB":
          case "FFD8FFE0":
          case "FFD8FFE1":
            return "image/jpeg";
          case "504B0304":
            return "application/zip";
          case "504B34":
            return "application/zip";
          default:
            return "Unknown filetype";
        }
      }

      const filereader = new FileReader();
      let uploads = [];
      filereader.onloadend = evt => {
        if (evt.target.readyState === FileReader.DONE) {
          const uint = new Uint8Array(evt.target.result);
          let bytes = [];
          uint.forEach(byte => {
            bytes.push(byte.toString(16));
          });
          const hex = bytes.join("").toUpperCase();
          uploads.push({
            filename: file.name,
            filetype: file.type ? file.type : "Unknown/Extension missing",
            binaryFileType: getMimetype(hex),
            hex: hex
          });

          if (["application/pdf"].includes(getMimetype(hex))) {
            if (!file.name.endsWith(".pdf")) {
              this.loadingStatus = false;
              this.$Notice.warning({
                title: "文件内容与文件的后缀不一致"
                // desc: file.name + " 文件是pdf文档，但文件名后缀不是.pdf！"
              });
              this.file = null;
              reject("文件内容与文件的后缀不一致，请确认文件是pdf文档！");
            } else {
              resolve();
            }
          } else if (["application/zip"].includes(getMimetype(hex))) {
            if (!file.name.endsWith(".zip")) {
              this.loadingStatus = false;
              // this.$refs.uploadComp.fileList.splice(0);
              // this.$refs.uploadComp.fileList = [];
              this.$Notice.warning({
                title: "文件内容与文件的后缀不一致"
                // desc: file.name + " 文件是zip压缩包，但文件名后缀不是.zip！"
              });
              this.file = null;
              reject("文件内容与文件的后缀不一致，请确认文件是zip压缩包！");
            } else {
              resolve();
            }
          } else {
            console.log("binary file type check: not zip or pdf");
            window._hmt.push([
              "_trackEvent",
              "离线考试页面",
              "上传作答",
              "文件格式非zip或pdf"
            ]);
            this.$Notice.warning({
              title: "作答文件损坏",
              desc:
                file.name +
                " 文件无法以 " +
                this.uploadFileFormat.join(" 或 ") +
                " 格式读取。"
            });
            this.file = null;
            this.loadingStatus = false;
            reject("作答文件损坏");
          }
        }
      };
      const blob = file.slice(0, 4);
      filereader.readAsArrayBuffer(blob);
    },
    handleSuccess() {
      window._hmt.push(["_trackEvent", "离线考试页面", "上传作答", "上传成功"]);
      this.file = null;
      this.loadingStatus = false;
      this.$Message.success({
        content: "上传成功",
        duration: 5,
        closable: true
      });
      this.$emit("reloadList");
    },
    handleError() {
      window._hmt.push(["_trackEvent", "离线考试页面", "上传作答", "上传失败"]);
      this.file = null;
      this.loadingStatus = false;
      this.$Message.error({
        content: "上传失败",
        duration: 15,
        closable: true
      });
    },
    handleFormatError(file) {
      this.file = null;
      this.loadingStatus = false;
      this.$Notice.warning({
        title: "作答文件格式不对",
        desc:
          file.name +
          " 文件格式不对，请选择 " +
          this.uploadFileFormat.join(" 或 ") +
          "  文件。"
      });
    },
    handleMaxSize(file) {
      this.file = null;
      this.loadingStatus = false;
      this.$Notice.warning({
        title: "超出文件大小限制",
        desc: file.name + " 太大，作答文件不能超过30M."
      });
    },
    handleBeforeUpload(file) {
      if (file.type.includes("/pdf")) {
        this.fileType = "pdf";
      } else if (file.type.includes("/zip")) {
        this.fileType = "zip";
      }
      this.file = file;
      this.loadingStatus = true;
      return new Promise((resolve, reject) =>
        this.fileFormatCheck(file, resolve, reject)
      );
    }
  }
};
</script>

<style lang="postcss">
.list .ivu-upload-select {
  width: 100%;
}
</style>
