<template>
  <Teleport to="body">
    <Transition name="fade">
      <div
        v-if="showOverlay"
        class="fixed inset-0 z-[9998] bg-indigo-900/40 flex items-center justify-center pointer-events-none"
        data-test="os-drag-overlay"
      >
        <div class="bg-white rounded-2xl px-10 py-8 text-center shadow-xl pointer-events-none">
          <AppIcon name="upload" class="w-10 h-10 text-indigo-400 mx-auto mb-3" />
          <p class="text-base font-semibold text-gray-800">Drop files to upload</p>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script>
import AppIcon from '../ui/AppIcon.vue'

export default {
  name: 'OsDragOverlay',
  components: { AppIcon },
  emits: ['files-dropped'],
  data() {
    return {
      dragDepth: 0,
      showOverlay: false,
    }
  },
  methods: {
    onDragEnter(e) {
      if (!e.dataTransfer?.types.includes('Files')) return
      this.dragDepth++
      this.showOverlay = true
    },
    onDragLeave() {
      this.dragDepth = Math.max(0, this.dragDepth - 1)
      if (this.dragDepth === 0) this.showOverlay = false
    },
    onDragOver(e) {
      e.preventDefault()
    },
    onDrop(e) {
      e.preventDefault()
      this.dragDepth = 0
      this.showOverlay = false
      const files = Array.from(e.dataTransfer.files)
      if (files.length) this.$emit('files-dropped', files)
    },
  },
  mounted() {
    window.addEventListener('dragenter', this.onDragEnter)
    window.addEventListener('dragleave', this.onDragLeave)
    window.addEventListener('dragover', this.onDragOver)
    window.addEventListener('drop', this.onDrop, true)
  },
  beforeUnmount() {
    window.removeEventListener('dragenter', this.onDragEnter)
    window.removeEventListener('dragleave', this.onDragLeave)
    window.removeEventListener('dragover', this.onDragOver)
    window.removeEventListener('drop', this.onDrop, true)
  },
}
</script>

<style scoped>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.15s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
