<template>
  <div class="signature-appearance-dialog" v-if="show">
    <Dialog :show="show" :dialogName="dialogName" class="appearance-dialog">
      <template #header>
        <p>{{ $t('signatures.appearanceDialog.title') }}</p>
        <CloseB class="close" @click="closePanel" />
      </template>

      <div class="sign-popup-header">
        <div @click="changeActiveSignWay('keyboard')" :class="{ active: activeSignWay === 'keyboard' }">{{ $t('signatures.keyboard') }}</div>
        <div @click="changeActiveSignWay('trackpad')" :class="{ active: activeSignWay === 'trackpad' }">{{ $t('signatures.trackpad') }}</div>
        <div @click="changeActiveSignWay('image')" :class="{ active: activeSignWay === 'image' }">{{ $t('signatures.image') }}</div>
        <div @click="changeActiveSignWay('none')" :class="{ active: activeSignWay === 'none' }">{{ $t('signatures.none') }}</div>
      </div>

      <div class="preview-area">
        <img :src="preview" >
      </div>

      <div class="preview-options">
        <template v-if="activeSignWay === 'image'">
          <span class="upload" @click="uploadImage">{{ $t('upload') }}<input ref="uploadImageEl" type="file" @change="handleFile" accept=".png, .jpg, .jpeg" name="signature"></span>
          <span @click="clearData">{{ $t('signatures.clear') }}</span>
        </template>
      </div>

      <p class="title">{{ $t('signatures.appearanceDialog.includeText') }}</p>
      <div class="configurations">
        <div class="left">
          <div class="checkboxes">
            <div class="check-box" @click="configurations.name = !configurations.name">
              <div class="check" :class="{'active': configurations.name}"><Checkbox v-show="configurations.name" /></div>
              <span>{{ $t('signatures.appearanceDialog.name') }}</span>
            </div>
            <div class="check-box" @click="configurations.dName = !configurations.dName">
              <div class="check" :class="{'active': configurations.dName}"><Checkbox v-show="configurations.dName" /></div>
              <span>{{ $t('signatures.appearanceDialog.dName') }}</span>
            </div>
            <div class="check-box" @click="configurations.date = !configurations.date">
              <div class="check" :class="{'active': configurations.date}"><Checkbox v-show="configurations.date" /></div>
              <span>{{ $t('signatures.appearanceDialog.date') }}</span>
            </div>
            <div class="check-box" @click="configurations.version = !configurations.version">
              <div class="check" :class="{'active': configurations.version}"><Checkbox v-show="configurations.version" /></div>
              <span>{{ $t('signatures.appearanceDialog.ComPDFKitVersion') }}</span>
            </div>
            <div class="check-box" @click="configurations.logo = !configurations.logo">
              <div class="check" :class="{'active': configurations.logo}"><Checkbox v-show="configurations.logo" /></div>
              <span>{{ $t('signatures.appearanceDialog.logo') }}</span>
            </div>
            <div class="check-box" @click="configurations.location = !configurations.location">
              <div class="check" :class="{'active': configurations.location}"><Checkbox v-show="configurations.location" /></div>
              <span>{{ $t('signatures.appearanceDialog.location') }}</span>
            </div>
            <div class="check-box" @click="configurations.reason = !configurations.reason">
              <div class="check" :class="{'active': configurations.reason}"><Checkbox v-show="configurations.reason" /></div>
              <span>{{ $t('signatures.appearanceDialog.reason') }}</span>
            </div>
            <div class="check-box" @click="configurations.labels = !configurations.labels">
              <div class="check" :class="{'active': configurations.labels}"><Checkbox v-show="configurations.labels" /></div>
              <span>{{ $t('signatures.appearanceDialog.labels') }}</span>
            </div>
          </div>
        </div>

        <div class="right">
          <div class="text-align">
            <span>{{ $t('signatures.appearanceDialog.textAlignment') }}</span>
            <div class="buttons">
              <div :class="{ active: configurations.alignment === 'left' }" @click="configurations.alignment = 'left'"><TextLeft /></div>
              <div :class="{ active: configurations.alignment === 'right' }" @click="configurations.alignment = 'right'"><TextRight /></div>
            </div>
          </div>
          <div class="addition" v-if="configurations.reason || configurations.location">
            <div v-if="configurations.reason">
              <span>{{ $t('signatures.appearanceDialog.reason') }}</span>
              <div class="select-box">
                <select v-model="configurations.reasonText">
                  <option :value="$t('signatures.none')">{{ $t('signatures.none') }}</option>
                  <option :value="$t('signatures.appearanceDialog.docOwner')">{{ $t('signatures.appearanceDialog.docOwner') }}</option>
                  <option :value="$t('signatures.appearanceDialog.approvingDoc')">{{ $t('signatures.appearanceDialog.approvingDoc') }}</option>
                  <option :value="$t('signatures.appearanceDialog.reviewedDoc')">{{ $t('signatures.appearanceDialog.reviewedDoc') }}</option>
                </select>
                <ArrowDown />
              </div>
            </div>
            <div v-if="configurations.location">
              <span>{{ $t('signatures.appearanceDialog.location') }}</span>
              <input type="text" v-model="configurations.locationText" name="signature">
            </div>
          </div>
        </div>
      </div>

      <template #footer class="upper">
        <div class="rect-button white" @click="closePanel('cancel')">{{ $t('cancel') }}</div>
        <div class="rect-button blue" @click="save">{{ $t('ok') }}</div>
      </template>
    </Dialog>
    <DigitalSignCreatePanel v-show="activeDigitalSignCreatePanel" @modifyImage="modifyImage"/>
    <DigitalKeyboardCreatePanel v-if="activeDigitalKeyboardCreatePanel" :text="textContent" @modifyText="modifyText"/>
  </div>
