<template>
  <div ref="mainContainer" class="document-container"
    :class="{
      'no-select': isHandActive,
      'under': (toolMode === 'compare' && compareStatus !== 'finished') || toolMode === 'document',
      'no-touch': ['selectText', 'highlight', 'underline', 'squiggly', 'strikeout'].includes(activeTool),
      'redact': ['redaction', 'remove'].includes(activeTool)
    }"
    :style="{
      'width': `calc(100% - ${leftPanelSpace}px - ${rightPanelSpace}px)`,
      'margin-left': `${leftPanelSpace}px`,
      'margin-right': `${rightPanelSpace}px`,
      'margin-top': `${topSpace}px`,
      'top': isHeaderDisabled ? '0px' : '44px'
    }"
    @dblclick="onDoubleClick"
    @click="onSingleClick"
    >
    <div ref="viewerContainer" class="document"></div>
    <PageNavOverlay v-if="!isPageNavOverlayDisabled" :style="{ left: `calc(50% + ${leftPanelSpace / 2}px - ${rightPanelSpace / 2}px)` }" />
  </div>
  <!-- <div id="findbar" class="findbar hidden">
    <div id="findbarInputContainer" class="findbarInputContainer">
      <div class="input-container">
        <input id="findInput" class="toolbarField" title="Find" placeholder="Find in document…">
        <div id="findResultsCount" class="toolbarLabel"></div>
      </div>
      <Button
        img="icon-previous-left"
        id="findPrevious"
        class="toolbarButton disabled"
        title="Find the previous occurrence of the phrase"
      >
        <ArrowPrev />
      </Button>
      <Button
        img="icon-next-right"
        id="findNext"
        class="toolbarButton disabled"
        title="Find the next occurrence of the phrase"
      >
        <ArrowNext />
      </Button>
    </div>
  </div> -->
  <EnterPassword />
  <div id="printServiceDialog" class="print-dialog">
    <div class="print-container">
      <div class="print-title">Preparing document for printing…</div>
      <div class="print-progress">
        <progress value="0" max="100"></progress>
        <span class="relative-progress">0%</span>
      </div>
    </div>
  </div>
  <SetPassword />
  <SettingsDialog />
  <PreventDialog />
  <MeasurePop />
  <SelectSignTypeDialog />
  <SignatureAppearanceDialog />
  <SignatureDetailsDialog />
  <CertificationViewerDialog />
  <DeleteSignatureDialog />
  <AddDigitalFileDialog />
  <RedactionConfirmDialog />
  <div v-if="loading && loadingPercent < 100" class="loading-state">{{ $t('loading') }}...</div>
  <div class="mask" :class="{ active: commonLoading }">
    <div v-show="commonLoading" class="loading"><Loading /></div>
  </div>
  <div v-show="!load && activePanelTab !== 'COMPARISON' && ['compare', 'view'].includes(toolMode)" class="upload-container">
    <input id="fileInput" type="file" accept=".pdf" @change="handleUpload" name="document"/>
    <label for="fileInput">{{ $t('upload') }}</label>
  </div>
  <TextPopup />
  <CropPagePopup />
  <ContentEditorPopup />
</template>

<script setup>
import { useViewerStore } from '@/stores/modules/viewer'
import { useDocumentStore } from '@/stores/modules/document'
import { computed, ref } from 'vue'
import getHashParameters from '@/helpers/getHashParameters'
import core from '@/core'
import { isMobileDevice } from '@/helpers/device'

const { isHeaderDisabled } = defineProps(['isHeaderDisabled'])

const { loadDocument, initializeViewer, initConfig, getDocumentViewer } = core
const mainContainer = ref()
const viewerContainer = ref()
const useViewer = useViewerStore()
const useDocument = useDocumentStore()

const isHandActive = computed(() => {
  return useViewer.getActiveHand
})

