"use client";
import type { VariantProps } from "@karma/cva";
import { cva, cx } from "@karma/cva";
import { LoadingIcon } from "@karma/icon";
import { Slot, Slottable } from "@radix-ui/react-slot";
import React, { forwardRef } from "react";

const buttonVariants = cva({
  base: "inline-flex items-center justify-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground focus-visible:ring-offset-2 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",

  variants: {
    variant: {
      accent: "hover:bg-accent/90 bg-accent text-secondary",
      primary: "hover:bg-background/90 bg-background text-primary",
      none: "bg-transparent text-secondary",
      outline: "border border-primary bg-transparent text-primary",
      muted: "hover:bg-muted/80 bg-muted text-secondary",
      secondary: "hover:bg-accent/90 bg-accent-secondary text-secondary",
      info: "hover:bg-primary-pink/90 bg-primary-pink text-secondary",
      danger: "bg-danger text-secondary hover:bg-danger",
      consolePrimary: "hover:bg-accent/90 bg-accent text-secondary",
    },
    size: {
      small: "px-3 py-1 text-sm",
      medium: "px-4 py-2 text-base",
      large: "px-6 py-3 text-lg",
      icon: "p-2",
      dot: "p-0",
    },
    shape: {
      pill: "rounded-full",
      rounded: "rounded-md",
      circle: "rounded-full",
      square: "rounded-none",
    },
  },
  defaultVariants: {
    variant: "primary",
    size: "medium",
    shape: "circle",
  },
});

export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
  VariantProps<typeof buttonVariants> & {
    icon?: React.ReactNode;
    iconPlacement?: "left" | "right";
    loading?: boolean;
    children?: React.ReactNode;
    asChild?: boolean;
    href?: string;
  };

export const Button = forwardRef<
  HTMLButtonElement | HTMLAnchorElement,
  ButtonProps
>(
  (
    {
      className,
      variant,
      size,
      shape,
      icon,
      iconPlacement = "left",
      loading = false,
      asChild = false,
      children,
      ...props
    },
    ref,
  ) => {
    const combinedProps = {
      className: cx(buttonVariants({ variant, size, shape, className })),
      ref,
      ...props,
    };

    const Comp = asChild ? Slot : "button";

    return (
      <Comp
        {...(combinedProps as React.ButtonHTMLAttributes<HTMLButtonElement>)}
      >
        {loading && (
          <LoadingIcon className="-ml-1 mr-3 h-5 w-5 animate-spin text-current" />
        )}
        {icon && iconPlacement === "left" && (
          <span className="mr-2">{icon}</span>
        )}
        <Slottable>{children}</Slottable>
        {icon && iconPlacement === "right" && (
          <span className="ml-2">{icon}</span>
        )}
      </Comp>
    );
  },
);

Button.displayName = "Button";
