<template>
  <div class="add-digital-file-dialog" v-if="show">
    <Dialog :show="show" :dialogName="dialogName" :close="true">
      <template #header>{{ $t('signatures.addDigitalFileDialog.title') }}</template>

      <p>{{ $t('signatures.addDigitalFileDialog.desc') }}</p>
      <div class="input-file row">
        <span>{{ $t('signatures.addDigitalFileDialog.certificateFile') }}</span>
        <div class="addition">
          <div class="file-input-underbox" @click="uploadFile">
            <span :class="{ 'uploaded': inputFile?.name }">{{ inputFile?.name || $t('signatures.addDigitalFileDialog.uploadFile') }}</span>
            <span class="icon-file"><FileFolder /></span>
          </div>
          <input ref="uploadFileEl" type="file" @change="handleFile" accept=".pfx,.p12" name="digital-signature">
        </div>
      </div>
      <div class="input-pwd row">
        <span>{{ $t('signatures.addDigitalFileDialog.password') }}</span>
        <div>
          <input v-model="password" type="password" :placeholder="$t('signatures.addDigitalFileDialog.enterPassword')" @input="isError && (isError = false)"  name="digital-signature">
          <p v-if="isError" class="error-text">{{ $t('signatures.addDigitalFileDialog.invalidPassword') }}</p>
        </div>
      </div>

      <template #footer>
        <div class="rect-button white" @click="closeDialog('cancel')">{{ $t('cancel') }}</div>
        <div class="rect-button blue" @click="next">{{ $t('continue') }}</div>
      </template>
    </Dialog>
  </div>
</template>

<script setup>
import { computed, ref, watch, getCurrentInstance } from 'vue'
import { useViewerStore } from '@/stores/modules/viewer'
import { useDocumentStore } from '@/stores/modules/document'
import core from '@/core'

const dialogName = 'addDigitalFileDialog'

const useViewer = useViewerStore()
const useDocument = useDocumentStore()
const instance = getCurrentInstance().appContext.app.config.globalProperties
const $t = instance.$t

const show = computed(() => useViewer.isElementOpen(dialogName))

const inputFile = ref(null)
const isError = ref(false)
const password = ref('')

const uploadFileEl = ref(null)

watch(() => show.value, (newVal, oldVal) => {
  if (newVal) {
    inputFile.value = null
    isError.value = false
  }
})

const closeDialog = (flag) => {
  if (flag) document.body.style.overflow = ''
  useViewer.closeElement(dialogName)
  password.value = ''
}

const next = async () => {
  if (!inputFile.value) return
  const result = await validatePwd()
  if (!result) return
  useViewer.setCommonLoading(true)

  const subject = result.subject

  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}`
  const content = `${$t('signatures.appearanceDialog.name')}: ${subject.CN}\n${$t('signatures.appearanceDialog.date')}: ${nowDateStr}`
  const src = await core.getSignature({
    rect: {
      width: 582,
      height: 187,
      top: 0,
      left: 0,
      right: 582,
      bottom: 187
    },
    content,
    text: subject.CN
  })
  useViewer.setCertSubject(subject)
  useViewer.setDigitalSignaturePreview(src)
  useViewer.setCommonLoading(false)
  closeDialog()
  useViewer.openElement('signatureAppearanceDialog')
}

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

    fileReader.readAsArrayBuffer(inputFile.value)
  })

  const pkcs12Buffer = await arrayBufferPromise

  const result = await core.loadCertificates({
    pkcs12Buffer,
    password: password.value
  })

  isError.value = !result

  if (result) {
    useDocument.setPkcs12({
      pkcs12Buffer,
      password: password.value
    })
  }
  return result
}

const uploadFile = () => {
  const el = uploadFileEl.value
  el.click()
}

const handleFile = (e) => {
  const file = e.target.files[0]
  const extension = file?.name.split('.').pop().toLowerCase()
  if (extension !== 'pfx' && extension !== 'p12') return

  inputFile.value = file
  uploadFileEl.value.value = ''
}
</script>

<style lang="scss">
.add-digital-file-dialog {

  .dialog-container {
    max-width: 450px;
    width: 100%;

    .close {
      float: right;
      margin-top: 4px;
    }
  }

  .row {
    display: flex;
    justify-content: space-between;
    > span {
      width: 100px;
      min-width: 100px;
      margin-right: 10px;
      white-space: nowrap;
    }
    > div {
      flex: 1;
    }
  }

  .input-file {
    margin: 20px 0;

    .addition {
      position: relative;
      display: flex;
      align-items: center;
      width: calc(100% - 110px);

      .file-input-underbox {
        position: relative;
        display: flex;
        align-items: center;
        color: var(--c-input-placeholder);
        cursor: pointer;
        span {
          white-space: nowrap;
          overflow: hidden;
        }

        .uploaded {
          color: var(--c-text);
          overflow: hidden;
          text-overflow: ellipsis;
        }

        .icon-file {
          position: absolute;
          right: 0;
          width: 24px;
          height: 100%;
          background-color: var(--c-input-bg);
          pointer-events: none;
        }

        svg {
          position: absolute;
          top: 3px;
          right: 4px;
          pointer-events: none;
          color: var(--c-side-outline-text);
        }
      }
    }
  }

  input,
  .file-input-underbox {
    padding: 0 20px 0 8px;
    width: 100%;
    max-width: 300px;
    height: 24px;
    color: var(--c-text);
    background: var(--c-input-bg);
    border: 1px solid var(--c-right-side-content-fillbox-border);
    border-radius: 1px;
    font-size: 14px;
    line-height: 16px;
  }
  input {
    font-size: 16px;
    &::placeholder {
      font-size: 14px;
      color: var(--c-input-placeholder);
    }
  }

  input[type="file"] {
    display: none;
    position: absolute;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;

    &::file-selector-button {
      cursor: pointer;
    }
  }
  
  .input-pwd {

    .error-text {
      color: red;
    }
  }
}
</style>
