<template>
  <div class="compareItem" v-loading="loading">
    <div class="title">{{ article.name }}</div>
    <ul class="tool-bar">
      <li title="目录" @click="toolbarClick(1)">
        <i class="el-icon-tickets" />
      </li>
      <li title="笔记" @click="toolbarClick(2)">
        <i class="el-icon-notebook-1" />
      </li>
    </ul>
    <!-- <html-content v-if="article.showType !== 'pdf'" @complete="complete" :id="id" @loading="setLoading($event)"
                  :detail="htmlContent"/> -->
    <!-- <readPdf v-else :article="article"/> -->
    <readPdf :article="article" />

    <el-dialog
      width="50vw"
      :modal="false"
      :append-to-body="true"
      :visible.sync="catalogueFlag"
      :class="id === 'detailLeft' ? 'catalogueOriginal' : 'catalogueCompare'"
    >
      <catalogue :catalogue="catalogue" @titleClick="titleClick($event)" />
    </el-dialog>

    <!--添加笔记窗口-->
    <note-window
      :dialogVisible="dialogVisible"
      @addNode="addNode"
      v-if="dialogVisible"
    />
  </div>
</template>

<script>
import { addOrUpdate, getBookMark, removeMark } from "@/api/doc/bookMark";
import { catlog, detail } from "@/api/doc/index";
import EasyMarker from "easy-marker";
// import Mark from "../../../node_modules/mark.js/dist/mark";

