import type { ReactNode } from 'react';
import React, { useMemo } from 'react';
import type { ViewProps } from 'react-native';
import Box from '../Box';
import type { IconName } from '../Icon';
import Typography from '../Typography';
import { StyledChipIcon, StyledChipWrapper } from './StyledChip';
import { useDeprecation } from '../../utils/hooks';

/**
 * @deprecated Use 'selection' | 'filter' | 'compact' | 'compact-outlined' instead.
 */
type DeprecatedVariant = 'outlined' | 'filled';

type ValidVariant = 'selection' | 'filter' | 'compact' | 'compact-outlined';

interface ChipProps extends ViewProps {
  /**
   * The label of the chip.
   */
  label: string | ReactNode;
  /**
   * Variant of the chip.
   *
   * ⚠️ 'outlined' | 'filled' variants are deprecated and will be removed in the next major release. Please use 'selection' | 'filter' | 'compact' | 'compact-outlined' instead.
   */
  variant?: ValidVariant | DeprecatedVariant;
  /**
   * Whether the chip is selected.
   */
  selected?: boolean;
  /**
   * Icon of the chip.
   */
  icon?: IconName;
  /**
   * Callback when the chip is pressed.
   */
  onPress?: () => void;
  /**
   * Whether to show the selected icon when using outlined variant.
   */
  showSelectedIcon?: boolean;
  /**
   * If true, indicates that the Chip is accessible to screen readers.
   */
  accessible?: boolean;
}

const getChipLabel = (label: string | ReactNode) => {
  if (typeof label === 'string') {
    return <Typography.Body variant="small">{label}</Typography.Body>;
  }

  return label;
};

const getChipVariant = (variant: ChipProps['variant'] = 'selection') => {
  switch (variant) {
    case 'selection':
    case 'filter':
    case 'compact':
    case 'compact-outlined':
      return variant;
    case 'outlined':
      return 'selection';
    case 'filled':
      return 'filter';
  }
};

const Chip = ({
  label,
  variant = 'selection',
  selected = false,
  icon,
  onPress,
  showSelectedIcon = true,
  accessible,
  onBlur,
  onFocus,
  ...otherProps
}: ChipProps) => {
  useDeprecation(
    'Chip variant `outlined` and `filled` are deprecated.',
    variant === 'outlined' || variant === 'filled'
  );
  const renamedVariant = getChipVariant(variant);

  const shouldShowSelectedIcon =
    (renamedVariant === 'selection' || renamedVariant === 'compact-outlined') &&
    selected &&
    showSelectedIcon;

  const chipLabel = useMemo(() => getChipLabel(label), [label]);

  return (
    <StyledChipWrapper
      onPress={onPress}
      themeVariant={renamedVariant}
      themeSelected={selected}
      accessible={accessible}
      onBlur={onBlur || undefined}
      onFocus={onFocus || undefined}
      {...otherProps}
    >
      {icon && (
        <Box marginRight="small">
          <StyledChipIcon icon={icon} testID={`chip-icon-${icon}`} />
        </Box>
      )}

      {chipLabel}

      {shouldShowSelectedIcon && (
        <Box marginLeft="small">
          <StyledChipIcon icon="cancel" testID="selected-chip-icon-cancel" />
        </Box>
      )}
    </StyledChipWrapper>
  );
};

export default Chip;
