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

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium transition-all duration-200 [transition-timing-function:var(--ease-out-expo)] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-4 select-none active:scale-[0.96] active:duration-75",
  {
    variants: {
      variant: {
        primary: "shine bg-primary text-primary-fg shadow-sm shadow-primary/25 hover:bg-primary-hover hover:shadow-md hover:shadow-primary/30 hover:-translate-y-px active:translate-y-0 [box-shadow:inset_0_1px_0_rgb(255_255_255/0.18),var(--tw-shadow)]",
        secondary: "bg-surface text-fg border border-border shadow-xs hover:bg-surface-2 hover:border-border-strong hover:-translate-y-px active:translate-y-0",
        ghost: "text-fg-muted hover:bg-surface-2 hover:text-fg",
        subtle: "bg-surface-2 text-fg hover:bg-surface-3",
        destructive: "bg-negative-600 text-white shadow-sm hover:bg-negative-700 hover:-translate-y-px active:translate-y-0",
        outlineDestructive: "border border-negative-500/40 text-negative-600 hover:bg-negative-50 dark:hover:bg-negative-500/10",
        link: "text-primary underline-offset-4 hover:underline h-auto p-0",
        gold: "shine bg-gold-500 text-stone-900 shadow-sm hover:bg-gold-300 hover:-translate-y-px active:translate-y-0",
      },
      size: {
        xs: "h-7 px-2.5 text-xs rounded-sm [&_svg]:size-3.5",
        sm: "h-8 px-3 text-xs",
        md: "h-9 px-4",
        lg: "h-10 px-5 text-sm",
        xl: "h-12 px-6 text-base rounded-xl",
        icon: "size-9",
        iconSm: "size-8 [&_svg]:size-4",
        iconXs: "size-7 rounded-sm [&_svg]:size-3.5",
      },
    },
    defaultVariants: { variant: "primary", size: "md" },
  }
);

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

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(({ className, variant, size, asChild = false, loading, children, disabled, ...props }, ref) => {
  if (asChild) {
    return (
      <Slot className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props}>
        {children}
      </Slot>
    );
  }
  return (
    <button className={cn(buttonVariants({ variant, size, className }))} ref={ref} disabled={disabled || loading} data-loading={loading ? "" : undefined} {...props}>
      {loading ? <Loader2 className="animate-spin animate-scale-in" /> : null}
      {children}
    </button>
  );
});
Button.displayName = "Button";

export { Button, buttonVariants };