const isLeftPanelOpen = computed(() => useViewer.isElementOpen('leftPanel'))
const leftPanelSpace = computed(() => {
  if (isMobileDevice) return 0
  return isLeftPanelOpen.value ? 260 : 0
})
const rightPanelSpace = computed(() => {
  if (isMobileDevice) return 0
  return (useViewer.isElementOpen('rightPanel') || useViewer.isElementOpen('pageModePanel') || useViewer.isElementOpen('stampPanel') || useViewer.isElementOpen('linkPanel') || useViewer.isElementOpen('contentEditorPanel')) ? 260 : 0
})
const toolMode = computed(() => useViewer.getToolMode)
const compareStatus = computed(() => useViewer.getCompareStatus)
const topSpace = computed(() => {
  if (isHeaderDisabled || ['view', 'document'].includes(useViewer.getToolMode) || (toolMode.value === 'compare' && compareStatus.value !== 'finished')) return 0
  if (['redaction', 'remove'].includes(activeTool.value)) {
    if (window.innerWidth > 500) return 44 + 48
    else return 44 + 88
  }
  if (signatureVerify.value && toolMode.value === 'sign') return 44 + 44
  return 44
})
const loading = computed(() => useViewer.getUploadLoading && useViewer.getUpload)
const activePanelTab = computed(() => useViewer.getActiveElementTab('leftPanel'))
const load = computed(() => useViewer.getUpload)
const isPageNavOverlayDisabled = computed(() => useViewer.getDisabledElements('pageNavOverlay'))
const activeTool = computed(() => useDocument.getActiveTool)
const scaleValue = computed(() => useViewer.getScale)
const signatureVerify = computed(() => useViewer.getSignatureVerify)
const commonLoading = computed(() => useViewer.getCommonLoading)

let originScale = 100
let lastClickTime = 0 // 用于手动检测双击

// 双击时切换缩放
function onDoubleClick() {
  if (!isMobileDevice) return
  const zoomFactor = 50 // 双击放大时每次增加的倍数
  const changeNumber = 2 // 可双击放大的次数，下一次双击变为原始缩放比例
  const newScale = scaleValue.value < (originScale + changeNumber * zoomFactor) ? scaleValue.value + zoomFactor : originScale
  useViewer.setCurrentScale(newScale / 100)
  core.scaleChanged(newScale / 100)
}

function onSingleClick(e) {
  const pageNav = mainContainer.value.querySelector('.page-nav')
  if (e.target.nodeName === 'A' || pageNav?.contains(e.target)) return
  const currentTime = new Date().getTime()
  if (currentTime - lastClickTime < 300) {
    onDoubleClick() // 如果在 300ms 内点击两次，视为双击
  }
  lastClickTime = currentTime
}

async function handleUpload(evt) {
  const file = evt.target.files[0];
  if (!file) return
  if (isLeftPanelOpen.value) {
    useViewer.closeElement('leftPanel')
  }
  useViewer.$patch({
    fullMode: false,
    currentPage: 0,
    scale: '',
    themeMode: 'Light',
    pageMode: 0,
    scrollMode: 'Vertical',
    activeTab: 0,
    searchStatus: false,
    activeElements: {
      leftPanel: false,
      rightPanel: false,
      pageModePanel: false
    },
    activeElementsTab: {
      leftPanel: 'THUMBS',
      rightPanel: 'GENERAL'
    },
    signatureVerify: 0
  })
  useDocument.resetSetting()
  core.clearSearchResults()
  useDocument.setToolState('')
  useViewer.setActiveToolMode('view')

  useViewer.setUploadLoading(true)
  let filename = file.name

  useViewer.setUpload(true)
  let url = URL.createObjectURL(file);
  await handlePdf(url, {
    filename
  })
  useViewer.setUploadLoading(false)

  URL.revokeObjectURL(url)
}

