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

const baseButtonClasses = cn(
  "inline-flex items-center justify-center gap-2",
  "whitespace-nowrap",
  "transition-all duration-300 ease-in-out",
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-main focus-visible:ring-offset-2",
  "disabled:pointer-events-none disabled:opacity-50",
  "cursor-pointer"
);

const buttonVariants = cva(baseButtonClasses, {
  variants: {
    variant: {
      default: "bg-primary-main text-white hover:bg-primary-dark",
      ghost: "bg-transparent text-text hover:bg-primary-dark hover:text-white",
      outline:
        "border border-primary-main bg-transparent text-primary-main hover:bg-primary-main hover:text-white",
    },
    size: {
      default: "px-3 h-[37px] text-[14px] md:px-[22px] md:h-[50px] md:text-[18px] font-bold rounded-full",
      icon: "h-[40px] aspect-square p-0 rounded-[8px]",
      link: "p-0 h-auto text-base font-medium hover:text-primary-main hover:bg-transparent w-[fit-content]",
    },
  },
  defaultVariants: {
    variant: "default",
    size: "default",
  },
  compoundVariants: [
    {
      variant: ["default", "ghost", "outline"],
      size: "link",
      class: "h-auto px-0",
    },
  ],
});

type RenderAs = "button" | "link";

interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  asChild?: boolean;
  as?: RenderAs;
  href?: string;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (
    {
      className,
      variant,
      size,
      asChild = false,
      as = "button",
      href,
      type = "button",
      ...props
    },
    ref
  ) => {
    if (as === "link") {
      if (!href) {
        console.warn("Button with as='link' requires an 'href' prop.");
        return null;
      }

      return (
        <Link
          href={href}
          className={cn(buttonVariants({ variant, size, className }))}
          {...(props as React.AnchorHTMLAttributes<HTMLAnchorElement>)}
        >
          {props.children}
        </Link>
      );
    }

    const Comp = asChild ? Slot : "button";

    return (
      <Comp
        type={type}
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    );
  }
);

Button.displayName = "Button";

export { Button, buttonVariants };