</template>

<script setup>
import { ref, computed, h, watch, getCurrentInstance, reactive, toRaw } from 'vue'
import { useViewerStore } from '@/stores/modules/viewer'
import { useDocumentStore } from '@/stores/modules/document'
import core from '@/core'
import MessageError from '@/assets/icons/icon-message-error.svg'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()

const dialogName = 'signatureAppearanceDialog'
const instance = getCurrentInstance().appContext.app.config.globalProperties
const $t = instance.$t

const useViewer = useViewerStore()
const useDocument = useDocumentStore()

const show = computed(() => useViewer.isElementOpen(dialogName))
const activeSignWay = computed(() => useViewer.getActiveElementTab('signPanel'))
const toolMode = computed(() => useViewer.getToolMode)
const activeTool = computed(() => useDocument.getActiveTool)
const preview = computed(() => useViewer.getDigitalSignaturePreview)
const activeDigitalSignCreatePanel = computed(() => useViewer.isElementOpen('digitalSignCreatePanel'))
const activeDigitalKeyboardCreatePanel = computed(() => useViewer.isElementOpen('digitalKeyboardCreatePanel'))
const subject = computed(() => useViewer.getCertSubject)
const uploadImageEl = ref(null)

const textContent = ref('')
const imageData = ref('')

const configurations = reactive({
  name: true,
  dName: false,
  date: true,
  version: false,
  logo: false,
  location: false,
  reason: false,
  labels: true,
  alignment: 'left',
  reasonText: t('signatures.none'),
  locationText: ''
})

watch(show, (newValue, oldValue) => {
  if (newValue) {
    textContent.value = subject.value?.CN
  }
})

watch(configurations, async (newValue, oldValue) => {
  const content = getContent()
  await getPreview(content)
}, { deep: true })

const modifyImage = async (image) => {
  imageData.value = image
  const content = getContent()
  await getPreview(content)
}

const modifyText = async (text) => {
  textContent.value = text
  const content = getContent()
  await getPreview(content)
}

