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

    <div :class="{ mobile: isMobile }">
      <div class="paint-container" ref="paintContainer">
        <canvas v-show="activeSignWay === 'trackpad'" id="electronicTrackpadCanvas" :width="canvasWidth" :height="canvasHeight"></canvas>

        <div class="keyboard-paint" v-show="activeSignWay === 'keyboard'">
          <input type="text" :placeholder="$t('signatures.signHere')" v-model="textSgin" name="signature">
        </div>

        <div class="image-paint" v-show="activeSignWay === 'image'">
          <a>{{ $t('signatures.selectFile') }}<input type="file" id="signImageInput" @change="handleFile" accept=".png, .jpg, .jpeg" @click="clickUpload" name="signature"></a>
        </div>
      </div>

      <div class="property-container" v-show="['trackpad', 'keyboard'].includes(activeSignWay)">
        <div v-show="activeSignWay === 'trackpad'" class="width-tool">
          <span v-if="!isMobile">{{ $t('signatures.lineWidth') }}</span>
          <n-slider v-model:value="widthValue" :step="1" :max="10" :min="1" class="width-slider">
            <template #thumb>
              <Slider />
            </template>
          </n-slider>
          <input v-model="widthValue" type="text" pattern="\d*" onkeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))" @blur="handleBlur" name="signature">
        </div>

        <div v-show="activeSignWay === 'keyboard'" class="font-tool">
          <span v-if="!isMobile">{{ $t('font') }}</span>
          <select id="fontFamily" v-model="fontFamily"  v-on:change="handleFontChange">
            <option value="Arial">Arial</option>
            <option value="Courier New">Courier New</option>
            <option value="Times New Roman">Times New Roman</option>
          </select>
        </div>

        <div v-show="activeSignWay === 'trackpad' || activeSignWay === 'keyboard'" class="color-tool">
          <span v-if="!isMobile">{{ $t('color') }}</span>
          <div class="colors-container">
            <span class="cell-container">
              <span class="cell-outer" :class="{ active: areColorsSimilar(fontColor, 'rgb(255, 0, 0)') }" @click="setActiveToolColor('rgb(255, 0, 0)')">
                <span class="cell red"></span></span>
            </span>
            <span class="cell-container">
              <span class="cell-outer" :class="{ active: areColorsSimilar(fontColor, 'rgb(0, 0, 0)') }" @click="setActiveToolColor('rgb(0, 0, 0)')">
                <span class="cell black"></span></span>
            </span>
            <span class="cell-container">
              <span class="cell-outer" :class="{ active: areColorsSimilar(fontColor, 'rgb(45, 119, 250)') }" @click="setActiveToolColor('rgb(45, 119, 250)')">
                <span class="cell blue"></span></span>
            </span>
            <div class="color-picker">
              <div class="preview" :style="{ backgroundColor: colorPickerValue }"></div>
              <n-color-picker
                to=".signatures-popup"
                @complete="onColorPickerComplete"
                @update:value="onColorPickerUpdate"
                :value="colorPickerValue"
                :show-alpha="false"
              >
                <template #label><img src="../Icon/colorful.svg" alt="colorPicker"></template>
              </n-color-picker>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="buttons-container">
      <div class="clear" :class="{ 'button': !isMobile }" @click="clearData">{{ $t('signatures.clear') }}</div>
      <div class="right-btns">
        <div class="button" @click="closePanel('cancel')">{{ $t('cancel') }}</div>
        <div class="button blue" @click="save">{{ $t('signatures.save') }}</div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { toRaw, ref, computed, h, watch, getCurrentInstance, onMounted, nextTick } 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 { NSlider, NColorPicker } from 'naive-ui'
import { isMobile } from '@/helpers/device'
import { areColorsSimilar } from '@/helpers/utils'

const instance = getCurrentInstance().appContext.app.config.globalProperties

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

const show = computed(() => useViewer.isElementOpen('signCreatePanel'))
const activeSignWay = computed(() => useViewer.getActiveElementTab('signPanel'))
const toolMode = computed(() => useViewer.getToolMode)
const activeTool = computed(() => useDocument.getActiveTool)

const textSgin = ref('')
const imageData = ref('')
const widthValue = ref(5)
const fontColor = ref('#000000')
const fontFamily = ref('Courier New')
const paintContainer = ref()
const canvasWidth = ref(578)
const canvasHeight = ref(270)
const colorPickerValue = ref('rgb(0, 0, 0)')

