<script lang="ts">
	import { fly } from "svelte/transition";
	import { toaster } from "./toaster.svelte.js";
	import { Progress } from "melt/components";
	import Close from "~icons/carbon/close";
	import { omit } from "$lib/utils/object.js";
	import { session } from "$lib/state/session.svelte.js";
	import { AnimationFrames } from "runed";

	let toastHeights = $state<number[]>([]);
	new AnimationFrames(() => {
		const rootEl = document.getElementById(toaster.root.id);
		if (!rootEl) return;

		const toastEls = Array.from(rootEl.querySelectorAll("[data-melt-toaster-toast-content]"));
		toastHeights = toastEls.map(el => el.clientHeight);
		// console.log(toastHeights);
	});

	const isComparing = $derived(session.project.conversations.length > 1);

	const GAP = 8;

	function getToastStyle(i: number) {
		// Remember, the order is reversed! Meaning i=0 was the first toast, so its the last
		// we want to show.
		const n = toaster.toasts.length - i - 1;
		if (n === 0) return "";
		const reversedHeights = toastHeights.toReversed();
		const yHover = -1 * reversedHeights.slice(0, n).reduce((a, b) => a + b + GAP, 0);

		const y = -n * 10;

		return `
			--y-hover: ${yHover}px;
			--y: ${y}px;
		`;
	}

	function getRootStyle() {
		const heightHover = toastHeights.reduce((a, b) => a + b + GAP, 0);
		return `
			--h-hover: ${heightHover}px;
		`;
	}
</script>

<div
	{...omit(toaster.root, "popover")}
	class={["absolute right-2 bottom-23 flex w-[300px] flex-col ", !isComparing && "md:right-0"]}
	style:--toasts={toaster.toasts.length}
	style={getRootStyle()}
>
	{#each toaster.toasts as toast, i (toast.id)}
		<div
			class="flex w-full flex-col justify-center rounded-xl bg-white px-4 py-4 text-left transition dark:bg-gray-800"
			{...toast.content}
			style:--n={toaster.toasts.length - i}
			in:fly={{ y: 20, opacity: 0 }}
			out:fly={{ y: 20 }}
			style={getToastStyle(i)}
		>
			<h3 {...toast.title} class="text-sm font-semibold whitespace-nowrap text-gray-700 dark:text-gray-300">
				{toast.data.title}
			</h3>

			{#if toast.data.description}
				<p {...toast.description} class="max-w-[200px] text-xs text-gray-700 dark:text-gray-300">
					{toast.data.description}
				</p>
			{/if}

			<button
				{...toast.close}
				aria-label="dismiss toast"
				class="absolute top-2 right-2 bg-transparent text-gray-300 hover:text-gray-400 dark:hover:text-gray-100"
			>
				<Close class="size-4" />
			</button>

			{#if toast.closeDelay !== 0}
				<div class="absolute right-4 bottom-4 h-[4px] w-[30px] overflow-hidden rounded-full">
					<Progress value={toast.percentage}>
						{#snippet children(progress)}
							<div {...progress.root} class="relative h-full w-full overflow-hidden bg-gray-200 dark:bg-gray-950">
								<div
									{...progress.progress}
									class="h-full w-full -translate-x-(--progress)"
									class:bg-green-400={toast.data.variant === "success"}
									class:bg-orange-400={toast.data.variant === "warning"}
									class:bg-red-500={toast.data.variant === "error"}
								></div>
							</div>
						{/snippet}
					</Progress>
				</div>
			{/if}
		</div>
	{/each}
</div>

<style>
	:global([popover]) {
		inset: unset;
	}

	[data-melt-toaster-root] {
		--gap: 0.75rem;
		--hover-offset: 0rem;
		/* --toast-height: 4.5rem; */
		--hidden-offset: 0.75rem;

		--hidden-toasts: calc(var(--toasts) - 1);

		overflow: visible;
		gap: 0;
		background: unset;
		padding: 0;

		border: none;
		height: var(--h);
	}

	[data-melt-toaster-root]:hover {
		height: var(--h-hover);
	}

	[data-melt-toaster-toast-content] {
		position: absolute;
		pointer-events: auto;
		bottom: 0;
		left: 0;
		box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);

		transform-origin: 50% 0%;
		transition: all 350ms ease;

		translate: 0 var(--y);
	}

	:global(.dark [data-melt-toaster-toast-content]) {
		box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.25);
	}

	[data-melt-toaster-toast-content]:nth-last-child(n + 4) {
		z-index: 1;
		scale: 0.925;
		opacity: 0;
	}

	[data-melt-toaster-toast-content]:nth-last-child(-n + 3) {
		z-index: 2;
		scale: 0.95;
	}

	[data-melt-toaster-toast-content]:nth-last-child(-n + 2) {
		z-index: 3;
		scale: 0.975;
	}

	[data-melt-toaster-toast-content]:nth-last-child(-n + 1) {
		z-index: 4;
		scale: 1;
	}

	[data-melt-toaster-root]:hover [data-melt-toaster-toast-content] {
		scale: 1;
		opacity: 1;
		translate: 0 var(--y-hover);
	}
</style>