<template>
  <div class="upload-dragdrop-zone">
    <div class="upload">

      <div v-show="!disabled && $refs.upload && $refs.upload.dropActive" class="drop-active">
        <h3>Drop files to upload</h3>
      </div>

      <v-container grid-list-md pa-0>
        <v-layout wrap align-center>

          <v-flex xs1 text-xs-left>
            <div class="upload-btn">
              <file-upload
                ref="upload"
                v-model="files"
                :custom-action="uploadFile"
                :drop="!disabled"
                :class="['v-btn v-btn--floating fab dark ma-0 primary', disabled ? 'disabled' : '']"
                @input-filter="inputFilter">
                <v-tooltip :disabled="!disabled" top>
                  <v-icon
                    slot="activator"
                    dark>
                    attach_file
                  </v-icon>
                  <span>Can't upload if Projects or Description fields are empty </span>
                </v-tooltip>
              </file-upload>
            </div>
          </v-flex>

          <v-flex xs5 text-xs-left>
            <v-input
              ref="uploadFileInput"
              :prepend-icon="icon"
              :hint="hint"
              :class="`ma-0 ${iconClass}`"
              :error-messages="errorMessages"
              persistent-hint
              @click:prepend="prependAction">
              <label for="file">
                {{ $get(file, 'name', '') || "Drag or select file to upload" }}
              </label>
            </v-input>
          </v-flex>

          <v-flex xs6 text-xs-left>
            <v-input
              v-show="$get(status, 'summary', '')"
              hint="Summary of new data"
              persistent-hint
              class="ma-0">
              {{ $get(status, 'summary', '') }}
            </v-input>
          </v-flex>

        </v-layout>
      </v-container>
    </div>
  </div>
</template>

<script>
import Vue from 'vue'
import FileUpload from 'vue-upload-component'
import { SHOW_ALERT } from '@/store/actions/alert'

export default {
  name: 'UploadFile',
  components: {
    FileUpload
  },
  props: {
    disabled: Boolean,
    loading: Boolean,
    status: Object
  },
  data () {
    return {
      files: []
    }
  },
  computed: {
    file () {
      return this.files.length ? this.files[0] : null
    },
    fileHasErrors () {
      return this.$get(this.status, 'errors', []).length
    },
    hint () {
      return (
        this.file
          ? (this.loading
            ? 'uploading and processing form...'
            : this.$formatSize(this.file.size)
          ) : '0 KB'
      )
    },
    icon () {
      return !this.file ? 'clear' : (
        this.loading ? 'loop' : (
          !this.fileHasErrors ? 'done' : 'clear'
        )
      )
    },
    prependAction () {
      return !this.loading && this.fileHasErrors
        ? this.removeFile
        : this.emptyMethod
    },
    iconClass () {
      return !this.file ? 'file-empty' : (
        this.loading ? 'file-uploading' : (
          !this.fileHasErrors ? 'file-correct' : 'file-error'
        )
      )
    },
    errorMessages () {
      let errors = []
      if (this.fileHasErrors) {
        this.status.errors.forEach(error => {
          Object.keys(error).forEach(type => {
            error[type].forEach(errorType => {
              errors.push(errorType)
            })
          })
        })
      }
      return errors
    }
  },
  watch: {
    disabled: {
      immediate: true,
      handler () {
        Vue.nextTick(() => {
          let fileInput = this.$refs.upload.$children.filter(
            el => el.$el.id === 'file'
          )[0]
          fileInput.$el.disabled = this.disabled
        })
      }
    }
  },
  methods: {
    inputFilter (newFile, oldFile, prevent) {
      if (newFile && !oldFile) {
        if (!/\.(xlsx|xls)$/i.test(newFile.name)) {
          this.$store.dispatch(SHOW_ALERT, {
            error: 'Form format is not valid'
          })
          return prevent()
        }
        this.$refs.upload.active = false
        this.$emit('reset-status')
      }
      // Create a blob field
      newFile.blob = ''
      let URL = window.URL || window.webkitURL
      if (URL && URL.createObjectURL) {
        newFile.blob = URL.createObjectURL(newFile.file)
      }
      // Trigger upload with custom-action
      this.$refs.upload.active = true
    },
    removeFile () {
      this.files = []
      this.$refs.upload.active = false
      this.$emit('reset-status')
    },
    async uploadFile () {
      this.$emit('upload-file', this.file.file)
    },
    emptyMethod () {
      return ''
    }
  }
}
</script>

<style lang="scss">

.upload-dragdrop-zone label.btn {
  margin-bottom: 0;
  margin-right: 1rem;
}
.upload-dragdrop-zone .drop-active {
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  position: fixed;
  z-index: 9999;
  opacity: .6;
  text-align: center;
  background: #000;
}
.upload-dragdrop-zone .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;
}
@keyframes rotating {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
.file {
  &-empty i {
    opacity: 0 !important;
    cursor: default !important;
  }
  &-correct i {
    color: green !important;
    cursor: default !important;
  }
  &-error i {
    color: red !important;
  }
  &-uploading i {
    color: blue !important;
    animation: rotating 2s linear infinite reverse;
    cursor: default !important;
  }
}
label {
  cursor: pointer;
}
.v-dialog {
  z-index: auto;
}
.upload {
  i {
    margin-top: 15px;
  }
  .disabled {
    box-shadow: none !important;
    opacity: 0.65;
    cursor: not-allowed;
    &:hover {
      background: transparent;
    }
  }
}
</style>
