<template>
  <div>
    <Upload
      ref="uploadComp"
      :headers="headers"
      :data="{ fileType: fileType }"
      :before-upload="handleBeforeUpload"
      :action="
        '/api/branch_ecs_oe_admin/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>
    <Modal v-model="showPreview" fullscreen footer-hide :closable="false">
      <!-- <div slot="header"></div> -->
      <img :id="previewId" class="preview-image" />
    </Modal>
  </div>
</template>

<script>
import { printCurrentPage } from "./imageToPdf";

export default {
  name: "EcsOfflineUploadCug",
  props: {
    course: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    return {
      headers: {
        token: window.sessionStorage.getItem("token"),
        key: window.localStorage.getItem("key"),
      },
      file: null,
      fileType: null,
      loadingStatus: false,
      uploadFileFormat: [],
      uploadFileAccept: "",
      // imageSrc
      previewImage: null,
      showPreview: false,
      previewId: "previewId" + Date.now(),
    };
  },
  async created() {
    const res = await this.$http.get(
      "/api/ecs_exam_work/exam/getExamPropertyFromCacheByStudentSession/" +
        this.course.examId +
        `/OFFLINE_UPLOAD_FILE_TYPE`
    );

    this.uploadFileFormat =
      (res.data.OFFLINE_UPLOAD_FILE_TYPE &&
        JSON.parse(res.data.OFFLINE_UPLOAD_FILE_TYPE)) ||
      [];
    this.uploadFileAccept =
      "image/jpeg," +
      this.uploadFileFormat.map((v) => "application/" + v.toLowerCase()).join();
    if (this.uploadFileAccept.includes("zip")) {
      this.uploadFileAccept = ".zip," + this.uploadFileAccept;
    }
    this.uploadFileFormat.push(...["jpeg", "jpg"]);
    this.uploadFileFormat = this.uploadFileFormat.map((v) => v.toLowerCase());
  },
  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";
        }
      }
      console.log(file);

      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 if (["image/jpeg"].includes(getMimetype(hex))) {
            if (file.name.endsWith(".jpeg") || file.name.endsWith(".jpg")) {
              printCurrentPage()
                .then((filename) => {
                  // const fs = nodeRequire("fs");
                  const path = window.nodeRequire("path");
                  const fileNew = {
                    name: path.basename(filename),
                    path: filename,
                    type: "application/pdf",
                    // lastModified
                    // lastModifiedDate
                    // size
                  };
                  this.file = fileNew;
                  file = fileNew;
                  // console.log(this.$refs.uploadComp.fileList);
                  // this.$refs.uploadComp.fileList = [file];
                  // console.log(this.$refs.uploadComp.fileList);
                  resolve();
                })
                .catch(() => {
                  reject();
                });
            } else {
              this.loadingStatus = false;
              // this.$refs.uploadComp.fileList.splice(0);
              // this.$refs.uploadComp.fileList = [];
              this.$Notice.warning({
                title: "文件内容与文件的后缀不一致",
              });
              this.file = null;
              reject("文件内容与文件的后缀不一致，请确认文件是jpg文件！");
            }
          } 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");
      this.showPreview = false;
    },
    handleError(error, file) {
      window._hmt.push(["_trackEvent", "离线考试页面", "上传作答", "上传失败"]);
      this.file = null;
      this.loadingStatus = false;
      console.log(error);
      this.$Message.error({
        content: (file && file.desc) || "上传失败",
        duration: 15,
        closable: true,
      });
      this.showPreview = false;
    },
    handleFormatError(file) {
      this.file = null;
      this.loadingStatus = false;
      this.$Notice.warning({
        title: "作答文件格式不对",
        desc:
          file.name +
          " 文件格式不对，请选择 " +
          this.uploadFileFormat.join(" 或 ") +
          "  文件。",
      });
      this.showPreview = false;
    },
    handleMaxSize(file) {
      this.file = null;
      this.loadingStatus = false;
      this.$Notice.warning({
        title: "超出文件大小限制",
        desc: file.name + " 太大，作答文件不能超过30M.",
      });
      this.showPreview = false;
    },
    async handleBeforeUpload(file) {
      const suffix = file.name.split(".").pop();
      if (suffix.toLowerCase() !== suffix) {
        this.$Notice.error({
          title: "文件名后缀必须是小写",
          desc: file.name + " 文件名后缀必须是小写。",
        });
        return Promise.reject("file suffix should be lower case");
      }
      if (file.name.endsWith(".jpeg") || file.name.endsWith(".jpg")) {
        new Promise((resolve, reject) => {
          if (this.course.offlineFileUrl) {
            this.$Modal.confirm({
              title: "已有作答附件，是否覆盖？",
              onCancel: () => reject("离线考试，取消覆盖"),
              onOk: () => resolve(),
            });
          } else {
            resolve();
          }
        })
          .then(() => {
            this.showPreview = true;
            this.$Message.info({
              content: "正在准备将图片转为PDF...",
              duration: 1.5,
              closable: true,
            });

            return new Promise((resolve) => {
              var reader = new FileReader();
              reader.onload = (e) => {
                document
                  .getElementById(this.previewId)
                  .setAttribute("src", e.target.result);

                setTimeout(resolve, 2500);
                // resolve();
              };
              //Imagepath.files[0] is blob type
              reader.readAsDataURL(file);
            });
          })
          .then(() => {
            // return;
            return printCurrentPage()
              .then((filename) => {
                const fs = window.nodeRequire("fs");
                const path = window.nodeRequire("path");
                // const fileNew = {
                //   name: path.basename(filename),
                //   // filename: path.basename(filename),
                //   uri: "file://" + filename,
                //   // path: filename,
                //   type: "application/pdf",
                // };
                const fileNew = new File(
                  [fs.readFileSync(filename)],
                  path.basename(filename),
                  { type: "application/pdf" } // what I upload is image.
                );
                this.file = fileNew;

                this.$Message.info({
                  content: "图片转换成功，正在上传...",
                  duration: 2,
                  closable: true,
                });

                var stats = fs.statSync(filename);
                var fileSizeInBytes = stats["size"];
                if (fileSizeInBytes > 1024 * 30 * 1024) {
                  this.handleMaxSize();
                  throw new Error("附件超过最大限制");
                }

                const formData = new FormData();
                formData.append("fileType", "pdf");
                formData.append("file", fileNew);

                return this.$http
                  .post(
                    "/api/branch_ecs_oe_admin/offlineExam/submitPaper?examRecordDataId=" +
                      this.course.examRecordDataId,
                    formData
                  )
                  .then(() => {
                    this.handleSuccess();
                  })
                  .catch(() => {
                    this.handleError();
                  });
              })
              .catch((error) => {
                console.log(error);
                this.handleError();
              });
          });
        return Promise.reject("图片另外路径上传");
      }

      return new Promise((resolve, reject) => {
        if (this.course.offlineFileUrl) {
          this.$Modal.confirm({
            title: "已有作答附件，是否覆盖？",
            onCancel: () => reject("离线考试，取消覆盖"),
            onOk: () => resolve(),
          });
        } else {
          resolve();
        }
      }).then(() => {
        if (
          file.type.includes("/pdf")
          //  ||
          // file.type.includes("/jpeg") ||
          // file.type.includes("/jpg")
        ) {
          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 scoped>
.list .ivu-upload-select {
  width: 100%;
}
.preview-image {
  max-width: 100vw;
  max-height: 100vh;
  margin: -16px;
  object-fit: contain;
}
</style>
