<template>
  <div class="compare-setting-popup" v-if="show">
    <Dialog :show="show" :dialogName="dialogName" :close="false">
      <!-- header -->
      <template #header>
        <div class="mode pc">
          <div :class="{ selected: mode === 'content' }" @click="changeMode('content')">{{ $t('compare.contentComparison') }}</div>
          <div :class="{ selected: mode === 'cover' }" @click="changeMode('cover')">{{ $t('compare.overlayComparison') }}</div>
        </div>
      </template>

      <!-- content -->
      <div class="dialog-content">
        <div class="mode mobile">
          <div :class="{ selected: mode === 'content' }" @click="changeMode('content')">{{ $t('compare.contentComparison') }}</div>
          <div :class="{ selected: mode === 'cover' }" @click="changeMode('cover')">{{ $t('compare.overlayComparison') }}</div>
        </div>
        <!-- 内容对比 - 对比项 -->
        <div class="compare-items" v-show="mode === 'content'">
          <p class="title">{{ $t('compare.compareItems') }}</p>
          <div class="row">
            <div class="check-box" @click="textCompare = !textCompare">
              <div class="check" :class="{'active': textCompare}"><Checkbox v-show="textCompare" /></div>
              <span>{{ $t('compare.text') }}</span>
            </div>
          </div>
          <div class="row">
            <div class="check-box" @click="imgCompare = !imgCompare">
              <div class="check" :class="{'active': imgCompare}"><Checkbox v-show="imgCompare" /></div>
              <span>{{ $t('compare.images') }}</span>
            </div>
          </div>
        </div>
        <!-- 覆盖对比 - 透明度 -->
        <div class="opacity" v-show="mode === 'cover'">
          <p class="title">{{ $t('opacity') }}</p>
          <div class="row">
            <span>{{ $t('compare.oldFile') }}</span>
            <n-slider v-model:value="oldOpacityVal" :step="10" :max="100" :min="0">
              <template #thumb>
                <Slider />
              </template>
            </n-slider>
            <div class="percent-input">
              <input v-model="oldOpacityVal" type="number" step="10" pattern="\d*" onkeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))" @blur="handleOldInputBlur" name="compare">
            </div>
          </div>
          <div class="row">
            <span>{{ $t('compare.newFile') }}</span>
            <n-slider v-model:value="newOpacityVal" :step="10" :max="100" :min="0">
              <template #thumb>
                <Slider />
              </template>
            </n-slider>
            <div class="percent-input">
              <input v-model="newOpacityVal" type="number" step="10" pattern="\d*" onkeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))" @blur="handleNewInputBlur" name="compare">
            </div>
          </div>
        </div>
        <!-- Mark颜色 -->
        <div class="mark-color">
          <p class="title">{{ $t('compare.colorMark') }}</p>
          <template v-if="mode === 'cover'">
            <div class="row">
              <span>{{ $t('compare.oldFile') }}</span>
              <n-popover
                ref="oldColorPopover"
                placement="bottom-start"
                trigger="click"
                :show-arrow="false"
                to="#outerContainer"
                :raw="true"
                class="color-popover"
              >
                <template #trigger>
                  <div class="select color-select">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer">
                          <span class="cell" :style="`background-color: ${oldFileColor};`"></span></span>
                      </span>
                    </div>
                    <ArrowDown />
                  </div>
                </template>
                <div class="drop-down">
                  <div class="drop-item" v-for="(color, index) in colorArray" :key="index">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer" :class="{ active: oldFileColor === color }" @click="setMarkColor('old', color)">
                          <span class="cell" :style="`background-color: ${color};`"></span>
                        </span>
                      </span>
                    </div>
                  </div>
                </div>
              </n-popover>
            </div>
            <div class="row">
              <span>{{ $t('compare.newFile') }}</span>
              <n-popover
                ref="newColorPopover"
                placement="bottom-start"
                trigger="click"
                :show-arrow="false"
                to="#outerContainer"
                :raw="true"
                class="color-popover"
              >
                <template #trigger>
                  <div class="select color-select">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer">
                          <span class="cell" :style="`background-color: ${newFileColor};`"></span></span>
                      </span>
                    </div>
                    <ArrowDown />
                  </div>
                </template>
                <div class="drop-down">
                  <div class="drop-item" v-for="(color, index) in colorArray" :key="index">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer" :class="{ active: newFileColor === color }" @click="setMarkColor('new', color)">
                          <span class="cell" :style="`background-color: ${color};`"></span>
                        </span>
                      </span>
                    </div>
                  </div>
                </div>
              </n-popover>
            </div>
            <div class="row">
              <span>{{ $t('compare.blendMode') }}</span>
              <n-popselect v-model:value="mixMode" :options="mixModeOptions" trigger="click" placement="bottom-start">
                <div class="select">
                  <span>{{ mixModeOptions[parseInt(mixMode)].label }}</span>
                  <ArrowDown />
                </div>
              </n-popselect>
            </div>
          </template>
          <template v-else>
            <div class="row">
              <span>{{ $t('compare.replacedContent') }}</span>
              <n-popover
                ref="replaceColorPopover"
                placement="bottom-start"
                trigger="click"
                :show-arrow="false"
                to="#outerContainer"
                :raw="true"
                class="color-popover"
              >
                <template #trigger>
                  <div class="select color-select">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer">
                          <span class="cell" :style="`background-color: ${replaceColor};`"></span>
                        </span>
                      </span>
                    </div>
                    <ArrowDown />
                  </div>
                </template>
                <div class="drop-down">
                  <div class="drop-item" v-for="(color, index) in colorArray" :key="index">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer" :class="{ active: replaceColor === color }" @click="setMarkColor('replace', color)">
                          <span class="cell" :style="`background-color: ${color};`"></span>
                        </span>
                      </span>
                    </div>
                  </div>
                </div>
              </n-popover>
            </div>
            <div class="row">
              <span>{{ $t('compare.insertedContent') }}</span>
              <n-popover
                ref="insertColorPopover"
                placement="bottom-start"
                trigger="click"
                :show-arrow="false"
                to="#outerContainer"
                :raw="true"
                class="color-popover"
              >
                <template #trigger>
                  <div class="select color-select">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer">
                          <span class="cell" :style="`background-color: ${insertColor};`"></span>
                        </span>
                      </span>
                    </div>
                    <ArrowDown />
                  </div>
                </template>
                <div class="drop-down">
                  <div class="drop-item" v-for="(color, index) in colorArray" :key="index">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer" :class="{ active: insertColor === color }" @click="setMarkColor('insert', color)">
                          <span class="cell" :style="`background-color: ${color};`"></span>
                        </span>
                      </span>
                    </div>
                  </div>
                </div>
              </n-popover>
            </div>
            <div class="row">
              <span>{{ $t('compare.deletedContent') }}</span>
              <n-popover
                ref="deleteColorPopover"
                placement="bottom-start"
                trigger="click"
                :show-arrow="false"
                to="#outerContainer"
                :raw="true"
                class="color-popover"
              >
                <template #trigger>
                  <div class="select color-select">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer">
                          <span class="cell" :style="`background-color: ${deleteColor};`"></span></span>
                      </span>
                    </div>
                    <ArrowDown />
                  </div>
                </template>
                <div class="drop-down">
                  <div class="drop-item" v-for="(color, index) in colorArray" :key="index">
                    <div class="colors-container mark">
                      <span class="cell-container">
                        <span class="cell-outer" :class="{ active: deleteColor === color }" @click="setMarkColor('delete', color)">
                          <span class="cell" :style="`background-color: ${color};`"></span>
                        </span>
                      </span>
                    </div>
                  </div>
                </div>
              </n-popover>
            </div>
          </template>
        </div>
        <div class="dialog-footer mobile">
          <div class="rect-button white" @click="closeDialog">{{ $t('compare.return') }}</div>
          <div class="rect-button blue" @click="comparing">{{ $t('compare.compare') }}</div>
        </div>
      </div>

      <!-- footer -->
      <template #footer>
        <div class="rect-button white" @click="closeDialog">{{ $t('compare.return') }}</div>
        <div class="rect-button blue" @click="comparing">{{ $t('compare.compare') }}</div>
      </template>
    </Dialog>
  </div>

  <!-- Loading -->
  <div class="mask" :class="{ active: loading }">
    <div v-show="loading" class="loading"><Loading /></div>
    <div class="loading-compare-tip"><span>{{ $t('compare.comingSoon') }}</span></div>
  </div>