export default {
  name: "compareItem",
  props: ["article", "id", "compareWindowFlag"],
  components: {
    // htmlContent: () => import('./htmlContent'),
    catalogue: () => import("./catalogue"),
    noteWindow: () => import("./noteWindow"),
    readPdf: () => import("./readPdf"),
  },
  data() {
    return {
      dialogVisible: false,
      loading: false,
      catalogue: [],
      catalogueFlag: false,
      htmlContent: undefined,
      notes: [],
      markIndex: 0,
      node: {
        flag: true, // 判断是否是新增笔记
        text: "",
        keyword: "",
        anchorOffset: "",
        id: undefined,
        icon: "note",
      },
    };
  },
  watch: {
    compareWindowFlag(c, o) {
      if (c) {
        this.getNotes();
        this.getContent();
      }
    },
  },
  methods: {
    addNode() {
      let keyword = this.node.keyword;
      let anchorOffset = this.node.anchorOffset;
      let id = this.node.id;
      let index = 0;
      this.markList.forEach((item, i) => {
        if (item.id === id) {
          index = i;
        }
      });
      if (this.node.flag) {
        this.setNode(keyword, anchorOffset, id);
      } else {
        let formData = new FormData();
        formData.append("id", this.markList[index].uid);
        formData.append("noteContent", this.node.text);
        addOrUpdate(formData).then((res) => {
          if (res.code === 200) {
            this.markList[index].detail[0].value = this.node.text;
            this.$message.success("修改成功！");
          }
        });
      }
      this.dialogVisible = false;
    },
    setLoading(e) {
      this.loading = e;
    },
    toolbarClick(e) {
      //1:目录，2：笔记
      if (e === 1) {
        this.catalogueFlag = true;
        this.setCatalogue();
      } else {
      }
    },
    setCatalogue() {
      if (this.catalogue.length !== 0) {
        return;
      }
      let p = {
        id: this.article.id,
      };
      catlog(p).then((res) => {
        if (res.code === 200) {
          this.catalogue = res.result.catalog;
        }
      });
    },
    complete() {
      this.playLine();
      this.markInit();
    },
    playLine() {
      let root = this;
      let em = new EasyMarker({
        menuTopOffset: "0.12rem",
        scrollSpeedLevel: 1,
        scrollOffsetBottom: "1.5rem",
        mask: {
          color: "#407ff2",
          // color: 'transparent'
        },
        highlight: {
          color: "red",
        },
        menuStyle: {
          menu: {
            backgroundColor: "#545454",
            padding: "0px 0.05rem",
            borderRadius: "0.05rem",
          },
          item: {
            fontSize: "15px",
            padding: "0px 10px",
            lineHeight: "30px",
            backgroundColor: "#545454",
            cursor: "pointer",
          },
          triangle: {
            borderTop: "0.1rem solid rgb(84 84 84)",
          },
        },
        menuItems: [
          {
            text: "划线",
            id: "1",
          },
          {
            text: "高亮",
            id: "2",
          },
          {
            text: "笔记",
            id: "3",
          },
          {
            text: "复制",
            id: "4",
          },
        ],
      });
      em.onMenuClick(function (id, data) {
        if (root.$store.state.currentUser === null) {
          root.$message.error("用户未登录或者登录过期，请重新登录！");
          return;
        }
        let keyword = data.anchorNode.textContent.slice(
          data.anchorOffset,
          data.focusOffset
        );
        let index = 0;
        if (data.anchorNode.parentNode.childNodes.length === 1) {
          index = 0;
        } else {
          for (
            let i = 0;
            i < data.anchorNode.parentNode.childNodes.length;
            i++
          ) {
            let item = data.anchorNode.parentNode.childNodes[i];
            if (item.textContent === data.anchorNode.textContent) {
              break;
            }
            index += item.textContent.length;
          }
        }
        if (id === "1") {
          root.setUnderine(
            keyword,
            data.anchorOffset + index,
            data.anchorNode.parentElement.getAttribute("id")
          );
        } else if (id === "2") {
          root.setHighlight(
            keyword,
            data.anchorOffset + index,
            data.anchorNode.parentElement.getAttribute("id")
          );
        } else if (id === "3") {
          root.node.anchorOffset = data.anchorOffset + index;
          root.node.keyword = keyword;
          root.node.id = data.anchorNode.parentElement.getAttribute("id");
          root.node.text = "";
          root.dialogVisible = true;
        } else if (id === "4") {
          const input = document.createElement("INPUT");
          input.style.opacity = "0";
          input.style.position = "absolute";
          document.body.appendChild(input);
          if (data.anchorNode === data.focusNode) {
            input.value = keyword;
          } else {
            input.value =
              data.anchorNode.textContent.slice(data.anchorOffset) +
              data.focusNode.textContent.slice(0, data.focusOffset);
          }
          input.select();
          if (root.flag) {
            root.flag = false;
            document.execCommand("copy");
            document.body.removeChild(input);
            root.$message.success("复制成功");
          }
        } else {
          root.$message.success("纠错");
        }
      });
      em.onSelectStatusChange((val) => {
        if (val === "finish") {
          root.flag = true;
        }
      });
      em.create(document.querySelector("#" + this.id), null);
      document.getElementById(this.id).setAttribute("style", "");
      document.querySelector("#" + this.id).onclick = (e) => {
        let points = document
          .querySelector("#" + this.id + " svg")
          .children[0].getAttribute("points");
        let style = document
          .querySelector("#" + this.id + " svg")
          .getAttribute("style");
        if (points !== "") {
          document
            .querySelector("#" + this.id + " svg")
            .setAttribute("style", style.replace(/display:none;/g, ""));
        } else {
          document
            .querySelector("#" + this.id + " svg")
            .setAttribute("style", style + "display:none;");
        }
      };
    },
    markInit() {
      this.notes.forEach((item) => {
        item.detail.forEach((target) => {
          if (target.icon === "underline") {
            this.setUnderine(
              target.value,
              parseInt(item.anchorOffset),
              item.nodeId,
              false
            );
          } else if (target.icon === "highlight") {
            this.setHighlight(
              target.value,
              parseInt(item.anchorOffset),
              item.nodeId,
              false
            );
          } else if (target.icon === "read") {
            this.setNode(
              target.value,
              parseInt(item.anchorOffset),
              item.nodeId,
              false
            );
          }
        });
      });
    },
    titleClick(e) {
      this.catalogueFlag = false;
      let dom = document.getElementById(this.id);
      for (let i = 0; i < dom.children.length; i++) {
        if (this.id === "detailLeft") {
          this.getScrollTop(
            dom.children[i],
            e.title,
            document.querySelector(".left")
          );
        } else {
          this.getScrollTop(
            dom.children[i],
            e.title,
            document.querySelector(".right")
          );
        }
      }
    },
    getScrollTop(e, t, d) {
      if (e.children.length > 0) {
        for (let i = 0; i < e.children.length; i++) {
          let dom = e.children[i];
          this.getScrollTop(dom, t, d);
        }
      } else {
        if (e.innerText === t) {
          if (e.offsetTop === 0) {
            d.scrollTop = e.parentElement.offsetTop + 120;
          } else {
            d.scrollTop = e.offsetTop + 120;
          }
        }
      }
    },
    async getNotes() {
      this.notes = [];
      let p = {
        docId: this.article.id,
        docSType: this.article.docSType,
      };

      await getBookMark(p).then((res) => {
        if (res.code === 200) {
          let result = this.NotesListFormater(res.result.data);
          this.notes = result;
        } else {
          this.$message.error(res.message);
        }
      });
    },
    NotesListFormater(e) {
      let result = [];
      e.forEach((item, i) => {
        let detail = [];
        if (item.type === "underline") {
          detail = [
            {
              key: "下划线",
              value: item.bookmarkContent,
              icon: "underline",
            },
          ];
        } else if (item.type === "highlight") {
          detail = [
            {
              key: "高亮",
              value: item.bookmarkContent,
              icon: "highlight",
            },
          ];
        } else {
          detail = [
            {
              key: "笔记",
              value: item.noteContent,
              icon: "note",
            },
            {
              key: "原文",
              value: item.bookmarkContent,
              icon: "read",
            },
          ];
        }
        let model = {
          id: "mark" + i,
          userName: this.$store.state.currentUser.userInfo.username,
          time: item.updateTime,
          anchorOffset: item.offset,
          nodeId: item.sectionId,
          detail: detail,
          uid: item.id,
        };
        result.push(model);
      });
      return result;
    },
    getOption(className, anchorOffset, node) {
      let root = this;
      let options = {
        node: node,
        anchorOffset: anchorOffset,
        element: "marker",
        className: className,
        exclude: [],
        separateWordSearch: false,
        accuracy: "partially",
        diacritics: true,
        synonyms: {},
        iframes: false,
        iframesTimeout: 5000,
        acrossElements: false,
        caseSensitive: false,
        ignoreJoiners: false,
        ignorePunctuation: [],
        wildcards: "disabled",
        each: (e) => {
          let index = "mark" + root.markIndex++;
          e.setAttribute("id", index);

          let icon = document.createElement("mycon");
          if (className !== "marknode") {
            icon.setAttribute("class", "note-co-o");
            e.addEventListener("click", (e) => {
              root.iconClick(e);
            });
          } else {
            icon.setAttribute("class", "note-co-b");
          }
          e.setAttribute("style", "cursor:pointer");
          e.addEventListener("mouseover", (e) => {
            root.markMouseOver(e);
          });
          icon.setAttribute("name", index);
          icon.addEventListener("click", (e) => {
            root.iconClick(e);
          });
          let parent = e.parentNode;
          if (parent.lastChild === e) {
            // 如果最后的节点是目标元素，则直接添加。因为默认是最后
            parent.appendChild(icon);
          } else {
            // 如果不是，则插入在目标元素的下一个兄弟节点 的前面。也就是目标元素的后面
            parent.insertBefore(icon, e.nextSibling);
          }
        },
        filter: function (textNode, foundTerm, totalCounter, counter) {
          let current = root.findStr(
            this.node.textContent,
            foundTerm.toString(),
            ++this.index
          );
          if (current === this.anchorOffset) {
            if (textNode.parentNode.localName === "marker") {
              return false;
            }
            return true; // must return either true or false
          } else {
            return false;
          }
        },
        noMatch: function (term) {
          // term is the not found term
        },
        done: function (counter) {},
        debug: false,
        log: window.console,
      };
      return options;
    },
    markMouseOver(e) {
      let target = e.currentTarget.getAttribute("id");

      let menuBg = document.createElement("div");
      let item = document.createElement("div");

      if (e.isTrusted && e.currentTarget.getAttribute("class") === "marknode") {
        menuBg.innerHTML = this.notes.find(
          (n) => n.id === target
        ).detail[0].value;
        menuBg.appendChild(item);
        menuBg.style.width = "160px";
        menuBg.style.left =
          (e.target.offsetLeft + e.target.offsetWidth / 2) * 0.01 + "rem";
        menuBg.style.top = (e.target.offsetTop - 6) * 0.01 + "rem";
        menuBg.id = "tooltip";
        document.getElementById(this.id).appendChild(menuBg);
        e.stopPropagation();
      }
      e.target.onmouseleave = (a) => {
        if (a.isTrusted) {
          let dom = document.getElementById("tooltip");
          if (dom !== null) {
            dom.remove();
            document.onclick = null;
          }
        }
      };
    },
    iconClick(e) {
      if (e.isTrusted) {
        let dom = document.getElementById("menu");
        if (dom !== null) {
          dom.remove();
          document.onclick = null;
        }
        let root = this;
        let target =
          e.currentTarget.getAttribute("name") === null
            ? e.currentTarget.getAttribute("id")
            : e.currentTarget.getAttribute("name");
        let menuBg = document.createElement("div");
        let menu = document.createElement("div");
        let bg = document.createElement("div");
        let item = document.createElement("span");
        let height = 0;
        if (this.id === "detailLeft") {
          height = document.getElementsByClassName("left")[0].scrollTop;
        } else {
          height = document.getElementsByClassName("right")[0].scrollTop;
        }
        item.innerText = "删除";
        item.addEventListener("click", (p) => {
          if (p.isTrusted) {
            let targetMenu = p.currentTarget.parentElement.parentElement;
            root
              .$confirm("此操作将永久删除该记录, 是否继续?", "提示", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
              })
              .then(() => {
                targetMenu.remove();
                root.removeMark(target);
              })
              .catch(() => {
                this.$message({
                  type: "info",
                  message: "已取消删除",
                });
              });
          }
        });
        menu.appendChild(item);
        let left = 96;
        let offsetLetf = 14;
        let top = 110;
        let offsetTop = 28;
        menu.style.left = (e.clientX - left - offsetLetf) * 0.01 + "rem";
        menu.style.top = (e.clientY - top - offsetTop + height) * 0.01 + "rem";
        bg.style.left = (e.clientX - left) * 0.01 + "rem";
        bg.style.top = (e.clientY - top + height) * 0.01 + "rem";
        menuBg.id = "menu";
        menuBg.appendChild(menu);
        menuBg.appendChild(bg);
        document.getElementById(this.id).appendChild(menuBg);
        e.stopPropagation();
        document.onclick = (a) => {
          if (a.isTrusted) {
            let dom = document.getElementById("menu");
            if (dom !== null) {
              dom.remove();
              document.onclick = null;
            }
          }
        };
      }
    },
    removeMark(e) {
      let target = undefined;
      let index = 0;
      for (let i = 0; i < this.notes.length; i++) {
        let item = this.notes[i];
        if (item.id === e) {
          index = i;
          target = item;
          break;
        }
      }
      let formData = new FormData();
      formData.append("id", target.uid);
      removeMark(formData).then((res) => {
        if (res.code === 200) {
          this.notes.splice(index, 1);
          let node = document.getElementById(e);
          // let instance = new Mark(node);
          document.getElementsByName(e)[0].remove();
          instance.unmark();
          this.$message.success("删除成功！");
        }
      });
    },
    async setHighlight(keyword, anchorOffset, id, flag = true) {
      if (flag && id.indexOf("mark") === -1) {
        await this.addMarkList(keyword, anchorOffset, id, "highlight");
      } else if (flag && id.indexOf("mark") !== -1) {
        this.$message.error("不能重复操作");
      }
      let dom = document.querySelector("#" + this.id + " #" + id);
      // let instance = new Mark(dom);
      instance.mark(
        keyword,
        this.getOption("markhigh", parseInt(anchorOffset), dom)
      );
    },
    async setUnderine(keyword, anchorOffset, id, flag = true) {
      if (flag && id.indexOf("mark") === -1) {
        await this.addMarkList(keyword, anchorOffset, id, "underline");
      } else if (flag && id.indexOf("mark") !== -1) {
        this.$message.error("不能重复操作");
      }
      let dom = document.querySelector("#" + this.id + " #" + id);
      // let instance = new Mark(dom);
      instance.mark(
        keyword,
        this.getOption("markline", parseInt(anchorOffset), dom)
      );
    },
    async setNode(keyword, anchorOffset, id, flag = true) {
      if (flag && id.indexOf("mark") === -1) {
        await this.addMarkList(keyword, anchorOffset, id, "note");
      } else if (flag && id.indexOf("mark") !== -1) {
        this.$message.error("不能重复操作");
      }
      let dom = document.querySelector("#" + this.id + " #" + id);
      // let instance = new Mark(dom);
      instance.mark(
        keyword,
        this.getOption("marknode", parseInt(anchorOffset), dom)
      );
    },
    async addMarkList(keyword, anchorOffset, id, icon) {
      let details = {};
      let model = {};
      model.id = "mark" + this.markIndex;
      model.userName = this.$store.state.currentUser.userInfo.username;
      model.time = new Date().toLocaleString();
      model.anchorOffset = anchorOffset;
      model.nodeId = id;
      model.detail = [];

      let formData = new FormData();
      formData.append("bookmarkContent", keyword);
      formData.append("docId", this.article.id);
      formData.append("noteContent", this.node.text);
      formData.append("docSType", this.article.docSType);
      formData.append("offset", anchorOffset);
      formData.append("sectionId", id);
      formData.append("type", icon);
      await addOrUpdate(formData).then((res) => {
        if (res.code === 200) {
          if (icon !== "note") {
            details.key = icon === "underline" ? "下划线" : "高亮";
            details.value = keyword;
            details.icon = icon;
            model.detail.push(details);
          } else {
            details.key = "笔记";
            details.value = this.node.text;
            details.icon = icon;
            model.detail.push(details);
            let target = {};
            target.key = "原文";
            target.value = keyword;
            target.icon = "read";
            model.detail.push(target);
          }
          model.uid = res.result;
          model.id = "mark" + this.markIndex;
          this.notes.push(model);
          this.$message.success("笔记添加成功！");
        } else {
          this.$message.error(res.message);
        }
      });
    },
    getContent() {
      let p = {
        docId: this.article.id,
        docSType: this.article.docSType,
      };
      detail(p).then((res) => {
        if (res?.code === 200) {
          this.htmlContent = res;
        }
      });
    },
    findStr(str, cha, num) {
      let times = num === 0 ? 1 : num;
      let x = str.indexOf(cha);
      for (let i = 0; i < times - 1; i++) {
        x = str.indexOf(cha, x + 1);
      }
      return x;
    },
  },
  async mounted() {
    await this.getNotes();
    this.getContent();
  },
};
</script>

