import type { ComponentProps } from 'react';
import React from 'react';
import Badge from '../Badge';
import Icon from '../Icon';
import type Typography from '../Typography';
import {
  StyledSegmentedItem,
  StyledSegmentedItemLabelWrapper,
  StyledSegmentedItemText,
  StyledSegmentedItemWrapper,
} from './StyledSegmentedControl';
import type {
  CounterBadgeType,
  SegmentedControlItemConfig,
  StatusBadgeType,
} from './types';
import Box from '../Box';

const DOT_CHAR = '\u00B7';
type TypographyIntent = ComponentProps<typeof Typography.Body>['intent'];
type IconIntent = ComponentProps<typeof Icon>['intent'];

export interface SegmentedItemProps extends SegmentedControlItemConfig {
  /**
   * Whether the segment option is selected.
   */
  selected?: boolean;
  /**
   * The size of the segment option.
   */
  size?: 'medium' | 'large';
  /**
   * The callback function to be called when the segment option is pressed.
   */
  onPress: () => void;
}

const SegmentedItemBadge = ({
  children,
  badge,
  testID,
}: {
  children?: React.ReactNode;
  badge?: StatusBadgeType | CounterBadgeType;
  testID?: string;
}) => {
  if (!badge) return children;

  if (badge.type === 'status') {
    return (
      <Badge.Status visible testID={testID}>
        <Box marginEnd="smallMedium">{children}</Box>
      </Badge.Status>
    );
  }

  if (badge.type === 'counter') {
    return (
      <>
        <Box marginEnd="xsmall">{children}</Box>
        <Badge
          visible
          content={badge.value}
          max={badge.max}
          testID={testID}
          size="small"
        />
      </>
    );
  }
};

const getTextAndIconIntent = ({
  selected,
  disabled,
}: {
  selected?: boolean;
  disabled?: boolean;
}): {
  iconIntent: IconIntent;
  textIntent: TypographyIntent;
  subTextIntent: TypographyIntent;
} => {
  if (disabled) {
    return {
      iconIntent: 'disabled-text',
      textIntent: 'disabled',
      subTextIntent: 'disabled',
    };
  }

  if (selected) {
    return {
      iconIntent: 'text',
      textIntent: 'body',
      subTextIntent: 'muted',
    };
  }

  return {
    iconIntent: 'inactive',
    textIntent: 'inactive',
    subTextIntent: 'inactive',
  };
};

const SegmentedItem = ({
  label,
  prefix,
  suffix,
  selected = false,
  size = 'medium',
  testID,
  onPress,
  disabled,
  badge,
  subText,
}: SegmentedItemProps) => {
  const { iconIntent, textIntent, subTextIntent } = getTextAndIconIntent({
    selected,
    disabled,
  });

  const shouldShowSuffix = !!label && !!suffix;

  return (
    <StyledSegmentedItem
      themeSize={size}
      themeSelected={selected}
      testID={testID}
      onPress={onPress}
      disabled={disabled}
    >
      <SegmentedItemBadge badge={badge} testID={`${testID}-badge`}>
        <StyledSegmentedItemWrapper>
          {/* Prefix */}
          {prefix && (
            <Icon
              icon={prefix}
              intent={iconIntent}
              size="xxxsmall"
              testID={`${testID}-prefix`}
            />
          )}

          {/* Label and subtext */}

          {!!label && (
            <StyledSegmentedItemLabelWrapper>
              {label && (
                <StyledSegmentedItemText
                  variant="small-bold"
                  intent={textIntent}
                >
                  {label}
                </StyledSegmentedItemText>
              )}

              {subText && (
                <>
                  <StyledSegmentedItemText
                    variant="small"
                    intent={subTextIntent}
                  >
                    {DOT_CHAR}
                  </StyledSegmentedItemText>
                  <StyledSegmentedItemText
                    variant="small"
                    intent={subTextIntent}
                  >
                    {subText}
                  </StyledSegmentedItemText>
                </>
              )}
            </StyledSegmentedItemLabelWrapper>
          )}

          {/* Suffix, only shown if there is a label and suffix */}
          {shouldShowSuffix && (
            <Icon
              icon={suffix}
              intent={iconIntent}
              size="xxxsmall"
              testID={`${testID}-suffix`}
            />
          )}
        </StyledSegmentedItemWrapper>
      </SegmentedItemBadge>
    </StyledSegmentedItem>
  );
};

export default SegmentedItem;
