import clsx from "clsx";
import Link from "next/link";

type Variant = "solid" | "line";

/*
 * Matches site/'s .btn--solid and .btn--line exactly, including the neutral
 * border on the secondary variant. site/ does not have an accent-outlined
 * button and this app should not invent one.
 */
export function buttonClass(variant: Variant = "solid", disabled = false, className?: string) {
    return clsx(
        "inline-flex items-center gap-2 rounded border px-4 py-2.5 text-[0.94rem] font-semibold",
        "transition-[filter,border-color] duration-150 hover:brightness-110",
        variant === "solid" ? "border-accent bg-accent text-accent-ink" : "border-rule bg-panel text-ink hover:border-ink-3",
        disabled && "cursor-not-allowed border-rule bg-panel text-ink-3 hover:brightness-100",
        className,
    );
}

type Props = React.ButtonHTMLAttributes<HTMLButtonElement> & { variant?: Variant };

export function Button({ variant = "solid", className, ...rest }: Props) {
    return <button {...rest} className={buttonClass(variant, rest.disabled, className)} />;
}

/*
 * A link that looks like a button. It exists so a navigation action never has to
 * be an <a> wrapped around a <button> invalid markup, and it gives screen
 * readers two nested controls where the page means one.
 */
export function LinkButton({ href, variant = "solid", external, className, children }: { href: string; variant?: Variant; external?: boolean; className?: string; children: React.ReactNode }) {
    const cls = buttonClass(variant, false, className);
    return external ? (
        <a href={href} className={cls}>
            {children}
        </a>
    ) : (
        <Link href={href} className={cls}>
            {children}
        </Link>
    );
}
