<template>
  <div class="file-upload">
    <input type="hidden" :name="name" :value="valueJson"/>
    <div v-if="modelValue" class="preview">
      @todo handle upload here
      <span class="file-upload-preview">
        <img
            class="img rounded-lg h-[200px] object-contain"
            :src="modelValue"
            title="Image"
        />
      </span>
    </div>
    <div v-else-if="file && file.length" class="preview">
      <span class="file-upload-preview">
        <img
            class="img"
            v-if="isImage(file.mime_type)"
            :src="file.url"
            :title="file.file_name"
        />
      </span>
      <a :href="file.url" target="_blank" class="link">
        <div class="file-upload-title">{{ file.file_name }}</div>
      </a>
      <a class="file-upload-file-remove">
        <i class="fal fa-times" @click="deleteFile(file)"></i>
      </a>
    </div>
    <div :class="'relative rounded-lg ' + background" v-show="!modelValue">
      <div class="dropzone border border-dashed rounded-lg z-10 h-[200px] w-full cursor-pointer relative"
           ref="dropzone">
      </div>
      <div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 p-4 rounded-lg flex flex-col justify-center items-center w-full">
        <div>
          <UploadCloud class="w-6 h-6"/>
        </div>
        <div class="text-sm text-center">
          <p>
            <span class="text-brand-900">Click to upload</span><span> or drag and drop</span>
          </p>
          <span>(max. 20MB)</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import {ref, reactive, onMounted, computed} from "vue";
import axios from "axios";
import Dropzone from "dropzone";
import UploadCloud from "@/assets/img/icons/upload-cloud-02.svg";

Dropzone.autoDiscover = false;

const props = defineProps({
  name: {
    type: String,
    required: false,
  },
  modelValue: {
    type: [String, Object],
    default: null,
  },
  submitEndpoint: {
    type: String,
    required: false,
  },
  deleteEndpoint: {
    type: String,
    required: false,
  },
  formData: {
    type: Object,
    default: null,
  },
  csrf: {
    type: String,
    required: false,
  },
  background: {
    type: String,
    default: "",
  }
});
const emit = defineEmits(["update:modelValue"]);

const file = ref([]);
const dropzone = ref(Dropzone);
const formData = ref(null);

const valueJson = computed(() => {
  return JSON.stringify(file);
});

const isImage = (mimeType) => {
  const imageMimes = ["image/gif", "image/jpeg", "image/png", "image/tiff"];
  return imageMimes.includes(mimeType);
};

const deleteFile = (fileToDelete) => {
  axios
      .delete(props.deleteEndpoint + '?' + fileToDelete.id)
      .then(() => {
        file.value = null;
      })
      .catch(console.error);
};

onMounted(() => {
  formData.value = props.formData;
  const csrf = props.csrf;

  dropzone.value = new Dropzone(dropzone.value, {
    url: props?.submitEndpoint + '?' + formData.value?.id,
    addRemoveLinks: true,
    maxFiles: 1,
    sending: (file, xhr, formData) => {
      formData.append("_token", csrf);
      formData.append("field", props.name);
    },
    success: (file, response) => {
      file.value = response;
    },
    complete: (file) => {
      dropzone.value?.removeFile(file);
    },
  });

  file.value = props.modelValue;
});
</script>
<style>
.dropzone {
  .dz-message {
    @apply hidden;
  }

  .dz-preview {
    @apply bg-gray-200 flex gap-1 h-[198px] p-4 items-center rounded-lg;

    .dz-image {
      @apply w-[100px] object-cover;
    }

    .dz-details, .dz-error-message, .dz-remove {
      @apply text-sm;
    }

    .dz-success-mark, .dz-error-mark, .dz-details, .dz-message {
      @apply hidden;
    }
  }
}
</style>