<script setup lang="ts">
import { Icon } from '@bagelink/vue'
import { ref } from 'vue'

const props = defineProps<{
	multiple?: boolean
	accept?: string
	disabled?: boolean
	browse?: boolean
}>()

const emit = defineEmits<{
	(e: 'addFiles', files: FileList): void
}>()

const isDragging = ref(false)
const dragCounter = ref(0)

function handleDragEnter(e: DragEvent) {
	if (props.disabled) { return }
	e.preventDefault()
	e.stopPropagation()
	dragCounter.value++
	isDragging.value = true
}

function handleDragOver(e: DragEvent) {
	if (props.disabled) { return }
	e.preventDefault()
	e.stopPropagation()
}

function handleDragLeave(e: DragEvent) {
	if (props.disabled) { return }
	e.preventDefault()
	e.stopPropagation()
	dragCounter.value--
	if (dragCounter.value === 0) {
		isDragging.value = false
	}
}

function handleClick(e: MouseEvent) {
	if (!props.browse || props.disabled) {
		return
	}
	e.preventDefault()
	e.stopPropagation()
	const input = document.createElement('input')
	input.type = 'file'
	input.multiple = !!props.multiple
	input.accept = props.accept || '*'
	input.onchange = (e: Event) => {
		const { files } = e.target as HTMLInputElement
		if (files) {
			emit('addFiles', files)
		}
	}
	input.click()
}

function handleDrop(e: DragEvent) {
	if (props.disabled) { return }
	e.preventDefault()
	e.stopPropagation()
	dragCounter.value = 0
	isDragging.value = false

	if (!e.dataTransfer) { return }
	emit('addFiles', e.dataTransfer.files)
}
</script>

<template>
	<div
		class="drag-over-container"
		:class="{
			'is-dragging': isDragging,
			'is-disabled': disabled,
		}"
		@dragenter="handleDragEnter"
		@dragover="handleDragOver"
		@dragleave="handleDragLeave"
		@drop="handleDrop"
		@click="handleClick"
	>
		<slot />
		<div v-if="isDragging && !disabled" class="drag-overlay">
			<Icon name="download" color="white" size="2" />
		</div>
	</div>
</template>

<style scoped>
.drag-over-container {
  position: relative;
}

.drag-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 10;
  border: 1px dashed #ccc;
  border-radius: 4px;
}

.drag-message {
  color: white;
  font-size: 1.5rem;
  font-weight: bold;
  text-align: center;
  padding: 1rem;
}

.is-dragging {
  outline: 1px dashed #4CAF50;
}

.is-disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
</style>
