<i18n>
{
  "th": {
    "drop": "วางไฟล์เพื่ออัพโหลด",
    "btn": {
      "upload": {
        "image": "เลือกรูปภาพ",
        "file": "เลือกไฟล์"
      },
      "submit": "ยืนยัน",
      "cancel": "ยกเลิก"
    }
  },
  "en": {
    "drop": "Drop files to upload",
    "btn": {
      "upload": {
        "image": "Select image",
        "file": "Select file"
      },
      "submit": "Submit",
      "cancel": "Cancel"
    }
  }
}
</i18n>

<template>
  <div
    class="upload-dd"
    :style="{ width, height }">
    <div
      v-show="$refs.upload && $refs.upload.dropActive"
      class="drop-active">
      <h3>{{ $t('drop') }}</h3>
    </div>
    <div
      v-show="!edit"
      class="upload-dd__wrapper text-center p-2">
      <v-hover v-slot="{ hover }">
        <label
          ref="labelupload"
          class="upload-label d-flex flex-column justify-center"
          :for="`${name}-upload`">
          <div
            v-if="value"
            class="d-flex h-100">
            <v-img
              v-if="acceptType === 'image'"
              class="bg-transparent"
              :src="value"
              contain>
              <v-expand-transition>
                <div
                  v-if="hover"
                  class="overlay d-flex align-center justify-center gap-2 transition-fast-in-fast-out"
                  @click.prevent.stop>
                  <v-btn
                    color="#ffffff"
                    fab
                    small
                    depressed
                    @click="$refs.labelupload.click()">
                    <v-icon small>
                      mdi-upload
                    </v-icon>
                  </v-btn>
                  <v-btn
                    v-if="showDelete"
                    color="error"
                    fab
                    dark
                    small
                    depressed
                    @click.prevent="remove()">
                    <v-icon small>
                      $snt_trash
                    </v-icon>
                  </v-btn>
                </div>
              </v-expand-transition>
            </v-img>
            <div v-else>
              {{ value }}
            </div>
          </div>
          <div v-else>
            <v-icon
              class="secondary--text text--lighten-2"
              small>mdi-plus</v-icon>
            <div class="secondary--text text--lighten-3">
              {{ placeholder || (acceptType === 'image' ? $t('btn.upload.image') : $t('btn.upload.file')) }}
            </div>
          </div>
        </label>
      </v-hover>
    </div>
    <div class="upload-input text-center p-2">
      <file-upload
        ref="upload"
        v-model="files"
        :extensions="extensions"
        :accept="accept"
        :name="`${name}-upload`"
        :drop="!edit"
        @input-filter="inputFilter"
        @input-file="inputFile" />
    </div>
    <div
      v-if="files.length && edit"
      class="h-100 p-relative">
      <div
        v-if="files.length"
        class="upload-edit-image">
        <div
          v-if="acceptType === 'image'"
          class="d-flex h-100">
          <v-img
            ref="editImage"
            class="bg-transparent"
            :src="files[0].url"
            contain />
        </div>
        <div v-else>
          {{ files[0].name }}
        </div>
      </div>
      <div
        v-if="error"
        class="error--text pa-1">
        {{ error }}
      </div>
      <div class="upload-action text-center pa-3">
        <v-btn
          type="submit"
          class="mr-1"
          color="primary"
          small
          rounded
          depressed
          @click.prevent="editSave($event)">
          {{ $t('btn.submit') }}
        </v-btn>
        <v-btn
          type="button"
          color="#ffffff"
          depressed
          rounded
          small
          @click.prevent="$refs.upload.clear">
          {{ $t('btn.cancel') }}
        </v-btn>
      </div>
    </div>
    <div v-else>
      <div
        v-if="error"
        class="caption error--text pa-1">
        {{ error }}
      </div>
    </div>
  </div>
</template>

<script>
/* eslint-disable consistent-return */
/* eslint-disable no-param-reassign */
import FileUpload from 'vue-upload-component'

