<template>
	<ToastProvider>
		<ToastRoot v-for="toast in model" :key="toast.id" :duration="toast.duration" class="ToastRoot bg-light-10 dark:bg-dark-10 border border-light-30 dark:border-dark-30 group" :open="toast.state ?? true" @update:open="(state: boolean) => tryClose(toast, state)" :data-type="toast.type ?? 'info'">
			<div class="grid grid-cols-8 px-3 pt-2 pb-2">
				<ToastTitle v-if="toast.title" class="font-semibold text-xl col-span-7 text-light-70 dark:text-dark-70" asChild><h4>{{ toast.title }}</h4></ToastTitle>
				<ToastClose v-if="toast.closeable" aria-label="Close" class="text-xl -translate-y-2 translate-x-4 cursor-pointer"><span aria-hidden>×</span></ToastClose>
				<ToastDescription v-if="toast.content" class="text-sm col-span-8 text-light-70 dark:text-dark-70" asChild><span>{{ toast.content }}</span></ToastDescription>
			</div>
			<TimerProgress v-if="toast.timer" shape="thin" :delay="toast.duration" class="mb-0 mt-0 w-full group-data-[type=error]:bg-light-redBack dark:group-data-[type=error]:bg-dark-redBack group-data-[type=error]:*:bg-light-red dark:group-data-[type=error]:*:bg-dark-red
			group-data-[type=success]:bg-light-greenBack dark:group-data-[type=success]:bg-dark-greenBack group-data-[type=success]:*:bg-light-green dark:group-data-[type=success]:*:bg-dark-green" @finish="() => tryClose(toast, false)" />
		</ToastRoot>
	
		<ToastViewport class="fixed bottom-0 right-0 flex flex-col p-6 gap-2 max-w-[512px] z-50 outline-none min-w-72" />
	</ToastProvider>
</template>

<script setup lang="ts">
const model = defineModel<ExtraToastConfig[]>();

function tryClose(config: ExtraToastConfig, state: boolean)
{
	if(!state)
	{
		const m = model.value;
		if(m)
		{
			const idx = m?.findIndex(e => e.id === config.id);
			m[idx].state = false;
			model.value = m;
		}
		setTimeout(() => model.value?.splice(model.value?.findIndex(e => e.id === config.id), 1), 500);
	}
}
</script>

<style>
.ToastRoot[data-type='error'] {
	@apply border-light-red;
	@apply dark:border-dark-red;
	@apply bg-light-redBack;
	@apply dark:bg-dark-redBack;
}
.ToastRoot[data-type='success'] {
	@apply border-light-green;
	@apply dark:border-dark-green;
	@apply bg-light-greenBack;
	@apply dark:bg-dark-greenBack;
}
.ToastRoot[data-state='open'] {
	animation: slideIn .15s cubic-bezier(0.16, 1, 0.3, 1);
}
.ToastRoot[data-state='closed'] {
	animation: hide .1s ease-in;
}
.ToastRoot[data-swipe='move'] {
	transform: translateX(var(--radix-toast-swipe-move-x));
}
.ToastRoot[data-swipe='cancel'] {
	transform: translateX(0);
	transition: transform .2s ease-out;
}
.ToastRoot[data-swipe='end'] {
	animation: swipeRight .1s ease-out;
}

@keyframes hide {
	from {
		opacity: 1;
	}
	to {
		opacity: 0;
	}
}
@keyframes slideIn {
	from {
		transform: translateX(calc(100% + var(--viewport-padding)));
	}
	to {
		transform: translateX(0);
	}
}
@keyframes swipeRight {
	from {
		transform: translateX(var(--radix-toast-swipe-end-x));
	}
	to {
		transform: translateX(100%);
	}
}
</style>