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

/**
 * Bouton — primitive maison.
 *
 * Personnalité :
 *  - Border-radius 6px (sharper que la default Tailwind, cohérent landing)
 *  - Shadow rubis-teintée sur primary (pas de shadow plate générique)
 *  - Micro-translateY au hover (le bouton "soulève" légèrement)
 *  - Pas de focus ring bleu — anneau rubis-glow discret
 *  - Variants explicites : primary / secondary / ghost / link / danger
 *
 * Composition via Radix Slot : `<Button asChild><Link to=…>` propage les styles
 * sans wrapper supplémentaire.
 */
const buttonVariants = cva(
  cn(
    // Base
    "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-default",
    "font-sans font-semibold transition-[transform,background,box-shadow,color] duration-150",
    // États génériques
    "disabled:pointer-events-none disabled:opacity-50",
    // Focus ring discret rubis-glow — pas de blue ring browser default
    "focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-rubis-glow",
    "focus-visible:ring-offset-0",
  ),
  {
    variants: {
      variant: {
        primary: cn(
          "bg-rubis text-white shadow-rubis",
          "hover:bg-rubis-deep hover:-translate-y-px hover:shadow-rubis-hover",
          "active:translate-y-0 active:shadow-rubis",
        ),
        secondary: cn(
          "bg-transparent text-ink border border-ink",
          "hover:bg-ink hover:text-cream",
        ),
        ghost: cn(
          "bg-transparent text-ink",
          "hover:bg-cream-2",
        ),
        link: cn(
          "bg-transparent text-rubis underline-offset-4 hover:underline px-0 py-0 h-auto",
          "shadow-none",
        ),
        danger: cn(
          "bg-rubis-deep text-white",
          "hover:bg-rubis-deep/90",
        ),
      },
      size: {
        sm: "h-9 px-3 text-[13px]",
        md: "h-11 px-[22px] py-[13px] text-[15px]",
        lg: "h-12 px-7 text-base",
        icon: "size-10 px-0",
      },
    },
    defaultVariants: {
      variant: "primary",
      size: "md",
    },
  },
);

export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
  VariantProps<typeof buttonVariants> & {
    /** Si true, rend l'enfant en propageant les styles (cf. Radix Slot). */
    asChild?: boolean;
    /** État chargement : remplace le contenu par un spinner discret. */
    loading?: boolean;
  };

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, asChild = false, loading = false, children, disabled, ...props }, ref) => {
    const Comp = asChild ? Slot : "button";
    return (
      <Comp
        ref={ref}
        className={cn(buttonVariants({ variant, size }), className)}
        disabled={disabled || loading}
        {...props}
      >
        {loading ? <ButtonSpinner /> : children}
      </Comp>
    );
  },
);
Button.displayName = "Button";

function ButtonSpinner() {
  return (
    <span
      aria-hidden="true"
      className="inline-block size-4 animate-spin rounded-full border-2 border-current border-r-transparent"
    />
  );
}

export { buttonVariants };
