import { Slot, Slottable } from "@radix-ui/react-slot"
import { type ButtonHTMLAttributes, forwardRef } from "react"
import { Loader2 } from "lucide-react"

type ButtonVariant = "primary" | "ghost" | "outline"
type ButtonSize = "sm" | "md" | "lg"

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  asChild?: boolean
  variant?: ButtonVariant
  size?: ButtonSize
  loading?: boolean
}

const variantClasses: Record<ButtonVariant, string> = {
  primary:
    "bg-sky-500 hover:bg-sky-600 active:bg-sky-700 text-white shadow-sm hover:-translate-y-0.5 active:translate-y-0 active:scale-[0.985]",
  ghost:
    "bg-sky-50 hover:bg-sky-100 active:bg-sky-200 text-sky-600",
  outline:
    "border border-sky-200 hover:border-sky-400 active:border-sky-500 text-sky-600 bg-white",
}

const sizeClasses: Record<ButtonSize, string> = {
  sm: "px-3 py-1.5 text-xs rounded-lg gap-1.5",
  md: "px-5 py-2 text-sm rounded-xl gap-2",
  lg: "px-6 py-2.5 text-sm rounded-xl gap-2",
}

const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ asChild, variant = "primary", size = "md", loading, disabled, className = "", children, ...rest }, ref) => {
    const Comp = asChild ? Slot : "button"
    return (
      <Comp
        ref={ref}
        disabled={disabled || loading}
        className={`inline-flex items-center justify-center font-medium transition-all duration-200 ease-out disabled:opacity-60 disabled:cursor-not-allowed disabled:hover:translate-y-0 ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}
        {...rest}
      >
        {loading && <Loader2 className="h-4 w-4 animate-spin" />}
        <Slottable>{children}</Slottable>
      </Comp>
    )
  },
)
Button.displayName = "Button"

export { Button, type ButtonProps, type ButtonVariant, type ButtonSize }