</template>

<script setup>
import { ref, computed, watch, getCurrentInstance } from 'vue'
import { useViewerStore } from '@/stores/modules/viewer'
import { useDocumentStore } from '@/stores/modules/document'
import { useI18n } from 'vue-i18n'
import { NSlider, NPopover, NPopselect } from 'naive-ui'
import getHashParameters from '@/helpers/getHashParameters'
import core from '@/core'
const { t } = useI18n()

const { compare, loadDocument, getOptionUrl } = core
const useViewer = useViewerStore()
const useDocument = useDocumentStore()
const instance = getCurrentInstance().appContext.app.config.globalProperties

const dialogName = 'compareSettingDialog'
const show = computed(() => useViewer.isElementOpen(dialogName))
const compareFiles = computed(() => useDocument.getCompareFiles)
const mode = computed(() => useViewer.getCompareMode)

// 属性值
const oldOpacityVal = ref(50)
const newOpacityVal = ref(50)
const oldFileColor = computed(() => useDocument.getCompareSetting('oldFileColor'))
const newFileColor = computed(() => useDocument.getCompareSetting('newFileColor'))
const mixMode = ref('0')
const mixModeOptions = [
  {
    label: t('compare.normal'),
    value: '0'
  },
  {
    label: t('compare.multiply'),
    value: '1'
  },
  {
    label: t('compare.screen'),
    value: '2'
  },
  {
    label: t('compare.overlay'),
    value: '3'
  },
  {
    label: t('compare.darken'),
    value: '4'
  },
  {
    label: t('compare.lighten'),
    value: '5'
  },
  {
    label: t('compare.colorDodge'),
    value: '6'
  },
  {
    label: t('compare.colorBurn'),
    value: '7'
  },
  {
    label: t('compare.hardLight'),
    value: '8'
  },
  {
    label: t('compare.softLight'),
    value: '9'
  },
  {
    label: t('compare.difference'),
    value: '10'
  },
  {
    label: t('compare.exclusion'),
    value: '11'
  },
  {
    label: t('compare.hue'),
    value: '12'
  },
  {
    label: t('compare.saturation'),
    value: '13'
  },
  {
    label: t('compare.colour'),
    value: '14'
  },
  {
    label: t('compare.luminosity'),
    value: '15'
  }
]
const textCompare = ref(true)
const imgCompare = ref(true)
const replaceColor = ref('#93B9FD')
const insertColor = ref('#C0FFEC')
const deleteColor = ref('#FBBDBF')