const getContent = () => {
  let content = ''
  if (configurations.name) content += getValue('name') + '\n'
  if (configurations.date) content += getValue('date') + '\n'
  if (configurations.reason) content += getValue('reason') + '\n'
  if (configurations.dName) content += getValue('dName') + '\n'
  if (configurations.version) content += getValue('version') + '\n'
  if (configurations.location) content += getValue('location')
  return content
}

const getPreview = async (content) => {
  const params = getParams(content)
  params.rect = {
    width: 582,
    height: 187,
    top: 0,
    left: 0,
    right: 582,
    bottom: 187
  }
  const src = await core.getSignature(params)
  useViewer.setDigitalSignaturePreview(src)
}

const getValue = (key) => {
  let text = {}
  switch (key) {
    case 'name':
      text.title = $t('signatures.appearanceDialog.name')
      text.value = subject.value.CN
      break
    case 'date':
      const nowDate= new Date()
      const year = nowDate.getFullYear()
      const month = nowDate.getMonth() + 1 < 10 ? `0${nowDate.getMonth() + 1}` : nowDate.getMonth() + 1
      const day = nowDate.getDate() < 10 ? `0${nowDate.getDate()}` : nowDate.getDate()
      const hour = nowDate.getHours() < 10 ? `0${nowDate.getHours()}` : nowDate.getHours()
      const minute = nowDate.getMinutes() < 10 ? `0${nowDate.getMinutes()}` : nowDate.getMinutes()
      const second = nowDate.getSeconds() < 10 ? `0${nowDate.getSeconds()}` : nowDate.getSeconds()
      const nowDateStr = `${year}.${month}.${day} ${hour}:${minute}:${second}`
      text.title = $t('signatures.appearanceDialog.date')
      text.value = nowDateStr
      break
    case 'reason':
      text.title = $t('signatures.appearanceDialog.reason')
      text.value = configurations.reasonText
      break
    case 'dName':
      const certDataKey = ["CN", "O", "OU", "email", "L", "ST", "C"]
      const dName = certDataKey.map(item => {
        return `${item}=${subject.value[item]}`
      }).join(',')
      text.title = $t('signatures.appearanceDialog.dName')
      text.value = dName
      break
    case 'version':
      text.title = $t('signatures.appearanceDialog.ComPDFKitVersion')
      text.value = '2.5.1'
      break
    case 'location':
      text.title = $t('signatures.appearanceDialog.location')
      text.value = configurations.locationText
      break
    default:
      break;
  }
  return configurations.labels ? `${text.title}: ${text.value}` : text.value
}

const getParams = (content) => {
  const params = {
    content,
    isContentAlginLeft: configurations.alignment !== 'left',
  }
  if (activeSignWay.value !== 'keyboard') {
    params.text = ''
  } else {
    params.text = textContent.value
  }
  if (activeSignWay.value === 'image' || activeSignWay.value === 'trackpad') {
    params.imageBase64 = imageData.value
  }
  if (configurations.logo) {
    params.isDrowLogo = true
    params.logoBase64 = 'data:image/png;base64, '
  }
  if (activeSignWay.value === 'none') {
    params.isDrawOnlyContent = true
  }
  return params
}

const changeActiveSignWay = (way) => {
  if (way === activeSignWay.value && ['image', 'none'].includes(way)) return

  core.handleSign({ flag: 'create', type: 1 })
  useViewer.setActiveSignWay(way)
  if (way === 'trackpad') useViewer.openElement('digitalSignCreatePanel')
  if (way === 'keyboard') useViewer.openElement('digitalKeyboardCreatePanel')
  clearData()
}

const closePanel = (flag) => {
  useViewer.closeElement(dialogName)

  if (activeSignWay.value !== 'trackpad') {
    clearData()
  }
  core.handleSign({ flag: 'reset' })

  document.body.style.overflow = ''

  if (!activeTool.value && flag === 'cancel') useViewer.openElement('selectSignTypeDialog')
  useViewer.setActiveSignWay('keyboard')

  Object.assign(configurations, {
    name: true,
    dName: false,
    date: true,
    version: false,
    logo: false,
    location: false,
    reason: false,
    labels: true,
    alignment: 'left',
    reasonText: $t('signatures.none'),
    locationText: ''
  })
}

