import { withUniwind } from 'uniwind';
import { cn } from '@cdx-ui/utils';
import type { ForgeIcon, ForgeIconProps } from '@cdx-ui/icons';

export type IconProps = ForgeIconProps & {
  className?: string; // TODO: Why does this need to specified manually?
  as: ForgeIcon;
};

function IconImpl({ as: IconComponent, ...props }: IconProps) {
  return <IconComponent {...props} />;
}

// Double-wrap: the inner `withUniwind` (auto mapping) resolves general
// `className` utilities (margin, padding, positioning, etc.) into the `style`
// prop so they reach the SVG on native. The outer `withUniwind` (custom mapping)
// extracts `size` and `color` from the same `className`. Without the inner
// wrapper, a custom mapping alone skips the `className` → `style` merge, so
// layout classes like `mt-3` are dropped on native (they still apply on web,
// where RNW keeps `className` as a real CSS class).
const StyledIcon = withUniwind(withUniwind(IconImpl), {
  size: {
    fromClassName: 'className',
    styleProperty: 'width',
  },
  color: {
    fromClassName: 'className',
    styleProperty: 'color',
  },
});

/**
 * A wrapper component for CDX icons with Uniwind `className` support via `withUniwind`.
 *
 * This component allows you to render any CDX icon while applying utility classes
 * using `uniwind`. It avoids the need to wrap or configure each icon individually.
 *
 * @component
 * @example
 * ```tsx
 * import { Icon } from '@cdx-ui/components';
 * import { ArrowRight } from '@cdx-ui/icons';
 *
 * <Icon as={ArrowRight} className="text-red-500 size-4" />
 * ```
 *
 * @param {ForgeIcon} as - The Forge icon component to render.
 * @param {string} className - Utility classes to style the icon using Uniwind.
 * @param {number} size - Icon size (overrides the size class).
 * @param {...ForgeIconProps} ...props - Additional icon props passed to the "as" icon.
 */
export function Icon({ as: IconComponent, className, ...props }: IconProps) {
  return (
    <StyledIcon
      as={IconComponent}
      className={cn('text-content-primary size-5', className)}
      {...props}
    />
  );
}
