<Service ref:Uploads
  service="Uploads"
  on:update="_onUploadsUpdate()"
  />

<div class="dropzone {{ dragging ? 'dropzone--dragging' : '' }}" ref:dropzone>
  <div class="dropzone_stats">
    {{#if uploading.total > 0}}
      <strong>Uploading {{ uploading.now }} / {{ uploading.total }}</strong>
    {{else}}
      <svg class="icon icon-upload"><use xlink:href="#icon-upload"></use></svg>
      <br/>
      <span><strong>{{ prettyUsed }}</strong> out of <strong>{{ prettyQuota }}</strong> used.</span>
    {{/if}}
  </div>
</div>

<style>
  .dropzone {
    display: flex;
    align-items: center;
    justify-content: center;

    background: #fff;
    border: 1px dashed #b8b8b8;

    font-size: 14px;
    font-family: "ProximaNova-Regular";
    text-align: center;
    cursor: pointer;

    transition: top 300ms ease-in, background 150ms ease-in 50ms;
  }

  .dropzone_stats {
    pointer-events: none;
  }

  .dropzone_stats span {
    transition: opacity 150ms ease-in 150ms;
  }

  .dropzone:hover {
    border-color: #888;
  }

  .dropzone.dropzone--dragging,
  .dropzone:hover {
    background: #f4f5f8;
  }

  .dropzone--dragging .dropzone_stats span {
    opacity: 0;
    transition: opacity 150ms ease-in;
  }

  .dropzone--dragging .dropzone_stats .icon {
    transform: scale(3) translateY(20%);
  }

  .dz-message, .dz-preview {
    display: none
  }

  .icon {
    fill: #929292;
    transition: transform 300ms ease-in;
  }
</style>

<script>
import Dropzone from 'dropzone';
import Service from './service.html';
import prettyBytes from 'pretty-bytes';

export default {
  components: { Service },
  data() {
    return {
      filetypes: '*',
      used: 0,
      quota: 0,
      uploading: { total: 0, now: 0 },
      dragging: false,
      maxFilesize: 10,
      instanceId: 0,
    };
  },
  computed: {
    prettyQuota: quota => prettyBytes(quota),
    prettyUsed: used => prettyBytes(used),
  },
  oncreate() {
    this.Uploads = this.refs.Uploads.instance();
    this.set({ quota: this.Uploads.quota, used: this.Uploads.used });

    this.dropzone = new Dropzone(this.refs.dropzone, {
      acceptedFiles: this.get('filetypes'),
      url: this.Uploads.getUploadURL(),
      headers: this.Uploads.getAuthHeaders(),
      accept: this.Uploads.accept.bind(this.Uploads),
      uploadMultiple: false,
      maxFilesize: this.get('maxFilesize'),
    });

    const events = {
      dragenter: this._onDragEnter.bind(this),
      dragleave: this._onDragLeave.bind(this),
      drop: this._onDragLeave.bind(this),
      addedfile: this._onAddedFile.bind(this),
      thumbnail: this._onThumbnail.bind(this),
      error: this._onError.bind(this),
      uploadprogress: this._onUploadProgress.bind(this),
      processing: this._updateFileState.bind(this, 'processing'),
      sending: this._updateFileState.bind(this, 'sending'),
      success: this._updateFileState.bind(this, 'success'),
      complete: this._updateFileState.bind(this, 'complete'),
      canceled: this._updateFileState.bind(this, 'canceled'),
      complete: this._onComplete.bind(this),
      totaluploadprogress: this._onTotalUploadProgress.bind(this),
      queuecomplete: this._onQueueComplete.bind(this),
    };

    for (const event in events) {
      this.dropzone.on(event, events[event]);
    }
  },
  // TODO implement ondestroy
  methods: {
    _onDragEnter() {
      this.set({ dragging: true });
      this.fire('dragging', true);
    },
    _onDragLeave() {
      this.set({ dragging: false });
      this.fire('dragging', false);
    },
    _onAddedFile(file) {
      this.fire('new');
      this.Uploads.upload(file);
    },
    _onThumbnail(file, thumbnail) {
      this.Uploads.setThumbnail(file, thumbnail);
    },
    _onError(file, error) {
      console.error(error);
      this.fire('error', { message: error });
      this.Uploads.setError(file, error);
    },
    _onUploadProgress(file, percentage, size) {
      this.Uploads.setUploadProgress(file, percentage, size);
    },
    _onComplete(file) {
      this.Uploads.uploadComplete(file, this.get('instanceId'));
    },
    _updateFileState(state, file) {
      this.Uploads.setUploadState(file, state);
    },
    _onTotalUploadProgress() {
      const total = this.dropzone.getAcceptedFiles().length;
      const queued = this.dropzone.getQueuedFiles().length;
      const uploading = this.dropzone.getUploadingFiles().length;
      const now = total - queued;

      this.set({ uploading: { total, now } });
    },
    _onQueueComplete() {
      this.dropzone.removeAllFiles();
    },
    _onUploadsUpdate() {
      this.set({
        quota: this.Uploads.quota,
        used: this.Uploads.used,
      });
    },
  },
};
</script>