watch(() => toolMode.value, (newValue, oldValue) => {
  if (!(oldValue === 'sign' && newValue === 'view') && newValue !== oldValue) {
    const imgUi = document.getElementById("sign-image-save")
    if (imgUi) imgUi.remove()
  }
})

watch(() => widthValue.value, (newValue, oldValue) => {
  const regex = /^\d+$/
  if ((newValue !== '' && (newValue > 10 || newValue <= 0 || !regex.test(newValue)))) {
    widthValue.value = oldValue
  }
  if (activeSignWay.value === 'trackpad') {
    core.handleSign({
      flag: 'update',
      param: {
        width: widthValue.value,
        color: fontColor.value
      }
    })
  }
})

watch(() => fontColor.value, (newValue, oldValue) => {
  core.handleSign({
    flag: 'update',
    param: {
      width: widthValue.value,
      color: fontColor.value
    }
  })

  if (activeSignWay.value === "keyboard") {
    colorPickerValue.value = fontColor.value
    let inputElement = document.querySelector(".keyboard-paint input")
    if (inputElement) {
      inputElement.style.color = fontColor.value
    }
  }
})

watch(() => show.value, (newValue, oldValue) => {
  if (newValue) {
    if (isMobile) {
      nextTick(() => {
        const { clientWidth, clientHeight } = paintContainer.value
        clientWidth && canvasWidth.value !== clientWidth && (canvasWidth.value = clientWidth)
        clientHeight && canvasHeight.value !== clientHeight && (canvasHeight.value = clientHeight)
      })
    }
    useViewer.setActiveSignWay('keyboard')
    textSgin.value = ''
    core.handleSign({ flag: 'create' })
  }
})

const changeActiveSignWay = (way) => {
  useViewer.setActiveSignWay(way)
  clearData()
  clearProperty()
}

const closePanel = (flag) => {
  useViewer.toggleElement('signCreatePanel')
  if (flag === 'cancel' && activeSignWay.value === 'trackpad') {
    core.handleSign({ flag: 'reset' })
  }
  if (activeSignWay.value !== 'trackpad') {
    clearData()
  }
  clearProperty()
  document.body.style.overflow = 'auto'

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

const clearData = () => {
  if (activeSignWay.value === 'keyboard') {
    textSgin.value = ''
  }
  if (activeSignWay.value === "image" || activeTool.value === 'image') {
    imageData.value = ''
    let imageDiv = document.querySelector('.image-paint')
    let imageInput = document.querySelector('.image-paint input')
    let imageLabel = document.querySelector('.image-paint a')
    let imageShow = document.querySelector('.image-paint img')
    if (imageDiv) {
      if (imageShow) {
        imageDiv.removeChild(imageShow)
        imageInput.value = ''
      }
      if (imageLabel) {
        imageLabel.style.display = "block"
      }
    }
  }
  if (activeSignWay.value === 'trackpad') {
    core.handleSign({ flag: 'clear' })
  }
}

const clearProperty = () => {
  if (fontColor.value !== '#000000') {
    fontColor.value = '#000000'
  }
  if (fontFamily.value !== 'Courier New') {
    fontFamily.value = 'Courier New'
    let inputElement = document.querySelector(".keyboard-paint input")
    if (inputElement) {
      inputElement.style.fontFamily = 'Courier New'
    }
  }
  if (widthValue.value !== 5) {
    widthValue.value = 5
    core.handleSign({
      flag: 'update',
      param: {
        width: widthValue.value,
        color: fontColor.value
      }
    })
  }
}

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

  if (toolMode.value === 'annotation') {
    useDocument.setToolState('image')
    core.handleCreateStatus({
      bool: true,
      fileData: file
    })
  }

  const fileReader = new FileReader()
  fileReader.readAsDataURL(file)
  fileReader.onload = function () {
    imageData.value = fileReader.result
    let imageDiv = document.querySelector('.image-paint')
    let imageLabel = document.querySelector('.image-paint a')
    if (imageDiv) {
      let imgUi = document.createElement("img")
      imgUi.setAttribute("src", imageData.value)
      imgUi.style.maxHeight = 220 + "px"
      imgUi.style.maxWidth = 568 + "px"
      imageLabel.style.display = "none"
      imageDiv.append(imgUi)
    }
    if (activeTool.value === 'image') {
      const image = new Image()
      image.onload = function () {
        save()
      }
      image.src = imageData.value
    }
  }
}

const clickUpload = (e) => {
  if (toolMode.value === 'annotation') {
    useDocument.setToolState('image')
  }
}

