<template>
  <div class="main">
    <div class="head">
      <div class="zoom">
        <el-button type="info" plain @click="() => zoomIn()" icon="ZoomOut"
          >缩小</el-button
        >
        <el-button type="info" plain @click="() => zoomOut()" icon="ZoomIn"
          >放大</el-button
        >
      </div>
      <div class="pagnaition">
        <el-button
          type="info"
          plain
          @click.stop="preventPage"
          :disabled="currValue === 1"
          icon="ArrowLeft"
          >上一页</el-button
        >
        <el-input
          type="text"
          v-model="currValue"
          @change="numChange"
          style="width: 50px"
        />
        /&nbsp;&nbsp;
        <el-text size="large">{{ allPage }}</el-text>
        <el-button
          type="info"
          plain
          @click.stop="nextPage"
          :disabled="currValue === allPage"
          icon="ArrowRight"
          >下一页</el-button
        >
        <!-- <el-button type="info" plain @click="() => rotate()" icon="RefreshRight">旋转</el-button> -->
        <el-button type="info" plain @click="() => doublePage()"
          >双页模式</el-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>
    <AnnotationInputDialog
      ref="annotationDialogRef"
      @confirm="confirmAddAnnotation"
    />
  </div>
</template>

<script setup>
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 AnnotationInputDialog from "./annotationInputDialog/index.vue";
// import { showMagBox } from './message/index';
pdfjsLib.GlobalWorkerOptions.workerSrc = "/pdf.worker.js";

let _pdfViewer = null;

let pdfAnno = null;

const props = defineProps({
  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: () => [],
  },
  url: {
    type: String,
    default: "",
  },
  annots: {
    type: [Array],
    default: () => [],
  },
  readOnly: {
    type: Boolean,
    default: false,
  },
});

// 监听URL变化，重新加载PDF
watch(
  () => props.url,
  (newUrl, oldUrl) => {
    if (newUrl && newUrl !== oldUrl) {
      // 添加防抖逻辑
      clearTimeout(pdfInitTimer);
      pdfInitTimer = setTimeout(() => {
        initPdf();
      }, 100);
    }
  }
);

// 监听注解数据变化，重新渲染注解
watch(
  () => props.annots,
  (newAnnots) => {
    // 只在注解数据真正变化时才重新渲染
    if (newAnnots && newAnnots.length >= 0) {
      setTimeout(() => {
        renderAnnots(newAnnots);
      }, 0);
    }
  },
  { deep: true }
);
// const url = ref('');
let pdfInitTimer = null;
const contextMenuTarget = ref(null);
const contextMenuVisible = ref(false);
const currValue = ref(1);
const allPage = ref(0);

const annotationDialogRef = ref(null);

const $emit = defineEmits([
  "ready",
  "addNote",
  "copy",
  "annotChange",
  "removeAnnots",
  "removeAllAnnot",
]);
const isPdfLoaded = ref(false);
async function initPdf() {
  // 清理之前的PDF viewer实例
  if (_pdfViewer) {
    _pdfViewer.cleanup();
    _pdfViewer = null;
  }

  // 清理之前的PDF注解实例
  if (pdfAnno) {
    pdfAnno = null;
  }

  // 清理页面容器
  const viewer = document.getElementById("viewer");
  if (viewer) {
    viewer.innerHTML = "";
  }

  // 加载pdf文件
  const loadingTask = pdfjsLib.getDocument(props.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,
  });

  _pdfViewer = pdfViewer;

  pdfViewer.setDocument(pdf);

  // ... existing code ...
  pdfViewer.onePageRendered.then(() => {
    // 设置合适的初始缩放，避免一开始就出现滚动条
    _pdfViewer.currentScaleValue = "page-width"; // 使用页面宽度适应模式
    currValue.value = pdfViewer._currentPageNumber;
    allPage.value = pdf.numPages;
    isPdfLoaded.value = true; // 标记PDF已加载

    // 确保PDF viewer完全初始化后再渲染注解
    setTimeout(() => {
      renderAnnots(props.annots);
    }, 100);

    $emit("ready", {
      PdfAnnots: pdfAnno,
      zoomIn: zoomIn,
      rotate: rotate,
      doublePage: doublePage,
      switchPage: switchPage,
      renderAnnots: renderAnnots,
    });
  });
  // ... existing code ...

  pdfAnno = new PdfAnnotation({
    pdfViewer: pdfViewer,
    pdfJs: pdf,
  });
}
function saveCurrentSelection() {
  const sel = window.getSelection();
  if (!sel.rangeCount) return null;

  const range = sel.getRangeAt(0).cloneRange();

  // 返回一个模拟Selection的对象
  return {
    rangeCount: 1,
    isCollapsed: range.collapsed,
    getRangeAt: () => range,
    toString: () => range.toString(),
    // 保留原始节点引用（用于PDF.js的特殊处理）
    _source: {
      startContainer: range.startContainer,
      endContainer: range.endContainer,
      startOffset: range.startOffset,
      endOffset: range.endOffset,
    },
  };
}
function addNote() {
  closeMenu();
  const savedRange = saveCurrentSelection();
  showAnnotationDialog({ pdfAnno, savedRange });
}

