// @design-system: primitives/IconButton
// Registered at /design-system#iconbutton-primitive

import { Slot } from '@radix-ui/react-slot';
import type { VariantProps } from 'class-variance-authority';
import { forwardRef, type ReactNode } from 'react';
import { cn } from '@/lib/cn';
import { iconButtonVariants } from './variants';

/** Props for the IconButton component */
export interface IconButtonProps
  extends
    Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'aria-label'>,
    VariantProps<typeof iconButtonVariants> {
  /**
   * Accessible label for the button — REQUIRED.
   * This is an icon-only control so a visible label is absent; `aria-label` is mandatory for screen readers.
   */
  'aria-label': string;
  /**
   * The icon to render inside the button. Typically an `<Icon>` component.
   * If omitted, children are used as the icon content.
   */
  icon?: ReactNode;
  /**
   * When true, renders the Radix Slot (merges props onto child element).
   * Useful for dnd-kit drag handles or Radix `asChild` composition.
   */
  asChild?: boolean;
}

/**
 * Multideal IconButton primitive.
 *
 * A square/circle button that wraps a single icon. Enforces `aria-label` at the TypeScript level.
 *
 * Variants: `default` | `ghost` | `on-brand` | `overlay`
 * Sizes: `sm` (h-8 w-8) | `md` (h-9 w-9) | `lg` (h-10 w-10) | `xl` (h-11 w-11, WCAG touch target)
 * Shape: `circle` (rounded-full, default) | `square` (rounded-md)
 *
 * @example
 * ```tsx
 * // Back button on a blue TopBar
 * <IconButton
 *   variant="on-brand"
 *   size="md"
 *   aria-label={t('back')}
 *   onClick={() => window.history.back()}
 * >
 *   <Icon name="ChevronRight" size="md" mirror />
 * </IconButton>
 *
 * // Carousel prev button
 * <IconButton
 *   variant="overlay"
 *   size="lg"
 *   shape="circle"
 *   aria-label={t('image_prev')}
 *   onClick={handlePrev}
 * >
 *   <Icon name="ChevronLeft" size="md" mirror />
 * </IconButton>
 * ```
 */
export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(
  { className, variant, size, shape, asChild = false, icon, children, ...props },
  ref,
) {
  const Comp = asChild ? Slot : 'button';

  return (
    <Comp
      ref={ref}
      type={asChild ? undefined : 'button'}
      className={cn(iconButtonVariants({ variant, size, shape }), className)}
      {...props}
    >
      {icon ?? children}
    </Comp>
  );
});