const clearData = async () => {
  imageData.value = ''
  if (activeSignWay.value === 'trackpad') core.handleSign({ flag: 'clear' })
  const content = getContent()
  await getPreview(content)
}

const uploadImage = () => {
  const el = uploadImageEl.value
  el.click()
}

const handleFile = async (evt) => {
  let file = evt.target.files[0]
  if (file.size > 1024 * 1024) {
    window.$message.error($t('signatures.uploadError'), {
      duration: 5000,
      icon: () => h('img', { src: MessageError })
    })
    evt.target.value = ''
    return
  }

  const fileReader = new FileReader()
  const imageBase64Promise = new Promise((resolve, reject) => {
    fileReader.addEventListener('load', async (e) => {
      resolve(e.target.result)
    })
    fileReader.addEventListener('error', () => {
      reject('Error reading the local image')
    })

    fileReader.readAsDataURL(file)
  })

  const imageBase64 = await imageBase64Promise
  imageData.value = imageBase64

  const content = getContent()
  await getPreview(content)
}

const save = async () => {
  useViewer.setCommonLoading(true)
  const content = getContent()
  const params = getParams(content)
  const pkcs12 = useDocument.getPkcs12
  await core.handleSign({
    type: 1,
    flag: 'save',
    param: {
      annotation: toRaw(useViewer.getSelectedSignatureField),
      ...params
    },
    pkcs12Buffer: pkcs12.pkcs12Buffer,
    password: pkcs12.password
  })
  closePanel()
  useViewer.setCommonLoading(false)
}

const openDrawPanel = () => {
  if (activeSignWay.value === 'trackpad') useViewer.openElement('digitalSignCreatePanel')
}
</script>