function confirmAddAnnotation(annots) {
  $emit("addNote", annots);
}

function showAnnotationDialog(pdfAnno) {
  annotationDialogRef.value.show(pdfAnno);
}
function renderAnnots(annots) {
  if (pdfAnno) {
    pdfAnno.removeAllAnnots();
    pdfAnno.addAnnots(annots);
  }
}

function removeAnnots(annotIds) {
  if (pdfAnno && annotIds) {
    pdfAnno.removeAnnots(annotIds);
    // $emit('removeAnnots');
  }
}

function removeAllAnnots() {
  if (pdfAnno) {
    pdfAnno.removeAllAnnots();
    // $emit('removeAllAnnot');
  }
}
function copy() {
  const text = document.getSelection().toString();
  navigator.clipboard
    .writeText(text)
    .then(() => {
      ElMessage.success("复制成功");
      closeMenu();
      $emit("copy", text);
    })
    .catch((err) => {
      console.log("无法复制文本: ", err);
    });
}
// 下划线
// function Underline() {
//   closeMenu();
//   pdfAnno
//     .setAnno({
//       subtype: 'Underline',
//       color: props.underlineColor
//     })
//     .then((annots) => {
//       $emit('addNote', annots);
//     });
// }
// 删除线
function StrikeOut() {
  closeMenu();
  const savedRange = saveCurrentSelection(); // 保存选区

  if (!savedRange || !savedRange.rangeCount) {
    console.warn("No valid selection found for StrikeOut");
    ElMessage.warning("请先选择要添加删除线的文本");
    return;
  }

  pdfAnno
    .setAnno({
      subtype: "StrikeOut",
      color: props.strikeOutColor,
      userId: "123",
      nickName: "123",
      createTime: "123",
      noteType: 1,
    })
    .then((annots) => {
      $emit("addNote", annots);
    })
    .catch((error) => {
      console.error("StrikeOut error:", error);
      ElMessage.error("删除线添加失败：" + error.message);
    });
}
// 高亮
function highlight() {
  closeMenu();
  pdfAnno
    .setAnno({
      subtype: "Highlight",
      color: props.highlightColor,
      userId: "123",
      nickName: "123",
      createTime: "123",
    })
    .then((annots) => {
      $emit("addNote", annots);
    });
}
function handleScroll(e) {
  // 判断是不是按下ctrl键
  if (e.ctrlKey) {
    // 取消浏览器默认的放大缩小网页行为
    e.preventDefault();
    // 判断是向上滚动还是向下滚动

    if (e.deltaY > 0) {
      zoomIn(0.1);
      // 放大重写，业务代码
    } else {
      zoomOut(0.1);
      // 缩小重写，业务代码
    }
  }
}
function closeMenu() {
  contextMenuVisible.value = false;
}
function zoomOut(scale = 0.2) {
  if (_pdfViewer.currentScale < 3) {
    _pdfViewer.currentScaleValue = _pdfViewer.currentScale + scale;
  }
}
function zoomIn(scale = 0.2) {
  if (_pdfViewer.currentScaleValue > 0.6) {
    _pdfViewer.currentScaleValue -= scale;
  }
}
function rotate() {
  _pdfViewer.pagesRotation += 90;
}
function doublePage() {
  if (_pdfViewer.spreadMode === 1) {
    _pdfViewer.spreadMode = 0;
  } else {
    _pdfViewer.spreadMode = 1;
  }
}
function numChange(page) {
  _pdfViewer.currentPageNumber = page;
  currValue.value = page;
}
// ... existing code ...
function switchPage(page) {
  try {
    // 确保PDF查看器已初始化并且页面有效
    if (_pdfViewer && page >= 1 && page <= allPage.value) {
      // 先获取页面容器
      const pageContainer = document.getElementById("pageContainer");

      // 重置滚动位置，确保从初始位置开始
      if (pageContainer) {
        pageContainer.scrollLeft = 0;
        pageContainer.scrollTop = 0;
      }

      // 记录跳转前的页面
      const oldPage = _pdfViewer.currentPageNumber;

      // 设置当前页码
      _pdfViewer.currentPageNumber = page;
      currValue.value = page;

      // 使用PDF.js内置的scrollPageIntoView方法来正确跳转
      if (_pdfViewer && typeof _pdfViewer.scrollPageIntoView === "function") {
        // 延迟执行确保页面已切换
        setTimeout(() => {
          _pdfViewer.scrollPageIntoView({
            pageNumber: page,
            dest: null,
            allowNegativeOffset: false,
            ignoreDestinationZoom: true, // 忽略目标缩放级别，保持当前缩放
          });

          // 再次重置横向滚动确保页面居中
          if (pageContainer) {
            setTimeout(() => {
              pageContainer.scrollLeft = 0;
            }, 100);
          }

          // 添加跳转成功的反馈
          if (oldPage !== page) {
            console.log(
              `Successfully switched from page ${oldPage} to page ${page}`
            );
          }
        }, 50);
      } else {
        // 如果没有scrollPageIntoView方法，给出警告
        console.warn("PDF.js scrollPageIntoView method is not available");
      }

      // 显示跳转成功的消息
      ElMessage.success(`已跳转到第${page}页`);
      return true;
    } else {
      // 页面参数无效，显示错误消息
      const errorMsg = !_pdfViewer
        ? "PDF查看器未初始化"
        : page < 1
        ? "页码不能小于1"
        : `页码超出范围，最大页码为${allPage.value}`;

      ElMessage.error(errorMsg);
      console.error("Invalid page switch attempt:", {
        page,
        maxPage: allPage.value,
        viewerReady: !!_pdfViewer,
      });
      return false;
    }
  } catch (error) {
    // 发生异常，显示错误消息
    ElMessage.error("跳转页面失败");
    console.error("Error switching to page:", error);
    return false;
  }
}
// ... existing code ...

