<template>
  <div :id="id" :ref="id" :action="url" class="dropzone">
    <input type="file" name="file">
  </div>
</template>

<script>
import Dropzone from 'dropzone';
import 'dropzone/dist/dropzone.css';

Dropzone.autoDiscover = false;

export default {
  props: {
    id: {
      type: String,
      required: true,
    },
    url: {
      type: String,
      required: true,
    },
    clickable: {
      type: Boolean,
      default: true,
    },
    defaultMsg: {
      type: String,
      default: 'Upload image',
    },
    acceptedFiles: {
      type: String,
      default: '',
    },
    thumbnailHeight: {
      type: Number,
      default: 200,
    },
    thumbnailWidth: {
      type: Number,
      default: 200,
    },
    showRemoveLink: {
      type: Boolean,
      default: true,
    },
    maxFilesize: {
      type: Number,
      default: 2,
    },
    maxFiles: {
      type: Number,
      default: 3,
    },
    autoProcessQueue: {
      type: Boolean,
      default: true,
    },
    useCustomDropzoneOptions: {
      type: Boolean,
      default: false,
    },
    defaultImg: {
      default: '',
      type: [String, Array],
    },
    couldPaste: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      dropzone: '',
      initOnce: true,
    };
  },
  watch: {
    defaultImg(val) {
      if (val.length === 0) {
        this.initOnce = false;
        return;
      }
      if (!this.initOnce) {
        return;
      }
      this.initImages(val);
      this.initOnce = false;
    },
  },
  mounted() {
    const element = document.getElementById(this.id);
    const vm = this;
    this.dropzone = new Dropzone(element, {
      clickable: this.clickable,
      thumbnailWidth: this.thumbnailWidth,
      thumbnailHeight: this.thumbnailHeight,
      maxFiles: this.maxFiles,
      maxFilesize: this.maxFilesize,
      dictRemoveFile: 'Remove',
      addRemoveLinks: this.showRemoveLink,
      acceptedFiles: this.acceptedFiles,
      autoProcessQueue: this.autoProcessQueue,
      dictDefaultMessage:
        '<i style="margin-top: 3em;display: inline-block" class="material-icons">' + this.defaultMsg + '</i><br>Drop files here to upload',
      dictMaxFilesExceeded: 'Only one picture',
      previewTemplate:
        '<div class="dz-preview dz-file-preview">' +
        '<div class="dz-image" style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" >' +
        '<img style="width:' + this.thumbnailWidth + 'px;height:' + this.thumbnailHeight + 'px" data-dz-thumbnail />' +
        '</div>' +
        '<div class="dz-details">' +
        '<div class="dz-size"><span data-dz-size></span></div>' +
        '<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>' +
        '<div class="dz-error-message"><span data-dz-errormessage></span></div>' +
        '<div class="dz-success-mark"><i class="material-icons">done</i></div>' +
        '<div class="dz-error-mark"><i class="material-icons">error</i></div>' +
        '</div>' +
        '</div>',
      init() {
        const val = vm.defaultImg;
        if (!val) {
          return;
        }
        if (Array.isArray(val)) {
          if (val.length === 0) {
            return;
          }
          val.map((v, i) => {
            const mockFile = { name: 'name' + i, size: 12345, url: v };
            this.options.addedfile.call(this, mockFile);
            this.options.thumbnail.call(this, mockFile, v);
            mockFile.previewElement.classList.add('dz-success');
            mockFile.previewElement.classList.add('dz-complete');
            vm.initOnce = false;
            return true;
          });
        } else {
          const mockFile = { name: 'name', size: 12345, url: val };
          this.options.addedfile.call(this, mockFile);
          this.options.thumbnail.call(this, mockFile, val);
          mockFile.previewElement.classList.add('dz-success');
          mockFile.previewElement.classList.add('dz-complete');
          vm.initOnce = false;
        }
      },
      accept: (file, done) => {
        done();
      },
      sending: (file, xhr, formData) => {
        vm.initOnce = false;
      },
    });

    if (this.couldPaste) {
      document.addEventListener('paste', this.pasteImg);
    }

    this.dropzone.on('success', file => {
      vm.$emit('dropzone-success', file, vm.dropzone.element);
    });
    this.dropzone.on('addedfile', file => {
      vm.$emit('dropzone-fileAdded', file);
    });
    this.dropzone.on('removedfile', file => {
      vm.$emit('dropzone-removedFile', file);
    });
    this.dropzone.on('error', (file, error, xhr) => {
      vm.$emit('dropzone-error', file, error, xhr);
    });
    this.dropzone.on('successmultiple', (file, error, xhr) => {
      vm.$emit('dropzone-successmultiple', file, error, xhr);
    });
  },
  destroyed() {
    document.removeEventListener('paste', this.pasteImg);
    this.dropzone.destroy();
  },
  methods: {
    removeAllFiles() {
      this.dropzone.removeAllFiles(true);
    },
    processQueue() {
      this.dropzone.processQueue();
    },
    pasteImg(event) {
      const items = (event.clipboardData || event.originalEvent.clipboardData).items;
      if (items[0].kind === 'file') {
        this.dropzone.addFile(items[0].getAsFile());
      }
    },
    initImages(val) {
      if (!val) {
        return;
      }
      if (Array.isArray(val)) {
        val.map((v, i) => {
          const mockFile = { name: 'name' + i, size: 12345, url: v };
          this.dropzone.options.addedfile.call(this.dropzone, mockFile);
          this.dropzone.options.thumbnail.call(this.dropzone, mockFile, v);
          mockFile.previewElement.classList.add('dz-success');
          mockFile.previewElement.classList.add('dz-complete');
          return true;
        });
      } else {
        const mockFile = { name: 'name', size: 12345, url: val };
        this.dropzone.options.addedfile.call(this.dropzone, mockFile);
        this.dropzone.options.thumbnail.call(this.dropzone, mockFile, val);
        mockFile.previewElement.classList.add('dz-success');
        mockFile.previewElement.classList.add('dz-complete');
      }
    },
  },
};
</script>

