<script lang="ts" setup>
import type { DraggableEvent } from './useDraggable'
import { ref, watch, onMounted, nextTick } from 'vue'
import { useDraggable } from './useDraggable'

const props = withDefaults(defineProps<{
	modelValue?: any[]
	group?: string
	handle?: string
	mode?: 'ghost' | 'line'
	disabled?: boolean
}>(), {
	mode: 'line',
	disabled: false
})

const emit = defineEmits<{
	'update:modelValue': [value: any[]]
	'start': [event: MouseEvent]
	'end': [event: DraggableEvent]
}>()

const dragContainer = ref<HTMLElement>()

const { initDraggableContainer } = useDraggable({
	group: props.group,
	handle: props.handle,
	mode: props.mode,
	disabled: props.disabled,
	items: props.modelValue,
	onStart: (event) => { emit('start', event) },
	onEnd: (event: DraggableEvent) => {
		const newList = [...props.modelValue!]
		const [removed] = newList.splice(event.oldIndex, 1)
		newList.splice(event.newIndex, 0, removed)
		emit('update:modelValue', newList)

		emit('end', event)
		nextTick(() => {
			if (dragContainer.value) {
				initDraggableContainer(dragContainer.value)
			}
		})
	}
})

watch(() => props.modelValue, () => {
	if (dragContainer.value) {
		initDraggableContainer(dragContainer.value)
	}
}, { deep: true })

onMounted(() => {
	if (dragContainer.value) {
		initDraggableContainer(dragContainer.value)
	}
})
</script>

<template>
	<div ref="dragContainer">
		<slot v-for="(item, index) in modelValue" :key="index" :item="item" :index="index" />
	</div>
</template>