const colorArray = ['#FBBDBF', '#93B9FD', '#FFF6B3', '#C0FFEC']
const oldColorPopover = ref(null)
const newColorPopover = ref(null)
const replaceColorPopover = ref(null)
const insertColorPopover = ref(null)
const deleteColorPopover = ref(null)
const loading = ref(false)
const oldCurrentScale = ref(null)
const newCurrentScale = ref(null)

watch(() => oldOpacityVal.value, (newValue, oldValue) => {
  const regex = /^\d+$/
  if ((newValue !== '' && (newValue > 100 || newValue < 0 || !regex.test(newValue)))) {
    oldOpacityVal.value = oldValue
  }
})

watch(() => newOpacityVal.value, (newValue, oldValue) => {
  const regex = /^\d+$/
  if ((newValue !== '' && (newValue > 100 || newValue < 0 || !regex.test(newValue)))) {
    newOpacityVal.value = oldValue
  }
})

// 点击开始对比
const comparing = async () => {
  const data = {
    leftFile: compareFiles.value.oldFile,
    leftFilePassword: compareFiles.value.oldFilePassword,
    rightFile: compareFiles.value.newFile,
    rightFilePassword: compareFiles.value.newFilePassword,
  }
  if (mode.value === 'content') {
    let text = textCompare.value
    let img = imgCompare.value
    if (!text && !img) {
      text = img = true
    }
    const contentData = {
      type: 1,
      textCompare: text,
      imgCompare: img,
      replaceColor: replaceColor.value,
      insertColor: insertColor.value,
      deleteColor: deleteColor.value
    }
    Object.assign(data, contentData)
  } else {
    const coverData = {
      type: 2,
      inTransparency: oldOpacityVal.value + '',
      newTransparency: newOpacityVal.value + '',
      coverType: mixMode.value,
      inColor: oldFileColor.value,
      newColor: newFileColor.value
    }
    Object.assign(data, coverData)
  }
  try {
    useViewer.closeElement(dialogName)
    loading.value = true
    const res = await compare(data)
    if (res && res.url) {
      useDocument.resetSetting()

      const options = {
        filename: t('compare.byComPDFKit') + '.pdf',
        progress: useDocument.setLoadingProgress,
        pageChangedCallback: useViewer.setCurrentPage,
        scaleChangedCallback: useViewer.setCurrentScale,
        annotationsNumChangedCallback: useDocument.setAnnotationsCount,
        distanceChangedCallback: useDocument.setDistance,
        notUpdatePwd: true
      }
      await loadDocument(res.url, options)
      loading.value = false
      
      // useViewer.toggleElement('leftPanel')
      const totalPages = core.getPagesCount()
      const scale = core.getScale()
      useDocument.setTotalPages(totalPages)
      useViewer.setCurrentScale(scale)
      useViewer.setCurrentPage(1)
      useViewer.setUpload(true)
      useViewer.setCompareStatus('finished')
    } else if (res && Array.isArray(res)) {
      const oldFile = res[0]
      const newFile = res[1]
      useDocument.setCompareResult({
        oldFile,
        newFile,
        mergeFile: res[2]
      })
      uploadPdf(oldFile.url, oldFile.fileName, 2)
      uploadPdf(newFile.url, newFile.fileName, 3)
      loading.value = false
      useViewer.setCompareStatus('next')
    } else {
      loading.value = false
      useViewer.setDownloadError('Compared')
    }
  } catch (error) {
    console.log(error)
    loading.value = false
    useViewer.setDownloadError('Compared')
    if (error === 'invalid_file_error' || error === 'no_password_given' || error === 'incorrect_password') {
      useViewer.setUpload(false)
      useDocument.setLoadingProgress(0)
      useViewer.resetSetting()
      const openFileInput = document.getElementById("fileInput")
      openFileInput.value = ''
    }
  }
}