export default {
  components: {
    FileUpload
  },
  props: {
    name: {
      type: String,
      required: true
    },
    value: {
      type: String,
      default: () => null
    },
    confirm: {
      type: Boolean,
      default: true
    },
    showDelete: {
      type: Boolean,
      default: false
    },
    acceptType: {
      type: String,
      validator: (val) => ['image', 'excel'].includes(val),
      default: 'image'
    },
    placeholder: {
      type: String,
      default: null
    },
    height: {
      type: String,
      default: '100%'
    },
    width: {
      type: String,
      default: '100%'
    },
    size: {
      type: Number,
      default: 10240
    }
  },
  data () {
    return {
      files: [],
      edit: false,
      error: ''
    }
  },
  computed: {
    extensions () {
      switch (this.acceptType) {
      case 'excel':
        return 'csv,xls,xlsx'
      default:
        return 'gif,jpg,jpeg,png,webp'
      }
    },
    accept () {
      switch (this.acceptType) {
      case 'excel':
        return '.csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel'
      default:
        return 'image/png,image/gif,image/jpeg,image/webp'
      }
    }
  },
  methods: {
    remove () {
      this.$emit('remove', true)
    },
    editSave () {
      const file = this.files[0]
      this.$emit('submit', file)
      this.edit = false
    },
    inputFile (newFile, oldFile) {
      if (newFile && !oldFile) {
        this.$nextTick(() => {
          if (this.confirm) {
            this.edit = true
          } else {
            this.editSave()
          }
        })
      }
      if (!newFile && oldFile) {
        this.edit = false
      }
    },
    inputFilter (newFile, oldFile, prevent) {
      this.error = null
      if (newFile && !oldFile) {
        if (this.acceptType === 'excel') {
          if (!/\.(csv|xls|xlsx)$/i.test(newFile.name)) {
            this.error = '* ประเภทไฟล์ excel เท่านั้น'
            return prevent()
          }
        } else if (this.acceptType === 'image') {
          if (!/\.(gif|jpg|jpeg|png|webp)$/i.test(newFile.name)) {
            this.error = '* ประเภทไฟล์ รูปภาพ เท่านั้น'
            return prevent()
          }
        }
        const sizeInKb = Math.floor(newFile.size / 1024)
        if (this.size < sizeInKb) {
          const maxSizeInMb = Math.floor(this.size / 1024)
          this.error = maxSizeInMb > 0 ? `* ขนาดไม่เกิน ${ maxSizeInMb } MB` : `* ขนาดไม่เกิน ${ this.size } KB`
          return prevent()
        }
      }
      if (newFile && (!oldFile || newFile.file !== oldFile.file)) {
        newFile.url = ''
        const URL = window.URL || window.webkitURL
        if (URL && URL.createObjectURL) {
          newFile.url = URL.createObjectURL(newFile.file)
        }
      }
    }
  }
}
</script>
<style lang="scss" scoped>
  .upload-dd {
    &__wrapper {
      height: 100%;
      width: 100%;
    }
    ::v-deep {
      .upload-label {
        display:block;
        height: 100%;
        width: 100%;
        border: 1px dotted #c6c6c6;
        background: #F9F9F9;
        cursor: pointer;
      }
      .text-center .btn {
        margin: 0 .5rem
      }
      .upload-edit-image {
        height: 100%;
        max-width: 100%
      }
      .drop-active {
        top: 0;
        bottom: 0;
        right: 0;
        left: 0;
        position: absolute;
        z-index: 1;
        opacity: .6;
        text-align: center;
        background: #000;
      }
      .drop-active h3 {
        margin: -.5em 0 0;
        position: absolute;
        top: 50%;
        left: 0;
        right: 0;
        -webkit-transform: translateY(-50%);
        -ms-transform: translateY(-50%);
        transform: translateY(-50%);
        font-size: 40px;
        color: #fff;
        padding: 0;
      }
    }
    .upload-action {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
    }
    .upload-input {
      display: none;
    }
    .overlay {
      height: 100%;
      background-color: rgba(245, 245, 245, .96);
    }
  }

</style>
