<template>
  <div class="main">
    <div class="head">
      <div class="zoom">
        <button @click="() => zoomIn()">缩小</button>
        <button @click="() => zoomOut()">放大</button>
      </div>
      <div class="pagnaition">
        <button @click.stop="preventPage" :disabled="currValue === 1">
          上一页
        </button>
        <input type="text" v-model="currValue" @change="numChange" />
        /&nbsp;&nbsp;{{ allPage }}
        <button @click.stop="nextPage" :disabled="currValue === allPage">
          下一页
        </button>
        <button @click="() => rotate()">旋转</button>
        <button @click="() => doublePage()">双页模式</button>
      </div>
    </div>
    <div class="content">
      <div id="pageContainer">
        <div id="viewer" class="pdfViewer"></div>
      </div>
    </div>

    <contextmenu
      class="right-menu"
      :target="contextMenuTarget"
      :show="contextMenuVisible"
      @update:show="(show) => (contextMenuVisible = show)"
    >
      <ul>
        <li v-for="o in eventList" :key="o.name">
          <button @click.stop="o.event">
            <img :src="o.icon" width="12" alt="" />
            {{ o.name }}
          </button>
        </li>
      </ul>
    </contextmenu>
  </div>
</template>

<script>
import contextmenu from "./VueContextMenu.vue";
import { PdfAnnotation } from "./util";
import underlineIcon from "./icon/underline.svg";
import copyIcon from "./icon/copy.svg";
import noteIcon from "./icon/note.svg";
import highlightIcon from "./icon/hign.svg";
import strikeOutIcon from "./icon/se.svg";
import { showMagBox } from "./message/index";

pdfjsLib.GlobalWorkerOptions.workerSrc = "/pdf.worker.js";

let _pdfViewer = null;
let pdfAnno = null;