const handleOldInputBlur = (event) => {
  if (!event.target.value) {
    oldOpacityVal.value = 1
  }
}

const handleNewInputBlur = (event) => {
  if (!event.target.value) {
    newOpacityVal.value = 1
  }
}

// 设置文件mark颜色
const setMarkColor = (name, color) => {
  if (name === 'old') {
    useDocument.setCompareSetting('oldFileColor', color)
  } else if (name === 'new') {
    useDocument.setCompareSetting('newFileColor', color)
  } else if (name === 'replace') {
    replaceColor.value = color
  } else if (name === 'insert') {
    insertColor.value = color
  } else if (name === 'delete') {
    deleteColor.value = color
  }

  if (mode.value === 'content') {
    replaceColorPopover.value.setShow(false)
    insertColorPopover.value.setShow(false)
    deleteColorPopover.value.setShow(false)
  } else {
    oldColorPopover.value.setShow(false)
    newColorPopover.value.setShow(false)
  }
}

const closeDialog = () => {
  useViewer.closeElement(dialogName)
}

// 预览pdf
async function uploadPdf (pdf, filename = null, docNum) {
  useViewer.setUploadLoading(true)

  let pwd = null
  if (docNum === 2) {
    pwd = useDocument.getCompareFile('oldFilePassword')
  } else if (docNum === 3) {
    pwd = useDocument.getCompareFile('newFilePassword')
  }
  const options = {
    extension: getHashParameters('extension', null),
    filename: filename || getHashParameters('filename', null),
    externalPath: getHashParameters('p', ''),
    documentId: getHashParameters('did', null),
    progress: useDocument.setLoadingProgress,
    pageChangedCallback: useViewer.setCurrentPage,
    scaleChangedCallback: docNum === 2 ? setOldCurrentScale() : setNewCurrentScale(),
    annotationsNumChangedCallback: useDocument.setAnnotationsCount,
    distanceChangedCallback: useDocument.setDistance,
    notUploadPdf: true
  }
  if (pwd) {
    options.pwd = pwd
  }
  try {
    await loadDocument(pdf, options, docNum)
  } catch (error) {
    console.log(error)
    useViewer.setDownloadError('Loaded')
  }
  useViewer.setUploadLoading(false)
}

const changeMode = (mode) => {
  useViewer.setCompareMode(mode)
}

const setOldCurrentScale = (scale) => {
  oldCurrentScale.value = scale
}
const setNewCurrentScale = (scale) => {
  newCurrentScale.value = scale
}
</script>

