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

	// the numbered rail from Figma node 191:6514 — same shape as the appview's
	// onboarding/fragments/steps, restyled onto the design-system tokens. the three
	// states differ only in the marker fill and the label colour, so they are one
	// variant across two slots rather than three hand-written class strings.
	export const steps = tv({
		slots: {
			root: "flex w-full items-center gap-2",
			item: "flex shrink-0 items-center gap-2",
			marker:
				"flex size-5 shrink-0 items-center justify-center rounded-full typography-paragraph-small",
			// labels are desktop-only, but sr-only rather than hidden so the rail still
			// reads as a named list of steps on a narrow screen
			label: "sr-only typography-paragraph-small whitespace-nowrap sm:not-sr-only",
			connector: "h-px min-w-4 flex-1 bg-border-default"
		},
		variants: {
			state: {
				done: {
					marker: "bg-background-inset text-foreground-default",
					label: "text-foreground-subtle"
				},
				current: {
					marker: "bg-background-muted text-foreground-default",
					label: "text-foreground-default"
				},
				upcoming: {
					marker: "bg-background-inset text-foreground-subtle",
					label: "text-foreground-subtle"
				}
			}
		},
		defaultVariants: {
			state: "upcoming"
		}
	});

	export type StepsVariants = VariantProps<typeof steps>;
	export type StepState = NonNullable<StepsVariants["state"]>;
</script>

<script lang="ts">
	import Check from "$icon/check";

	interface Props {
		items: readonly { key: string; label: string }[];
		current: number;
	}

	let { items, current }: Props = $props();

	// root and connector take no variant, so they resolve once
	const shell = steps();

	const stateOf = (index: number): StepState =>
		index < current ? "done" : index === current ? "current" : "upcoming";
</script>

<ol class={shell.root()}>
	{#each items as item, index (item.key)}
		{#if index > 0}
			<li aria-hidden="true" class={shell.connector()}></li>
		{/if}
		{@const state = stateOf(index)}
		{@const slot = steps({ state })}
		<li class={slot.item()} aria-current={state === "current" ? "step" : undefined}>
			<span class={slot.marker()} aria-label={state === "done" ? "done" : undefined}>
				{#if state === "done"}
					<Check class="size-3.5" aria-hidden="true" />
				{:else}
					{index + 1}
				{/if}
			</span>
			<span class={slot.label()}>{item.label}</span>
		</li>
	{/each}
</ol>
