<template>
  <div 
    class="file-input" 
    :class="{ 'drag-over': isDragOver }"
    @click="handleClick()"
    @dragenter.prevent="handleDragEnter"
    @dragover.prevent="handleDragOver"
    @dragleave.prevent="handleDragLeave"
    @drop.prevent="handleDrop"
  >
    <slot></slot>
    <input 
      class="input"
      type="file" 
      name="upload" 
      ref="inputRef" 
      :accept="accept" 
      @change="$event => handleChange($event)"
      @click.stop
    >
  </div>
</template>

<script lang="ts" setup>
import { ref, useTemplateRef } from 'vue'

withDefaults(defineProps<{
  accept?: string
}>(), {
  accept: 'image/*',
})

const emit = defineEmits<{
  (event: 'change', payload: FileList): void
}>()

const inputRef = useTemplateRef<HTMLInputElement>('inputRef')
const isDragOver = ref(false)

const handleClick = () => {
  if (!inputRef.value) return
  inputRef.value.value = ''
  inputRef.value.click()
}
const handleChange = (e: Event) => {
  const files = (e.target as HTMLInputElement).files
  if (files) emit('change', files)
}
const handleDragEnter = () => {
  isDragOver.value = true
}
const handleDragOver = () => {
  isDragOver.value = true
}
const handleDragLeave = () => {
  isDragOver.value = false
}
const handleDrop = (e: DragEvent) => {
  isDragOver.value = false
  const files = e.dataTransfer?.files
  if (files && files.length > 0) {
    emit('change', files)
  }
}
</script>

<style lang="scss" scoped>
.input {
  display: none;
}
</style>