<style scoped>
.dropzone {
  border: 2px solid #e5e5e5;
  font-family: 'Roboto', sans-serif;
  color: #777;
  transition: background-color 0.2s linear;
  padding: 5px;
}

.dropzone:hover {
  background-color: #f6f6f6;
}

i {
  color: #ccc;
}

.dropzone .dz-image img {
  width: 100%;
  height: 100%;
}

.dropzone input[name='file'] {
  display: none;
}

.dropzone .dz-preview .dz-image {
  border-radius: 0px;
}

.dropzone .dz-preview:hover .dz-image img {
  transform: none;
  -webkit-filter: none;
  width: 100%;
  height: 100%;
}

.dropzone .dz-preview .dz-details {
  bottom: 0px;
  top: 0px;
  color: white;
  background-color: rgba(33, 150, 243, 0.8);
  transition: opacity 0.2s linear;
  text-align: left;
}

.dropzone .dz-preview .dz-details .dz-filename span,
.dropzone .dz-preview .dz-details .dz-size span {
  background-color: transparent;
}

.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
  border: none;
}

.dropzone .dz-preview .dz-details .dz-filename:hover span {
  background-color: transparent;
  border: none;
}

.dropzone .dz-preview .dz-remove {
  position: absolute;
  z-index: 30;
  color: white;
  margin-left: 15px;
  padding: 10px;
  top: inherit;
  bottom: 15px;
  border: 2px white solid;
  text-decoration: none;
  text-transform: uppercase;
  font-size: 0.8rem;
  font-weight: 800;
  letter-spacing: 1.1px;
  opacity: 0;
}

.dropzone .dz-preview:hover .dz-remove {
  opacity: 1;
}

.dropzone .dz-preview .dz-success-mark,
.dropzone .dz-preview .dz-error-mark {
  margin-left: -40px;
  margin-top: -50px;
}

.dropzone .dz-preview .dz-success-mark i,
.dropzone .dz-preview .dz-error-mark i {
  color: white;
  font-size: 5rem;
}
</style>