const loadingPercent = computed(() => useDocument.getLoadingProgress)
async function handlePdf (pdf, {
  filename = null,
  password = ''
}) {
  const options = {
    extension: getHashParameters('extension', null),
    filename: getHashParameters('filename', null) || filename,
    externalPath: getHashParameters('p', ''),
    documentId: getHashParameters('did', null),
    progress: useDocument.setLoadingProgress,
    pageChangedCallback: useViewer.setCurrentPage,
    scaleChangedCallback: useViewer.setCurrentScale,
    annotationsNumChangedCallback: useDocument.setAnnotationsCount,
    distanceChangedCallback: useDocument.setDistance,
    password,
  }
  try {
    const res = await loadDocument(pdf, options)
    if (!res) return
    const { pwd } = res
    useDocument.setFileHasPwd(!!pwd)
    useDocument.setPassword(pwd)
    useDocument.setCurrentPdfData(pdf, options)
    useDocument.setOutline(core.getOutlines())
  } catch (error) {
    console.log(error)
    if (error === 'invalid_file_error' || error === 'no_password_given' || error === 'incorrect_password') {
      useViewer.setUpload(false)
      useViewer.resetSetting()
      const openFileInput = document.getElementById("fileInput")
      openFileInput.value = ''
      useDocument.setCurrentPdfData()
      return
    }
  }
  const totalPages = core.getPagesCount()
  const scale = core.getScale()
  useDocument.setTotalPages(totalPages)
  useViewer.setCurrentPage(1)
  useViewer.setCurrentScale(scale)
  originScale = Math.round(scale * 100)
}

window.instance.initOptions = async (options) => {
  const res = await initConfig(options)
  const webviewerMode = !!(options && options.webviewerServer) ? options.webviewerServer : 'Standalone'
  useViewer.setWebviewerMode(webviewerMode)
  if (!res) return

  const toolModeChanged = (mode) => {
    if (mode === toolMode.value) return
    useViewer.setActiveToolMode(mode)
  }
  core.addEvent('toolModeChanged', toolModeChanged)

  const toolChanged = ({ tool }) => {
    useDocument.setActiveTool(tool)
  }
  core.addEvent('toolChanged', toolChanged)

  useViewer.setVierified(res)
  useViewer.setLicense(getDocumentViewer()._license)
  const thumbnailView = document.querySelector('.thumbnail-view')
  const annotationView = document.querySelector('.annotation-view')
  const outlineView = document.querySelector('.outline-view')
  const findbarView = document.querySelector('.findbar-view')
  initializeViewer({
    container: mainContainer.value,
    viewer: viewerContainer.value,
    thumbnailView,
    outlineView,
    annotationView,
    findbarView,
    toggleButton: document.querySelector('.toggle-button')
  })

  if (!options.initialDoc) {
    useViewer.setUpload(false)
  }
  options.autoJumpNextSign && useDocument.setAutoJumpNextSign(true)

  core.addEvent('onPagesUpdated', (data) => {
    const { pageNumber } = data
    useDocument.setOutline(core.getOutlines())
    const totalPages = core.getPagesCount()
    const scale = core.getScale()
    useDocument.setTotalPages(totalPages)
    useViewer.setCurrentPage(pageNumber || 1)
    useViewer.setCurrentScale(scale)

    const scrollMode = useViewer.getScrollMode
    const pageMode = useViewer.getPageMode

    const modeNum = scrollMode === 'Vertical' ? 0 : 1
    core.switchScrollMode(modeNum)
    core.switchSpreadMode(pageMode)
  })

  window.parent.postMessage({
    type: 'documentViewerLoaded',
    docId: parseInt(getHashParameters('docId'), 10),
  }, '*')
}
// window.instance.initOptions({
//   license: 'qMP0vqPQwaQRzgpdsgT8XjiXImmg3wewcg4ZdhADT9+PImvelornERhjuXFmSm1u6vulW5hSW2Yl8JbNZVPfKYkWjYNnsFPdbF08Ki2XFXECyd+ioqSmR6QgXTzvjvsnYHAgHWlW1qaV3grt65gN3RTCPe32s3IAmZNyaXNJsFS6TbpO5Fz4Kha+hIC/0QKIY5f736R9Do368GJi1wsFtx3fpVqFSq1tE3/tEhm43GEom+y1Ea5sH8DJxSLa3uHndmmzPCDWhXNg+04zcDd7pRsFx/8QFm/IqOAp/SezG1QeZ3gZ2+CRt43iBqfeevPMbi3qtoX8IuN5HEOVGIDO6q8kD+Q9C95FZo3W7DLPF5IZWiBPIsFBXW6GG9jIMlEFWe5rnWo7I9ujPHSweIzq22orZsVxD5tPPZ5v7nNW86LvpYVrsZA1ZWyQ08PB4C5RojNrlBK+2jwgC76todX8+OMMXi5FZaHOhVK4mdgXvNKoU3I/BJTvpGOfrVXKJOP5Rm9A3ki7tGs3KS1+TcPxP+7hkxw+qkcPbbYUUZGSaFhWNmeZ8AxazlM2vWnAKDfxyB3zkYt10OmuUj4xx8hkvV5adbfllpJjvdp0DBYyOc6+K0TBVof+phlwhjszWrdm3QIveURmbR763QUBTybPikNm7rh2AHOlZwPY0qWudzuJdXp7Ua4M8Hk2hIUl5hSAyi0KfwVzaj4qZFJz98c3GhGqSEkBoRJBWuxkclY+4WlEQ+GYDjWpAryku2gWr457',
//   webFontURL: '/fonts/'
// })