const save = () => {
  let showData = ''
  let imgWidth = 0
  let imgHeight = 0
  const selectedSignatureField = useViewer.getSelectedSignatureField

  if ((activeSignWay.value === "image" && imageData.value !== '') || (activeTool.value === 'image' && imageData.value !== '')) {
    showData = imageData.value
  }

  if (activeSignWay.value === "keyboard" && textSgin.value !== '') {
    let canvasItem = document.createElement("canvas")
    let canvasDraw = document.createElement("canvas")

    let ctx = canvasItem.getContext("2d")
    ctx.font = "46px " + fontFamily.value
    let textWidth = ctx.measureText(textSgin.value).width

    canvasDraw.width = textWidth
    canvasDraw.height = 60
    ctx = canvasDraw.getContext("2d")

    ctx.font = "46px " + fontFamily.value
    ctx.fillStyle = fontColor.value
    ctx.fillText(textSgin.value, 0, 50)

    imgWidth = textWidth
    imgHeight = 60
    showData = canvasDraw.toDataURL()
  }

  if (showData) {
    let docDiv = document.querySelector('.content')
    if (docDiv && activeTool.value === 'image') {
      let imgUi = document.getElementById("sign-image-save")
      if (!imgUi) {
        imgUi = document.createElement("img")
        imgUi.style.position = "absolute"
        imgUi.style.zIndex = 10
        imgUi.style.pointerEvents = "none"
        imgUi.style.maxHeight = "220px"
        imgUi.style.maxWidth = "568px"
        imgUi.style.border = "2px solid blue"
        imgUi.style.cursor = "crosshair"
        imgUi.id = "sign-image-save"
      }

      imgUi.setAttribute("src", showData)
      imgUi.style.left = "50%"
      imgUi.style.top = "50%"
      imgUi.style.display = "hidden"

      docDiv.append(imgUi)
      if (imgUi.offsetWidth > 0 && imgUi.offsetHeight > 0) {
        imgWidth = imgUi.offsetWidth
        imgHeight = imgUi.offsetHeight
      }
      let offsetX = Math.min(parseInt(imgWidth / 2), 568 / 2)
      let offsetY = Math.min(parseInt(imgHeight / 2), 220 / 2)
      imgUi.style.left = "calc(50% -" + offsetX + ")"
      imgUi.style.top = "calc(50% -" + offsetY + ")"
      imgUi.style.display = "block"
      docDiv.onmousemove = function (evt) {
        imgUi.style.left = (evt.clientX - offsetX) + "px"
        imgUi.style.top = (evt.clientY - offsetY) + "px"
      }
    } else {
      core.handleSign({
        flag: 'save',
        param: {
          imageBase64: showData,
          annotation: toRaw(selectedSignatureField)
        }
      })
    }
  }
  if (activeSignWay.value === 'trackpad') {
    core.handleSign({
      flag: 'save',
      param: {
        width: widthValue.value,
        color: fontColor.value,
        annotation: toRaw(selectedSignatureField)
      }
    })
  }

  if (activeTool.value === 'image') {
    clearData()
  } else {
    closePanel()
  }
}

const handleBlur = (event) => {
  if (!event.target.value) {
    widthValue.value = 1
  }
}

const setActiveToolColor = (color) => {
  fontColor.value = color
}

const handleFontChange = (evt) => {
  let inputElement = document.querySelector(".keyboard-paint input")
  if (inputElement) {
    inputElement.style.fontFamily = evt.target.value
  }
}

// 颜色选择器选中颜色事件
const onColorPickerComplete = (value) => {
  if (!areColorsSimilar(value, fontColor.value)) setActiveToolColor(value)
}

// 颜色选择器颜色改变事件
const onColorPickerUpdate = (value) => {
  colorPickerValue.value = value
}
</script>

