<template>
  <div class="upload-image">
    <div
      class="
        upload-image__drag-area d-flex
        justify-content-center
        d-flex
        flex-column
        align-items-center"
      v-if="!image && !loading"
      @dragover.prevent
      @drop.prevent="$_onDrop"
    >
    <div class="cloud-icon">
      <font-awesome-icon icon="cloud-upload-alt" class="align-self-center" size="4x" />
    </div>
    <div class="
      d-flex
      align-items-center
      justify-content-center
      flex-column
      max-middle-text"
    >
      <div>Solte sua foto em qualquer</div>
      <div>lugar para atualizar</div>
      <div>ou</div>
      <b-button class="btn-default btn-blue btn shadow-none border-0" @click="$_onClick">
        Escolher Foto
      </b-button>
      <span class="min-middle-text mt-1">Tamanho máximo de upload de arquivo: 10WMB</span>
    </div>
    </div>
    <div
      v-else
      class="d-block w-100 mh-100 d-flex flex-wrap justify-content-center upload-image__preview"
      :class="preview_modifiers"
    >
      <img class="w-100" :src="image" alt="image-preview" />
    </div>
  </div>
</template>

<script>
import NProgress from 'nprogress/nprogress';
import { readFile, compressImage } from '../../utils/image';

const AVAILABLE_ENDPOINTS = ['/docs/upload-generic', '/docs'];

export default {
  name: 'upload-image',
  model: {
    prop: 'value',
    event: 'change',
  },
  props: {
    autoUpload: {
      type: Boolean,
      default: false,
    },
    fileUploadProps: {
      type: Object,
      default: () => ({}),
    },
    fileUploadEndpoint: {
      type: String,
      default: '/docs/upload-generic',
      validator: value => AVAILABLE_ENDPOINTS.includes(value),
    },
    fileUploadName: {
      type: String,
      default: 'file',
    },
    value: {
      type: [String, Object],
    },
  },
  computed: {
    preview_modifiers() {
      return {
        'upload-image__preview--loading': this.loading,
      };
    },
    is_doc() {
      return this.fileUploadEndpoint === '/docs';
    },
  },
  data: () => ({
    image: null,
    loading: false,
  }),
  mounted() {
    if (this.value) {
      this.image = this.value;
    }
  },
  methods: {
    async $_setImage(file) {
      if (this.autoUpload) {
        this.loading = true;
      }

      try {
        const image = await compressImage(await readFile(file));
        this.image = image;

        if (this.autoUpload) {
          const fileData = await this.$_upload(image, this.fileUploadProps);

          if (fileData.status && fileData.status === 'success') {
            if (this.is_doc) {
              this.$emit('change', fileData.body);
            } else {
              this.$emit('change', fileData.body.absolute_path);
            }
          }

          this.loading = false;
        } else {
          this.image = image;
          this.$emit('change', this.image);
        }
      } catch (e) {
        console.error(e);
        throw new Error(e);
      }
    },
    async $_upload(file, fileProps = {}) {
      NProgress.inc();
      const formData = new FormData();
      formData.append(this.fileUploadName, file);

      Object.keys(fileProps).forEach((item) => {
        formData.append(item, fileProps[item]);
      });

      return fetch(`${process.env.YOUR_APY}${this.fileUploadEndpoint}`, {
        method: 'POST',
        body: formData,
      }).then((result) => {
        NProgress.done();
        return result.json();
      });
    },
    $_onDrop(event) {
      const { dataTransfer } = event;
      const { files } = dataTransfer;

      this.$_setImage(files[0]);
    },
    $_onClick() {
      const elFile = document.createElement('input');
      elFile.type = 'file';
      elFile.accept = 'image/*';
      elFile.click();

      elFile.onchange = () => {
        this.$_setImage(elFile.files[0]);
      };
    },
  },
};
</script>

<style scoped lang="scss">
.upload-image {
  width: 100%;

  &__drag-area {
    // cursor: pointer;
    width: 100%;
    border: 2px gray dashed;
    border-radius: 10px;
    height: 279px;
  }

  &__preview {
    &--loading {
      opacity: 0.5;
      pointer-events: none;
    }
  }
}

.btn-default {
  border-radius: 20px;
  width: 100%;
  max-width: 192px;
  height: 35px;
  background: #278937;
}

.btn-blue {
  background: #FF9B64;
}

.cloud-icon {
  color: #FF9B64;
}

.min-middle-text {
  font-size: 9px;
  letter-spacing: 0.23px;
  color: #7A7A7A;
}

.max-middle-text {
  letter-spacing: 0.35px;
}

</style>