window.instances.UI.loadDocument = async (file, {
  filename = '',
  password = ''
} = {}) => {
  if (!file) return
  if (isLeftPanelOpen.value) {
    useViewer.closeElement('leftPanel')
  }
  useViewer.$patch({
    fullMode: false,
    currentPage: 0,
    scale: '',
    themeMode: 'Light',
    pageMode: 0,
    scrollMode: 'Vertical',
    activeTab: 0,
    searchStatus: false,
    activeElements: {
      leftPanel: false,
      rightPanel: false
    },
    activeElementsTab: {
      leftPanel: 'THUMBS',
      rightPanel: 'GENERAL'
    }
  })
  useDocument.resetSetting()
  core.clearSearchResults()
  useDocument.setToolState('')
  useViewer.setActiveToolMode('view')

  useViewer.setUploadLoading(true)
  useViewer.setUpload(true)

  let url = typeof file === 'string' ? file : URL.createObjectURL(file)
  await handlePdf(url, {
    filename: file.name || filename,
    password,
  })
  useViewer.setUploadLoading(false)
}
</script>

<style lang="scss">
.grab-to-pan-grab {
  cursor: grab !important;
}

.grab-to-pan-grabbing {
  cursor: grabbing !important;
  position: fixed;
  background: rgba(0, 0, 0, 0);
  display: block;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  z-index: 50000;
}

.document-container {
  overflow: auto;
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  outline: none;
  transition: all .3s ease-in-out;
  touch-action: pan-x pan-y;
}

.no-select {
  .textLayer span {
    user-select: none;
    -webkit-user-select: none;
  }

  .annotationContainer>div .freetext {
    pointer-events: none;
  }
}

.no-touch {
  touch-action: none;
}

.under {
  z-index: -1;
  opacity: 0;
  pointer-events: none;
}

.loading-state {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: 46px;
  z-index: 2;
}

.upload-container {
  position: absolute;
  top: 44px;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: calc(100vh - 44px);

  input {
    display: none;
  }

  label {
    display: inline-block;
    background-color: #0097FF;
    width: 260px;
    height: 48px;
    font-size: 24px;
    line-height: 48px;
    text-align: center;
    color: #FFFFFF;
  }
}

.annotationLayer {
  background: transparent;
  position: absolute;
  top: 0;
  left: 0;
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
  z-index: 2;
}