<style lang="scss">
.catalogueOriginal {
  width: 46vw !important;
  margin-left: 62px !important;
  overflow: hidden;

  .el-dialog {
    width: 44vw !important;
    height: 600px !important;
    box-shadow: 0 0 8px 1px !important;
    overflow: auto;
  }

  .el-row--flex {
    display: block !important;
    width: 100% !important;
    font-size: 20px !important;
  }

  .el-tree-node {
    margin-bottom: 8px !important;
  }

  .el-tree--highlight-current {
    width: 100% !important;
  }
}

.catalogueCompare {
  z-index: 0 !important;
  width: 46vw !important;
  margin-left: 1012px !important;
  overflow: hidden;

  .el-dialog {
    width: 44vw !important;
    height: 600px !important;
    box-shadow: 0 0 8px 1px !important;
    overflow-y: auto;
  }
}
</style>

<style lang="scss" scoped>
.compareItem {
  & > .title {
    padding-top: 20px;
    text-align: center;
    font-size: 30px;
    font-weight: bold;
    font-family: cursive;
  }

  & > .tool-bar {
    margin-top: 50px;
    position: absolute;

    & > li {
      transition: all 0.5s ease;
      cursor: pointer;
      background-color: #2eb4ff;
      display: block;

      & > i {
        color: #ffffff;
        border: 1px solid #004b71;
        font-size: 26px;
        padding: 10px;
      }
    }

    & > li:hover {
      background-color: #0085cd;
    }

    & > li:first-child {
      border-top-right-radius: 6px;

      & > i:first-child {
        border-top-right-radius: 6px;
      }
    }

    & > li:last-child {
      border-bottom-right-radius: 6px;

      & > i:last-child {
        border-bottom-right-radius: 6px;
      }
    }
  }
}
</style>
