import { forwardRef, type ReactNode } from 'react';
import { Text, View, type ViewProps } from 'react-native';
import { dataAttributes, mergeDataAttributes } from '@cdx-ui/primitives';
import { cn } from '@cdx-ui/utils';
import type { ForgeIcon } from '@cdx-ui/icons';
import { Icon } from '../Icon';
import {
  badgeIconVariants,
  badgeIndicatorVariants,
  badgeLabelVariants,
  badgeRootVariants,
  type BadgeVariantProps,
} from './styles';

const INDICATOR_STYLE = { pointerEvents: 'none' as const };

export interface BadgeProps extends ViewProps, BadgeVariantProps {
  children?: ReactNode;
  label?: ReactNode;
  icon?: ForgeIcon;
  className?: string;
}

const Badge = forwardRef<View, BadgeProps>(
  (
    {
      children,
      variant = 'default',
      color = 'action',
      placement = 'top-end',
      overlap = 'rectangular',
      label,
      icon: IconComponent,
      accessibilityLabel,
      className,
      style,
      ...props
    },
    ref,
  ) => {
    const isDecorative = variant === 'dot' || !accessibilityLabel;

    const renderContent = () => {
      if (variant === 'dot') return null;
      if (IconComponent) {
        return <Icon as={IconComponent} className={badgeIconVariants({ color })} />;
      }
      if (typeof label === 'string' || typeof label === 'number') {
        return (
          <Text
            className={badgeLabelVariants({ color })}
            {...dataAttributes({ slot: 'badge-label' })}
          >
            {label}
          </Text>
        );
      }
      return label ?? null;
    };

    const hasChildren = children != null;

    return (
      <View
        ref={ref}
        className={cn(badgeRootVariants({ standalone: !hasChildren }), className)}
        style={style}
        {...props}
        {...mergeDataAttributes(props, dataAttributes({ slot: 'badge' }))}
      >
        {children}
        <View
          className={cn(badgeIndicatorVariants({ variant, color, placement, overlap }))}
          style={INDICATOR_STYLE}
          accessible={!isDecorative}
          accessibilityLabel={accessibilityLabel}
          aria-hidden={isDecorative}
          accessibilityElementsHidden={isDecorative}
          importantForAccessibility={isDecorative ? 'no-hide-descendants' : 'auto'}
          {...dataAttributes({ slot: 'badge-indicator' })}
        >
          {renderContent()}
        </View>
      </View>
    );
  },
);
Badge.displayName = 'Badge';

export { Badge };
export type { BadgeVariantProps } from './styles';