export default {
  name: "PDFAnnot",
  props: {
    url: { type: String, require: true },
    annots: {
      type: Array,
      default: () => [],
    },
    underlineColor: {
      type: [String, Array],
      default: () => [255, 0, 0],
    },
    strikeOutColor: {
      type: [String, Array],
      default: () => [255, 0, 0],
    },
    highlightColor: {
      type: [String, Array],
      default: () => [255, 255, 0],
    },
    contextmenuList: {
      type: [Array],
      default: () => [],
    },
  },
  components: {
    contextmenu,
  },
  emits: ["annotChange", "copy", "addNote", "ready"],
  data() {
    return {
      contextMenuTarget: null,
      contextMenuVisible: false,
      currValue: 1,
      allPage: 0,
    };
  },

  mounted() {
    const container = document.getElementById("pageContainer");
    this.contextMenuTarget = container;
    container.addEventListener("mousewheel", this.handleScroll, {
      passive: false,
    });
    this.initPdf();
  },
  methods: {
    handleScroll(e) {
      // 判断是不是按下ctrl键
      if (e.ctrlKey) {
        // 取消浏览器默认的放大缩小网页行为
        e.preventDefault();
        // 判断是向上滚动还是向下滚动

        if (e.deltaY > 0) {
          this.zoomIn(0.1);
          // 放大重写，业务代码
        } else {
          this.zoomOut(0.1);
          // 缩小重写，业务代码
        }
      }
    },
    copy() {
      const text = document.getSelection().toString();
      navigator.clipboard
        .writeText(text)
        .then(() => {
          showMagBox({
            type: "info",
            msg: "复制成功",
          });
          this.closeMenu();
          this.$emit("copy", text);
        })
        .catch((err) => {
          console.log("无法复制文本: ", err);
        });
    },
    addNote() {
      this.closeMenu();
      pdfAnno
        .note({
          subtype: "Underline",
          color: this.strikeOutColor,
        })
        .then((annots) => {
          this.$emit("addNote", annots);
        });
    },
    renderAnnots(annots) {
      pdfAnno.addAnnots(annots);
    },
    async initPdf() {
      // 加载pdf文件
      const loadingTask = pdfjsLib.getDocument(this.url);
      // 生成文档
      const pdf = await loadingTask.promise;
      const container = document.getElementById("pageContainer");

      const eventBus = new pdfjsViewer.EventBus();
      const pdfViewer = new pdfjsViewer.PDFViewer({
        container: container,
        eventBus: eventBus,
        annotationMode: 1,
        textLayerMode: 1,
        annotationEditorMode: -1,
      });

      // 开始绘制到dom
      pdfViewer.setDocument(pdf);
      pdfViewer.onePageRendered.then((t) => {
        _pdfViewer.currentScaleValue = 1.2;
        this.currValue = pdfViewer._currentPageNumber;
        this.allPage = pdf.numPages;
        this.renderAnnots(this.annots);
        this.$emit("ready", {
          PdfAnnots: pdfAnno,
          zoomIn: this.zoomIn,
          rotate: this.rotate,
          doublePage: this.doublePage,
          switchPage: this.switchPage,
          renderAnnots: this.renderAnnots,
        });
      });

      // _pdf = pdf;
      _pdfViewer = pdfViewer;

      pdfAnno = new PdfAnnotation({
        pdfViewer: pdfViewer,
        pdfJs: pdf,
        // Annot: [],
      });
    },
    zoomOut(scale = 0.2) {
      if (_pdfViewer.currentScale < 3) {
        _pdfViewer.currentScaleValue = _pdfViewer.currentScale + scale;
      }
    },
    zoomIn(scale = 0.2) {
      if (_pdfViewer.currentScaleValue > 0.6) {
        _pdfViewer.currentScaleValue -= scale;
      }
    },
    rotate() {
      _pdfViewer.pagesRotation += 90;
    },
    doublePage() {
      _pdfViewer.spreadMode = 1;
    },
    closeMenu() {
      this.contextMenuVisible = false;
    },
    Underline() {
      this.closeMenu();
      pdfAnno
        .setAnno({
          subtype: "Underline",
          color: this.underlineColor,
        })
        .then((annots) => {
          console.log(annots);
          this.$emit("annotChange", annots);
        });
    },
    StrikeOut() {
      this.closeMenu();
      pdfAnno
        .setAnno({
          subtype: "StrikeOut",
          color: this.strikeOutColor,
        })
        .then((annots) => {
          this.$emit("annotChange", annots);
        });
    },
    highlight() {
      this.closeMenu();
      pdfAnno
        .setAnno({
          subtype: "Highlight",
          color: this.highlightColor,
        })
        .then((annots) => {
          this.$emit("annotChange", annots);
        });
    },
    numChange(e) {
      const page = +e.target.value;
      _pdfViewer.currentPageNumber = page;
    },
    switchPage(page) {
      _pdfViewer.currentPageNumber = page;
      this.currValue = page;
    },
    preventPage() {
      if (this.currValue > 0) {
        this.currValue -= 1;
        _pdfViewer.previousPage();
      }
    },
    nextPage() {
      if (this.currValue < this.allPage) {
        this.currValue += 1;
        _pdfViewer.nextPage();
      }
    },
  },
  computed: {
    eventList: function () {
      return [
        {
          name: "复制",
          icon: copyIcon,
          event: this.copy,
        },
        {
          name: "添加笔记",
          icon: noteIcon,
          event: this.addNote,
        },
        {
          name: "下划线",
          icon: underlineIcon,
          event: this.Underline,
        },
        {
          name: "高亮",
          icon: highlightIcon,
          event: this.highlight,
        },
        {
          name: "删除线",
          icon: strikeOutIcon,
          event: this.StrikeOut,
        },
        ...this.contextmenuList,
      ];
    },
  },
};
</script>

<style scoped>
#pageContainer {
  position: absolute;
  margin: auto;
  width: 100%;
  height: 100%;
  overflow-y: auto;
}
.content {
  position: relative;
  width: 100%;
  flex: 1;

  overflow-y: auto;
}
.head {
  padding: 10px;
  border-bottom: 1px solid #eee;
  display: flex;
  justify-content: center;
}
.pagnaition button,
.zoom button {
  margin: 0 10px;
}
.pagnaition input {
  width: 25px;
  height: 25px;
  margin-right: 5px;
}
.main {
  height: 90vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.pdfViewer {
  background: #666;
  box-sizing: border-box;
  position: relative;
  padding-top: 10px;
}
div.page {
  display: inline-block;
}

.right-menu {
  position: fixed;
  background: #fff;
  border: solid 1px rgba(0, 0, 0, 0.2);
  border-radius: 3px;
  z-index: 999;
  display: none;
}
.right-menu ul,
.right-menu li {
  list-style: none;
  margin: 0;
  padding: 0;
}
.right-menu ul {
  display: flex;
  flex-direction: column;
}
.right-menu li {
  display: inline-block;

  font-size: 14px;
}
li button {
  border: unset;
  background: unset;
  width: 100%;
  padding: 5px 20px;
  text-align: left;
  cursor: pointer;
}
.right-menu li:not(:last-child) {
  border-bottom: 1px solid #eee;
}
</style>
<style>
.pdfViewer .page {
  border: none;
}
</style>