// 添加一个强制居中当前页面的方法
function centerCurrentPage() {
  const pageContainer = document.getElementById("pageContainer");
  if (pageContainer && _pdfViewer) {
    const currentPage = _pdfViewer.currentPageNumber;
    const pageElement = document.querySelector(
      `.page[data-page-number="${currentPage}"]`
    );

    if (pageElement) {
      // 获取容器和页面的尺寸
      const containerRect = pageContainer.getBoundingClientRect();
      const pageRect = pageElement.getBoundingClientRect();

      // 计算需要滚动的距离以使页面居中
      const scrollLeft =
        pageRect.left -
        containerRect.left +
        pageContainer.scrollLeft -
        (containerRect.width - pageRect.width) / 2;

      // 水平滚动到居中位置
      pageContainer.scrollLeft = Math.max(0, scrollLeft);
    }
  }
}

// 监听页面变化事件
function onPageChange() {
  // 页面变化后自动居中
  setTimeout(() => {
    centerCurrentPage();
  }, 100);
}
// ... existing code ...
function preventPage() {
  if (currValue.value > 1) {
    currValue.value -= 1;
    switchPage(currValue.value);
  }
}

function nextPage() {
  if (currValue.value < allPage.value) {
    currValue.value += 1;
    switchPage(currValue.value);
  }
}

// const eventList = computed(() => {
//   return [
//     {
//       name: '复制',
//       icon: copyIcon,
//       event: copy
//     },
//     {
//       name: '添加笔记',
//       icon: noteIcon,
//       event: addNote
//     },
//     // {
//     //   name: '下划线',
//     //   icon: underlineIcon,
//     //   event: Underline
//     // },
//     // {
//     //   name: '高亮',
//     //   icon: highlightIcon,
//     //   event: highlight
//     // },
//     {
//       name: '删除线',
//       icon: strikeOutIcon,
//       event: StrikeOut
//     },
//     ...props.contextmenuList
//   ];
// });

const eventList = computed(() => {
  // 基础事件列表
  const baseEvents = [
    {
      name: "复制",
      icon: copyIcon,
      event: copy,
    },
  ];

  // 如果不是只读模式，添加编辑相关功能
  if (!props.readOnly) {
    baseEvents.push(
      {
        name: "添加笔记",
        icon: noteIcon,
        event: addNote,
      },
      {
        name: "删除线",
        icon: strikeOutIcon,
        event: StrikeOut,
      }
    );
  }

  // 合并用户自定义的 contextmenuList
  return [...baseEvents, ...props.contextmenuList];
});

onMounted(() => {
  const container = document.getElementById("pageContainer");
  contextMenuTarget.value = container;
  container.addEventListener("mousewheel", handleScroll, {
    passive: false,
  });
  initPdf();
});

onUnmounted(() => {
  // 清理定时器
  if (pdfInitTimer) {
    clearTimeout(pdfInitTimer);
  }
  // 重置加载状态
  isPdfLoaded.value = false;
  // 清理PDF实例
  if (_pdfViewer) {
    _pdfViewer.cleanup();
    _pdfViewer = null;
  }
});

defineExpose({
  switchPage,
  renderAnnots,
  removeAnnots,
  removeAllAnnots,
  initPdf,
});
</script>

<style scoped lang="scss">
.main {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.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;
}

.content {
  position: relative;
  width: 100%;
  flex: 1;
  overflow-y: auto;
}

#pageContainer {
  position: absolute;
  margin: auto;
  width: 100%;
  height: 100%;
  overflow-y: auto;
}

/* 确保页面在容器中居中显示 */
.pdfViewer .page {
  display: inline-block;
  margin: 0 auto 10px auto;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
}

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>
