<template>
  <vue-dropzone
    :options="dropzoneOptions"
    ref="el"
    id="postdropzone"
    class="ds-card-image"
    :use-custom-slot="true"
    @vdropzone-error="verror"
    @vdropzone-thumbnail="transformImage"
  >
    <div class="crop-overlay" ref="cropperOverlay" v-show="showCropper">
      <ds-button @click="cropImage" class="crop-confirm" primary>
        {{ $t('contribution.teaserImage.cropperConfirm') }}
      </ds-button>
      <ds-button @click="cancelCrop" class="crop-cancel" icon="close"></ds-button>
    </div>
    <div
      :class="{
        'hc-attachments-upload-area-post': true,
        'hc-attachments-upload-area-update-post': contribution,
      }"
    >
      <slot></slot>
      <div
        :class="{
          'hc-drag-marker-post': true,
          'hc-drag-marker-update-post': contribution,
        }"
      >
        <ds-icon name="image" size="xxx-large" />
      </div>
    </div>
  </vue-dropzone>
</template>

<script>
import vueDropzone from 'nuxt-dropzone'
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.css'

export default {
  components: {
    vueDropzone,
  },
  props: {
    contribution: { type: Object, default: () => {} },
  },
  data() {
    return {
      dropzoneOptions: {
        url: () => '',
        maxFilesize: 5.0,
        previewTemplate: this.template(),
      },
      image: null,
      file: null,
      editor: null,
      cropper: null,
      thumbnailElement: null,
      oldImage: null,
      error: false,
      showCropper: false,
    }
  },
  watch: {
    error() {
      let that = this
      setTimeout(function() {
        that.error = false
      }, 2000)
    },
  },
  methods: {
    template() {
      return `<div class="dz-preview dz-file-preview">
                <div class="dz-image">
                  <div data-dz-thumbnail-bg></div>
                </div>
              </div>
	     `
    },
    verror(file, message) {
      this.error = true
      this.$toast.error(file.status, message)
    },
    transformImage(file) {
      this.file = file
      this.showCropper = true
      this.initEditor()
      this.initCropper()
    },
    initEditor() {
      this.editor = this.$refs.cropperOverlay
      this.clearImages()
      this.thumbnailElement.appendChild(this.editor)
    },
    clearImages() {
      this.thumbnailElement = document.querySelectorAll('#postdropzone')[0]
      const thumbnailPreview = document.querySelectorAll('.thumbnail-preview')[0]
      if (thumbnailPreview) thumbnailPreview.remove()
      const contributionImage = document.querySelectorAll('.contribution-image')[0]
      this.oldImage = contributionImage
      if (contributionImage) contributionImage.remove()
    },
    initCropper() {
      this.image = new Image()
      this.image.src = URL.createObjectURL(this.file)
      this.editor.appendChild(this.image)
      this.cropper = new Cropper(this.image, { zoomable: false, autoCropArea: 0.9 })
    },
    cropImage() {
      this.showCropper = false
      const canvas = this.cropper.getCroppedCanvas()
      canvas.toBlob(blob => {
        this.setupPreview(canvas)
        this.removeCropper()
        const croppedImageFile = new File([blob], this.file.name, { type: 'image/jpeg' })
        this.$emit('addTeaserImage', croppedImageFile)
      }, 'image/jpeg')
    },
    setupPreview(canvas) {
      this.image = new Image()
      this.image.src = canvas.toDataURL()
      this.image.classList.add('thumbnail-preview')
      this.thumbnailElement.appendChild(this.image)
    },
    cancelCrop() {
      this.showCropper = false
      if (this.oldImage) this.thumbnailElement.appendChild(this.oldImage)
      this.removeCropper()
    },
    removeCropper() {
      this.editor.removeChild(document.querySelectorAll('.cropper-container')[0])
    },
  },
}
</script>
<style lang="scss">
#postdropzone {
  width: 100%;
  min-height: 500px;
  background-color: $background-color-softest;
}

.hc-attachments-upload-area-post {
  position: relative;
  display: flex;
  justify-content: center;
  cursor: pointer;
}

.hc-attachments-upload-area-update-post img {
  object-fit: cover;
  object-position: center;
  display: block;
  width: 100%;
}

.hc-attachments-upload-area-update-post:hover {
  opacity: 0.7;
}

.hc-drag-marker-post {
  position: absolute;
  width: 122px;
  height: 122px;
  border-radius: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 180px 5px;
  color: hsl(0, 0%, 25%);
  transition: all 0.2s ease-out;
  font-size: 60px;
  background-color: $background-color-softest;
  opacity: 0.65;

  &:before {
    position: absolute;
    content: '';
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    border-radius: 100%;
    border: 20px solid $text-color-base;
    visibility: hidden;
  }

  &:after {
    position: absolute;
    content: '';
    top: 10px;
    left: 10px;
    bottom: 10px;
    right: 10px;
    border-radius: 100%;
    border: $border-size-base dashed $text-color-base;
  }

  .hc-attachments-upload-area-post:hover & {
    opacity: 1;
  }
}

.hc-drag-marker-update-post {
  opacity: 0;
}

.contribution-form-footer {
  border-top: $border-size-base solid $border-color-softest;
}

.crop-overlay {
  max-height: 2000px;
  position: relative;
  width: 100%;
  background-color: #000;
}

.crop-confirm {
  position: absolute;
  left: 10px;
  top: 10px;
  z-index: 1;
}
.crop-cancel {
  position: absolute;
  right: 10px;
  top: 10px;
  z-index: 1;
}
</style>
