import { forwardRef } from "react";
import type { ElementRef, ComponentProps } from "react";
import type { DataAttributeMap } from "./utils/buildDataAttributes";
import clsx from "clsx";
import buildDataAttributes from "./utils/buildDataAttributes";

type ButtonSizes = "small" | "standard";

type ButtonTones = "neutral" | "critical";

type ButtonVariants = "solid" | "ghost" | "soft" | "transparent";

type ButtonProps = {
  variant?: ButtonVariants;
  href?: string;
  children: React.ReactNode;
  onClick?:
    | ComponentProps<"a">["onClick"]
    | ComponentProps<"button">["onClick"];
  disabled?: boolean;
  size?: ButtonSizes;
  tone?: ButtonTones;
  isLoading?: boolean;
  UNSAFE_className?: string;
  data?: DataAttributeMap;
};

const variants = {
  solid: "",
  soft: "btn-ghost",
  ghost: "btn-outline",
  transparent: "btn-link",
};

const sizes = {
  small: "btn-sm",
  standard: "btn-md",
};

const tones: { [key in ButtonTones]: string } = {
  neutral: "btn-primary",
  critical: "btn-error",
};

// Full button coming: https://github.com/radix-ui/primitives/issues/892
export const Button = forwardRef<ElementRef<"a" | "button">, ButtonProps>(
  (
    {
      tone = "neutral",
      variant = "solid",
      children,
      onClick,
      size = "standard",
      disabled,
      href,
      isLoading,
      UNSAFE_className,
      data,
    },
    forwardedRef
  ) => {
    const isLink = typeof href !== "undefined";
    const Component = isLink ? "a" : "button";
    return (
      <Component
        // @ts-ignore -- TODO fix
        ref={forwardedRef}
        className={clsx(
          "btn",
          variants[variant],
          sizes[size],
          tones[tone],
          { loading: isLoading },
          UNSAFE_className
        )}
        href={href}
        // @ts-ignore -- TODO fix
        onClick={onClick}
        {...(disabled ? { disabled: "disabled", tabIndex: "-1" } : {})}
        {...(data ? buildDataAttributes(data) : undefined)}
      >
        {children}
      </Component>
    );
  }
);

Button.displayName = "Button";

Lookup