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

	export const buttonCard = tv({
		base: "flex cursor-pointer select-none items-start gap-3 rounded p-3 text-left no-underline transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:no-underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50",
		variants: {
			variant: {
				default: "border border-border-default bg-background-default hover:bg-background-subtle",
				ghost: "bg-transparent hover:bg-background-inset"
			}
		},
		defaultVariants: {
			variant: "default"
		}
	});

	export type ButtonCardVariants = VariantProps<typeof buttonCard>;
</script>

<script lang="ts">
	import { resolve } from "$app/paths";
	import type { Component, Snippet } from "svelte";
	import type {
		HTMLAnchorAttributes,
		HTMLButtonAttributes,
		SvelteHTMLElements
	} from "svelte/elements";

	interface Props extends Omit<HTMLAnchorAttributes & HTMLButtonAttributes, "class" | "children"> {
		variant?: ButtonCardVariants["variant"];
		href?: string;
		type?: "button" | "submit" | "reset";
		disabled?: boolean;
		title?: string;
		description?: string;
		icon?: Component<SvelteHTMLElements["svg"]>;
		class?: string;
		children?: Snippet;
	}

	let {
		variant = "default",
		href,
		type = "button",
		disabled = false,
		title,
		description,
		icon,
		class: className,
		children,
		...rest
	}: Props = $props();

	const classes = $derived(buttonCard({ variant, class: className }));
	const Icon = $derived(icon);
</script>

{#if href}
	<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -- internal hrefs go through resolve(), external ones must pass through untouched -->
	<a
		href={href?.startsWith("/") ? resolve(href as "/") : href}
		class={classes}
		aria-disabled={disabled ? "true" : undefined}
		tabindex={disabled ? -1 : undefined}
		{...rest}
	>
		{#if Icon}
			<Icon class="size-5 shrink-0" aria-hidden="true" />
		{/if}
		{#if children}
			{@render children()}
		{:else}
			<div class="flex flex-col gap-0.5">
				{#if title}
					<span class="text-sm font-medium text-foreground-default">{title}</span>
				{/if}
				{#if description}
					<span class="text-xs text-foreground-muted">{description}</span>
				{/if}
			</div>
		{/if}
	</a>
{:else}
	<button {type} {disabled} class={classes} {...rest}>
		{#if Icon}
			<Icon class="size-5 shrink-0" aria-hidden="true" />
		{/if}
		{#if children}
			{@render children()}
		{:else}
			<div class="flex flex-col gap-0.5">
				{#if title}
					<span class="text-sm font-medium text-foreground-default">{title}</span>
				{/if}
				{#if description}
					<span class="text-xs text-foreground-muted">{description}</span>
				{/if}
			</div>
		{/if}
	</button>
{/if}