<style lang="scss">
.signature-appearance-dialog {

  .dialog-container {
    padding: 15px 23px;
    max-width: 628px;
    width: 100%;
    border-radius: 0;
    position: relative;

    header {
      
      p {
        font-size: 14px;
        line-height: 16px;
        font-weight: 400;
        color: var(--c-right-side-header-text);
      }

      .close {
        position: absolute;
        top: 8px;
        right: 8px;
        margin: 0;
        cursor: pointer;
      }
    }

    main {
      margin-top: 24px;
      margin-bottom: 20px;
    }

    footer {

      .rect-button {
        border-radius: 4px;
      }
    }
  }

  .sign-popup-header {
    display: flex;
    justify-content: center;

    > div {
      margin: 10px 12px 0;
      height: 30px;
      font-size: 16px;
      font-weight: 400;
      line-height: 24px;
      color: #666;
      cursor: pointer;

      &.active {
        color: var(--c-text);
        border-bottom: 2px solid #4982E6;
      }
    }
  }

  .preview-area {
    position: relative;
    display: flex;
    width: 100%;
    background: #F4F7FF;
    color: #232531;
    font-size: 30px;
    overflow: hidden;
    img {
      width: 100%;
    }
  }

  .preview-options {
    display: flex;
    min-height: 16px;

    span {
      display: inline-block;
      font-size: 12px;
      line-height: 16px;
      color: #1460F3;
      cursor: pointer;

      & + span {
        margin-left: 16px;
      }
    }

    .upload {
      position: relative;
      display: inline-flex;
      align-items: center;
      cursor: pointer;

      input[type="file"] {
        display: none;

        &::file-selector-button {
          cursor: pointer;
        }
      }
    }
  }

  .title {
    margin: 16px 0;
    font-size: 14px;
    line-height: 16px;
    font-weight: 700;
    color: #43474D;
  }

  .configurations {
    display: flex;
    justify-content: space-between;

    span {
      font-size: 14px;
      line-height: 16px;
      white-space: nowrap;
    }

    .left {
      flex: 1;

      .checkboxes {
        display: grid;
        grid-template-columns: auto auto;
        justify-content: space-between;
        grid-gap: 8px 12px;
        margin-right: 48px;
      }

      .addition {
        margin-top: 12px;
        margin-bottom: 38px;
        width: 240px;

        > div {
          display: flex;
          align-items: center;
          justify-content: space-between;

          select,
          input {
            margin-left: 8px;
            flex: 1;
          }

          & + div {
            margin-top: 8px;
          }
        }
      }
    }

    .check-box {
      padding: 6px 0;
      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;
        min-width: 14px;

        &.active {
          border: none;
        }

        svg {
          vertical-align: top;
        }
      }
    }

    .right {
      margin-top: -32px;
      width: 42%;

      .grid-box {
        display: grid;
        grid-template-columns: auto minmax(80px, 192px);
        align-items: center;
        gap: 8px;
      }
    }

    select,
    input {
      padding: 0 8px;
      width: 100%;
      height: 32px;
      background: var(--c-right-side-content-fillbox-bg);
      border: 1px solid var(--c-right-side-content-fillbox-border);
      border-radius: 1px;
      font-size: 14px;
      line-height: 20px;
      color: var(--c-text);
      font-family: 'Helvetica';

      &::placeholder {
        color: var(--c-text);
        opacity: 0.6;
      }
    }

    .select-box {
      position: relative;
      display: flex;
      align-items: center;
      width: 100%;

      svg {
        position: absolute;
        right: 4px;
        pointer-events: none;
      }
    }

    select {
      font-size: 14px;
      padding-right: 20px;
      -webkit-appearance: none;
      -moz-appearance: none;
      appearance: none;
    }

    .text-align {
      margin-top: 8px;
      display: flex;
      justify-content: space-between;
      align-items: center;

      .buttons {
        margin-left: 8px;
        flex: 1;
        display: inline-flex;
        max-width: 140px;
        border: 1px solid #0000001F;
        background: var(--c-right-side-content-fillbox-bg);

        div {
          padding: 7px;
          flex: 1;
          height: 30px;
          text-align: center;
          cursor: pointer;
        }

        .active {
          background: #DDE9FF;

          svg {
            color: #43474D;
          }
        }
      }
    }
  }

  .appearance-dialog footer {
    margin-top: -38px;
  }
}

@media screen and (min-width: 500px) and (max-width: 628px) {
  .signature-appearance-dialog .dialog-container {

    footer {
      margin-top: 0;
    }
  }

  .signature-appearance-dialog .configurations .left {

    .checkboxes {
      margin-right: 20px;
      justify-content: left;
      grid-gap: 8px;
    }

    .addition {
      max-width: 200px;
      width: 100%;
    }
  }
}

@media screen and (max-width: 499px) {
  .signature-appearance-dialog .appearance-dialog {

    .dialog-container {
      padding: 15px 0;

      header {
        padding-left: 23px;
        padding-right: 23px;
      }

      main {
        margin-bottom: 0;
        padding-left: 23px;
        padding-right: 23px;
      }

      footer {
        border-top: 1px solid #ccc;
        margin-top: 0;
        padding-top: 8px;

        > div:last-child {
          margin-right: 23px;
        }
      }
    }

    .configurations {
      flex-direction: column;
      height: 152px;
      overflow: auto;
      padding-bottom: 16px;

      .right {
        margin-top: 16px;
        width: 100%;

        .text-align {
          flex-direction: column;
          align-items: normal;

          .buttons {
            margin-left: 0;
            margin-top: 4px;
          }
        }

        .addition > div {
          margin-top: 8px;
        }
      }
    }
  }
}

@media screen and (max-width: 768px) {
  .signature-appearance-dialog .configurations input {
    font-size: 16px;
  }
}
</style>