.annotationLayer > svg {
  display: block;
  pointer-events: auto;
}

.inkEditor .inkEditorCanvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  touch-action: none;
}

.inkEditor {
  position: absolute;
  background: transparent;
  border-radius: 3px;
  overflow: auto;
  width: 100%;
  height: 100%;
  z-index: 1;
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
  cursor: auto;
}

.inkEditor.selectedAnnotation {
  outline: solid 2px rgb(71, 126, 222);
}

.stickyAnnotation,
.editor-container {
  position: absolute;
  pointer-events: auto;
}

.stickyAnnotation {
  outline: none;
  font-size: 0;
  border: 1px solid transparent;
}

.selectedAnnotation {
  border-color: rgb(71, 126, 222);
}

.editor-container {
  transform: translateX(-50%);
  width: 300px;
  height: 247px;
  padding: 6px;
  z-index: 1;
  box-sizing: border-box;
  background-color: rgb(255, 245, 203);
  box-shadow: rgb(0, 0, 0, 10%) 0px -2px 12px 2px;
  border-radius: 5px;
  border: none;
  outline: none;
  font-size: 12px;
  color: rgb(51, 51, 51);
  line-height: 17px;
  resize: none;
  text-align: left;
}

.print-dialog {
  display: none;
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 6;
  background-color: rgba(0, 0, 0, 0.2);

  &.show {
    display: block;
  }

  .print-container {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    max-width: 254px;
    padding: 15px;
    border-spacing: 4px;
    color: #000;
    font-size: 12px;
    line-height: 14px;
    background-color: #FFF;
    border: 1px solid rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  }

  .print-title {
    margin-bottom: 20px;
  }

  .print-progress .relative-progress {
    margin-left: 10px;
  }
}

@media screen and (max-width: 640px) {
  .document-container {
    width: 100%;
  }
}

@media screen and (min-width: 641px) {
  .document-container {
    width: calc(100% - 260px);
    margin-left: 260px;
  }
}

.document .page {
  position: relative;
  margin: 20px auto;
  background-clip: content-box;
  background-color: rgba(255, 255, 255, 1);
  user-select: none;
  -webkit-user-select: none;

  >.freetext {
    position: absolute;
    z-index: 5;
    pointer-events: auto;
    outline: none;
  }

  .text-title {
    padding: 8px 0 5px;
    font-weight: bold;
    font-size: 14px;
    line-height: 16px;
    color: #333333;
  }
  &.text {
    .annotationLayer {
      cursor: text;
    }
  }
  .text-container .text-selection {
    position: absolute;
    z-index: 122;
    cursor: text;
    background-color: rgba(0, 0, 255, 0.25);
  }
}

.document.scrollHorizontal,
.spread {
  white-space: nowrap;
  text-align: center;

  .spread,
  .page {
    display: inline-block;
    margin: 20px;
    vertical-align: middle;
  }
}
.pdfPresentationMode .page {
  margin: 2px;
  display: inline-block;
  vertical-align: middle;
}

.document.scrollHorizontal .spread {
  margin: 0px;
}

.document {
  &.annotation-edit {
    .textLayer {
      pointer-events: none;
    }

    .annotationLayer {
      cursor: crosshair;
    }

    .page {
      touch-action: none;
    }
  }

  .canvasWrapper {
    position: absolute;
    pointer-events: none;
    overflow: hidden;
    width: 100%;
    height: 100%;
    z-index: 1;
  }

  .page canvas {
    width: 100%;
    height: 100%;
  }

  .page.loadingIcon:after {
    position: absolute;
    top: 0;
    left: 0;
    content: "";
    width: 100%;
    height: 100%;
    background: url('/images/loading-icon.gif') center no-repeat;
    display: none;
    transition-property: display;
    transition-delay: 400ms;
    z-index: 5;
    contain: strict;
  }

  .page.loading:after {
    display: block;
  }
}

