import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from "react";
import { createAccentVariables, type RgbTuple } from "@nodedc/ui-core";
import { cn } from "./cn.js";

export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "accent";
export type ButtonSize = "default" | "compact";
export type ButtonShape = "default" | "pill" | "rounded";

export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: ButtonVariant;
  size?: ButtonSize;
  width?: "auto" | "full";
  shape?: ButtonShape;
  accent?: RgbTuple;
  icon?: ReactNode;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button({
    variant = "secondary",
    size = "default",
    width = "auto",
    shape = "default",
    accent,
    icon,
    className,
    children,
    style,
    type = "button",
    ...props
  }, ref) {
    const accentStyle = accent ? createAccentVariables(accent) : undefined;
    return (
      <button
        ref={ref}
        type={type}
        className={cn("nodedc-button", className)}
        data-variant={variant}
        data-size={size === "default" ? undefined : size}
        data-width={width === "auto" ? undefined : width}
        data-shape={shape === "default" ? undefined : shape}
        style={accentStyle ? { ...accentStyle, ...style } : style}
        {...props}
      >
        {icon ? <span className="nodedc-button__icon" aria-hidden="true">{icon}</span> : null}
        {children}
      </button>
    );
  });

export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  label: string;
  shape?: "circle" | "rounded";
}

export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton({
  label,
  shape = "circle",
  className,
  children,
  type = "button",
  ...props
}, ref) {
  return (
    <button
      ref={ref}
      type={type}
      className={cn("nodedc-icon-button", className)}
      data-shape={shape === "circle" ? undefined : shape}
      aria-label={label}
      title={label}
      {...props}
    >
      {children}
    </button>
  );
});
