<script setup>
const props = defineProps({
	type: {
		type: String,
		default: "single"
	},
	defaultValue: {
		type: String || Array,
	}
})

const emit = defineEmits(['update:modelValue'])

const toggleGroup = ref(null);
const selected = ref((props.type === "single") ? props.defaultValue : [].concat(props.defaultValue));

watch(selected, (newValue) => {
	emit('update:modelValue', newValue);
})
emit('update:modelValue', selected.value);

const items = ref([]);

function registerToggleItem(value) {
	const item = { value, tabIndex: (props.defaultValue.includes(value)) ? ref('0') : ref('-1') }
	const itemIndex = (items.value.push(item)) - 1
	return { item, index: itemIndex };
}

function toggleItem(index) {
	if (props.type === "single") {
		selected.value = items.value[index].value;
		return;
	}
	if (selected.value.indexOf(items.value[index].value) > -1) {
		selected.value = selected.value.filter((e) => e !== items.value[index].value)
		return;
	}
	selected.value.push(items.value[index].value);
}

function keydown(event) {
	const elements = Array.from(toggleGroup.value.children).filter(
		(el) => el.nodeName.toLowerCase() === 'button'
	);

	if (event.key === "Home") {
		event.preventDefault();
		items.value.forEach((el, i) => {
			if (i === 0) return items.value[i].tabIndex = '0';
			return items.value[i].tabIndex = '-1';
		});
		elements[0].focus();
	}

	if (event.key === "End") {
		event.preventDefault();
		items.value.forEach((el, i) => {
			if (i === items.value.length - 1) return items.value[i].tabIndex = '0';
			return items.value[i].tabIndex = '-1';
		});
		elements[items.value.length-1].focus();
	}

	const focusedElement = document.activeElement;
	const currentIndex = elements.indexOf(focusedElement);
	if (event.key === "ArrowRight" || event.key === "ArrowDown") {
		event.preventDefault();
		const nextIndex = currentIndex < elements.length - 1 ? currentIndex + 1 : 0;
		items.value.forEach((el, i) => {
			if (i === nextIndex) return items.value[i].tabIndex = '0';
			return items.value[i].tabIndex = '-1';
		});
		elements[nextIndex].focus();
	}

	if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
		event.preventDefault();
		const nextIndex = currentIndex > 0 ? currentIndex - 1 : elements.length - 1;
		items.value.forEach((el, i) => {
			if (i === nextIndex) return items.value[i].tabIndex = '0';
			return items.value[i].tabIndex = '-1';
		});
		elements[nextIndex].focus();
	}
}

provide('toggleGroup', { registerToggleItem, toggleItem, selected })
</script>

<template>
	<div role="group" ref="toggleGroup" class="vl-toggle-group" @keydown="keydown($event)">
		<slot />
	</div>
</template>