.textLayer {
  position: absolute;
  text-align: initial;
  pointer-events: none;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  line-height: 1;
  -webkit-text-size-adjust: none;
  -moz-text-size-adjust: none;
  -ms-text-size-adjust: none;
  text-size-adjust: none;
  forced-color-adjust: none;
  line-height: 1;
  transform-origin: 0 0;
  z-index: 3;

  & ::selection {
    background-color: rgba(0, 0, 255, 0.25);
  }

  .blank::selection {
    background-color: transparent;
  }
}

[data-main-rotation="90"] {
  transform: rotate(90deg) translateY(-100%);
}

.textLayer .markedContent {
  top: 0;
  height: 0;
}

.textLayer br {
  display: none;
}

.textLayer span {
  color: transparent;
  position: absolute;
  white-space: pre;
  pointer-events: none;
  cursor: text;
  -webkit-transform-origin: 0% 0%;
  transform-origin: 0% 0%;
}

.searchContainer {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 3;
  pointer-events: none;
}
.searchContainer .highlight {
  position: absolute;
  background-color: rgba(255, 255, 0, 0.25);
}

.searchContainer .selected .highlight {
  background-color: rgba(255, 255, 0, 0.7);
}

.findbar {
  padding: 8px;
  background-color: var(--c-findbar-bg);

  &.hidden {
    display: none;
  }

  .findbarInputContainer {
    display: flex;
    align-items: center;
  }

  .input-container {
    flex-grow: 1;
    display: flex;
    width: 180px;
    margin: 3px 0;
    padding: 0 8px;
    border-radius: 1px;
    border: 1px solid var(--c-findbar-input-border);
    background-color: var(--c-findbar-input-bg);
  }

  input {
    flex-grow: 1;
    width: 0;
    height: 30px;
    outline: none;
    padding: 5px 8px;
    box-shadow: none;
    border: none;
    background-color: var(--c-findbar-input-bg);
    color: var(--c-findbar-text);
    font-size: 16px;
  }

  .toolbarLabel {
    font-size: 14px;
    line-height: 30px;
    color: var(--c-findbar-text);
    white-space: nowrap;
  }

  .button {
    margin-left: 8px;
    padding: 0;
    color: var(--c-findbar-text);
  }
}

.contentContainer {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  line-height: 1;
  -webkit-text-size-adjust: none;
  -moz-text-size-adjust: none;
  -ms-text-size-adjust: none;
  text-size-adjust: none;
  forced-color-adjust: none;
  line-height: 1;
  transform-origin: 0 0;
  z-index: 3;

  .cursor-animation {
    animation: caretanimation 1.2s steps(2, jump-none) 0s infinite normal both running;
  }

  .frame-container {
    .text-container,
    .image-container {
      border-style: dashed;
    }

    .text-container textarea {
      cursor: default;
    }

    &.selected {
      z-index: 2;
    }

    &.editing {
      .text-container,
      .image-container {
        border-style: solid;
        z-index: 1;
      }
      
      .text-container,
      .text-container textarea {
        cursor: text;
      }
    }
  }
}

.document-container.pdfPresentationMode .contentContainer {
  display: none !important;
}

.document-container.pdfPresentationMode {
  top: 0;
  background-color: rgb(0 0 0);
  width: 100%;
  height: 100%;
  overflow: hidden;
  cursor: none;
  user-select: none;
}

.document .dummyPage {
  position: relative;
  width: 0;
  height: 100vh;
  display: inline-block;
  vertical-align: middle;
}

@keyframes caretanimation {
  0% {
    color: #000;
  }

  100% {
    color: transparent;
  }
}

.redact .annotationContainer > div:not(.redact),
.redact .annotationContainer > div:not(.redact).annotation > div,
.redact .annotationContainer > div:not(.redact).annotation > img {
  cursor: inherit;
  pointer-events: none;
}
</style>