<style lang="scss">
.signatures-popup {
  width: 628px;
  background: #fff;
  box-shadow: 2px 6px 18px rgba(0, 0, 0, 0.2);

  .sign-popup-header {
    display: flex;
    padding: 12px;

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

      &.active {
        color: #000;
        border-bottom: 2px solid #4982E6;
      }
    }
  }

  .paint-container {
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0 24px;
    height: 240px;
    background-color: #F2F3F5;

    .keyboard-paint {
      flex: 1;

      input {
        width: 100%;
        font-size: 46px;
        line-height: 64px;
        font-weight: 400;
        color: #000;
        border: none;
        background: transparent;
        text-align: center;
        font-family: 'Courier New', Courier, monospace;
      }
    }

    .image-paint {
      a {
        position: relative;
        font-size: 14px;
        line-height: 20px;
        font-weight: 400;
        color: #1460F3;
        text-decoration: underline;

        input[type="file"] {
          position: absolute;
          left: 0;
          width: 100%;
          height: 100%;
          opacity: 0;
          font-size: 0;
          cursor: pointer;
        }
      }
    }
  }

  .property-container {
    display: flex;
    justify-content: space-between;
    margin: 18px 24px 38px;
    min-height: 30px;
    font-family: Segoe UI;
    font-size: 14px;
    line-height: 20px;
    color: #000;
    .width-tool {
      display: flex;
      align-items: center;
      .n-slider.width-slider {
        margin-left: 12px;
        margin-right: 8px;
        width: 96px;
        .n-slider-rail {
          border-radius: 0;
          .n-slider-rail__fill {
            background-color: #0078D7;
            border-radius: 0;
          }
        }
        .n-slider-handles {
          left: 0;
          right: 0;
        }
      }
      input {
        padding: 6px;
        width: 72px;
        height: 30px;
        border: 1px solid #B4B4B4;
        outline: none;
        border-radius: 0;
        &:focus {
          border-color: #1460F3;
        }
      }
    }
    .color-tool {
      display: flex;
      align-items: center;
      .colors-container {
        margin-left: 8px;
        padding: 0;
        border: none;
        .cell-container {
          .cell-outer {
            border-width: 1px;
            width: 30px;
            height: 30px;
            &.active {
              .cell {
                width: 22px;
                height: 22px;
              }
            }
            .cell {
              width: 24px;
              height: 24px;
            }
            .red {
              background-color: rgb(255, 0, 0);
            }
            .black {
              background-color: rgb(0, 0, 0);
            }
            .blue {
              background-color: rgb(45, 119, 250);
            }
          }
          & + .cell-container {
            margin-left: 8px;
          }
        }
        .box {
          position: relative;
          background-color: transparent;
          border-radius: 50%;
          overflow: hidden;
          .box-outer {
            width: 100%;
            height: 100%;
            position: absolute;
            border-radius: 50%;
            border: 1px solid #DADBDE;
            background-color: transparent;
          }
          .box-inner {
            height: 110%;
            left: 14px;
            position: absolute;
            border: 1px solid #FA1E5D;
            background-color: #FA1E5D;
            transform: rotate(45deg) translate(0%, 0%);
          }
        }
      }
    }
    .font-tool {
      select {
        margin-left: 8px;
        padding: 4px 4px 4px 8px;
        // width: 232px;
        height: 28px;
        color: #43474D;
        border: 1px solid rgba(0, 0, 0, 0.12);
        border-radius: 1px;
      }
    }
  }

  .buttons-container {
    display: flex;
    justify-content: space-between;
    margin: 12px;

    .button {
      padding: 0 20px;
      height: 32px;
      font-size: 14px;
      font-weight: 400;
      line-height: 20px;
      color: #000;
      background-color: #E2E3E6;
      border-radius: 0;
      margin-right: 0;

      &.disabled {
        color: #999;
        background-color: rgba(0, 0, 0, 0.2);
        opacity: 1;
      }

      &.blue {
        color: #fff;
        background-color: #1460F3;

        &:hover {
          background-color: rgba(20, 96, 243, 0.80);
        }
      }
    }

    .right-btns {
      display: flex;

      .button+.button {
        margin-left: 8px;
      }
    }
  }
}

@media screen and (max-width: 640px) {
  .signatures-popup {
    width: calc(100% - 40px);
    border-radius: 4px;

    .sign-popup-header {
      padding: 0;
      background-color: var(--c-bg);
    }

    .mobile {
      display: flex;
      flex-direction: column-reverse;
    }

    .property-container {
      margin: 24px 25px 0;
      flex-direction: row-reverse;

      .color-tool .colors-container {
        margin-left: 0;
      }
    }

    .paint-container {
      margin: 24px 20px;
      background-color: var(--c-side-bg);
      border: 1px solid var(--c-header-border);
      border-radius: 4px;

      .keyboard-paint input {
        font-family: Segoe UI;
        font-size: 30px;

        &::placeholder {
          color: rgba(0, 0, 0, 0.3);
        }
      }
    }

    .buttons-container {
      margin: 0 20px 16px;
      align-items: center;

      .clear {
        font-size: 14px;
      }
    }
  }
}

@media screen and (max-width: 450px) {
  .signatures-popup .property-container .color-tool .colors-container {

    span {
      display: none;
    }

    .color-picker {
      margin-left: 0;
      height: 30px;
    }
  }
}
</style>
