<script module lang="ts">
	import { tv, type VariantProps } from "tailwind-variants";

	export const error = tv({
		slots: {
			root: "overflow-hidden rounded border border-border-danger bg-background-danger-subtle text-foreground-danger dark:border-border-danger/60 dark:bg-background-danger-subtle/20",
			header: "flex items-center gap-2",
			icon: "shrink-0",
			label: "min-w-0",
			toggle:
				"flex w-full items-center gap-2 border-t border-border-danger text-foreground-danger transition-colors hover:text-foreground-danger-strong dark:border-border-danger/60",
			chevron: "shrink-0 transition-transform",
			body: "border-t border-border-danger font-mono text-foreground-danger-strong dark:border-border-danger/60"
		},
		variants: {
			size: {
				small: {
					header: "px-3 py-2 text-sm",
					icon: "size-4",
					toggle: "px-3 py-2 text-sm",
					chevron: "size-4",
					body: "px-3 py-2 text-xs"
				},
				large: {
					header: "px-4 py-3 text-base",
					icon: "size-5",
					toggle: "px-4 py-3 text-sm",
					chevron: "size-4",
					body: "px-4 py-3 text-sm"
				}
			}
		},
		defaultVariants: {
			size: "small"
		}
	});

	export type ErrorVariants = VariantProps<typeof error>;
</script>

<script lang="ts">
	import type { Snippet } from "svelte";
	import type { HTMLAttributes } from "svelte/elements";
	import OctagonAlert from "$icon/octagon-alert";
	import ChevronRight from "$icon/chevron-right";

	interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "class" | "children"> {
		/** The error message shown next to the icon. */
		label: string;
		size?: ErrorVariants["size"];
		class?: string;
		/** Optional collapsible content revealed by a "Show code" toggle. */
		children?: Snippet;
	}

	let { label, size = "small", class: className, children, ...rest }: Props = $props();

	let open = $state(false);

	const classes = $derived(error({ size }));
</script>

<div class={classes.root({ class: className })} role="alert" {...rest}>
	<div class={classes.header()}>
		<OctagonAlert class={classes.icon()} aria-hidden="true" />
		<span class={classes.label()}>{label}</span>
	</div>

	{#if children}
		<button type="button" class={classes.toggle()} onclick={() => (open = !open)}>
			<ChevronRight class="{classes.chevron()} {open ? 'rotate-90' : ''}" aria-hidden="true" />
			<span>Show code</span>
		</button>
		{#if open}
			<div class={classes.body()}>
				{@render children()}
			</div>
		{/if}
	{/if}
</div>
