import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { Loader2 } from "lucide-react";
import { cn } from "@/lib/utils";

/**
 * CTA tiering per Sprint 2 §07 — exactly three visual tiers site-wide.
 * primary = solid blue (one per screen); secondary = blue outline; tertiary = plain link.
 * Gold (secondary token) is reserved as an accent only — never a button fill.
 */
export const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg font-sans font-medium transition-all duration-200 ease-editorial focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:ring-offset-bg disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        primary:
          "bg-primary text-primary-contrast shadow-1 hover:bg-primary-strong hover:shadow-[0_4px_18px_rgb(var(--color-accent)/0.25)] active:bg-primary-strong",
        secondary: "border border-primary bg-paper text-primary hover:bg-primary/5 hover:shadow-1",
        tertiary: "text-ink-soft underline underline-offset-4 decoration-line hover:text-primary hover:decoration-primary",
      },
      size: {
        sm: "h-9 px-4 text-body-sm",
        md: "h-11 px-5 text-body-md",
        lg: "h-13 px-7 text-body-md",
      },
    },
    compoundVariants: [{ variant: "tertiary", size: ["sm", "md", "lg"], class: "h-auto px-0" }],
    defaultVariants: {
      variant: "primary",
      size: "md",
    },
  }
);

export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  isLoading?: boolean;
  asChild?: boolean;
}

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, isLoading, disabled, children, ...props }, ref) => {
    return (
      <button
        ref={ref}
        className={cn(buttonVariants({ variant, size }), className)}
        disabled={disabled || isLoading}
        aria-busy={isLoading || undefined}
        {...props}
      >
        {isLoading && <Loader2 className="size-4 animate-spin" aria-hidden="true" />}
        {children}
      </button>
    );
  }
);
Button.displayName = "Button";