<style lang="scss">
.compare-setting-popup {
  font-family: Helvetica;
  .mode {
    max-width: 340px;
    width: 100%;
    margin: 0 auto;
    div {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      width: 50%;
      padding: 8px 10px;
      border-radius: 2px;
      background: #F2F2F2;
      color: #001A4E;
      font-size: 14px;
      font-weight: 400;
      line-height: 16px;
      text-align: center;
      &.selected {
        background-color: #1460F3;
        color: #fff;
        font-weight: 700;
      }
    }
  }

  .dialog-content {
    width: 406px;
    padding: 8px 16px;
    border-radius: 4px;
    background-color: var(--c-toolbar-bg);
    > div {
      margin-bottom: 16px;
    }
    .title {
      margin: 4px 0;
      font-size: 16px;
      font-weight: 700;
      line-height: 24px;
    }
    .row {
      display: flex;
      align-items: center;
      height: 28px;
      > span {
        width: 110px;
      }
      & + .row {
        margin-top: 8px;
      }
      & > :nth-child(2) {
        margin-left: 8px;
      }
      & > :nth-child(3) {
        margin-left: 8px;
      }
    }
    .opacity .row {
      height: 32px;
      > span {
        width: 82px;
      }
      .n-slider {
        width: 129px;
        .n-slider-rail {
          height: 2px;
          border-radius: 0;
          .n-slider-rail__fill {
            background-color: #4982E6;
            border-radius: 0;
          }
        }
        .n-slider-handles {
          left: 0;
          right: 0;
        }
      }
      input {
        padding: 6px;
        width: 72px;
        height: 30px;
        border: 1px solid var(--c-side-header-border);
        outline: none;
        border-radius: 0;
        background-color: var(--c-side-header-bg);
        color: var(--c-text);
        &:focus {
          border-color: var(--c-popup-bg-active);
        }
      }
      .percent-input {
        position: relative;
        &::after {
          content: '%';
          position: absolute;
          top: 5px;
          left: 30px;
          pointer-events: none;
        }
      }
    }
    .compare-items {
      .check-box {
        display: inline-flex;
        align-items: center;
        cursor: pointer;
        .check {
          margin-right: 4px;
          width: 14px;
          height: 14px;
          background: var(--c-right-side-content-fillbox-bg);
          border: 1px solid var(--c-right-side-content-fillbox-border);
          border-radius: 1px;
          overflow: hidden;
          &.active {
            border: none;
          }
          svg {
            vertical-align: top;
          }
        }
        span {
          font-size: 14px;
          font-weight: 400;
          line-height: 16px;
        }
      }
    }
  }
  .mobile {
    display: none;
  }
  .pc {
    display: flex;
  }
}
.mark-color {
  .select {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 4px 4px 8px;
    height: 30px;
    border-radius: 1px;
    border: 1px solid var(--c-side-header-border);
    background-color: var(--c-side-header-bg);
    cursor: pointer;
    &.color-select {
      width: 60px;
    }
  }
}
.colors-container.mark {
  padding: 0;
  border: none;
  .cell-container {
    .cell-outer {
      border-width: 1px;
      width: 24px;
      height: 24px;
      &.active {
        .cell {
          width: 17px;
          height: 17px;
        }
      }
      .cell {
        width: 18px;
        height: 18px;
      }
    }
    & + .cell-container {
      margin-left: 8px;
    }
  }
}
.color-popover {
  margin-top: 2px !important;
  .drop-down {
    display: flex;
    padding: 4px 8px;
    .drop-item {
      padding: 0;
      & + .drop-item {
        margin-left: 8px;
      }
      &:hover {
        background-color: unset;
      }
    }
  }
}
.mask {
  flex-direction: column;
  .loading-compare-tip {
    margin-top: 23px;
    padding: 12px;
    border-radius: 4px;
    background: rgba(54, 56, 59, 0.80);
    color: #FFF;
    font-size: 14px;
  }
}

.dark {
  .n-base-select-menu .n-base-select-menu-option-wrapper .n-base-select-option::before {
    transition: none;
  }
  .n-base-select-menu .n-base-select-option.n-base-select-option--pending::before {
    background-color: var(--c-dropdown-hover-bg);
  }
}

@media screen and (max-width: 430px) {
  .compare-setting-popup {
    position: relative;
    .pc {
      display: none;
    }
    .mobile {
      display: block;
    }
    .dialog {
      overflow: hidden;
    }
    .dialog-content {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 2;
      padding-top: 20px;
      padding-bottom: 20px;
      background-color: var(--c-header-bg);
      border-radius: 0;
    }
    .dialog-footer {
      position: absolute;
      right: 16px;
      bottom: 0;
      display: flex;
      .rect-button {
        width: 120px;
        height: 40px;
      }
    }
  }
  .mask {
    .loading-compare-tip {
      position: absolute;
      bottom: 57px;
    }
  }
}

@media screen and (max-width: 768px) {
  .compare-setting-popup .dialog-content .opacity .row input {
    font-size: 16px;
  }
}
</style>
