import React from 'react';
import type { ReactElement } from 'react';
import type { StyleProp, ViewStyle } from 'react-native';
import {
  Container,
  ContentContainer,
  CTAWrapper,
  IconContainer,
  StyledBody,
  StyledIcon,
  TextContainer,
} from './StyledAlert';
import type { IconName } from '../Icon';
import { useDeprecation } from '../../utils/hooks';

type Intent = 'success' | 'info' | 'warning' | 'error' | 'notification';
const getIntentIcon = (
  intent: 'success' | 'info' | 'warning' | 'error' | 'notification'
) => {
  switch (intent) {
    case 'success':
      return 'circle-ok';
    case 'warning':
      return 'warning';
    case 'info':
      return 'circle-info';
    case 'error':
      return 'circle-warning';
    default:
      return undefined;
  }
};

const AlertIcon = ({ icon, intent }: { icon?: IconName; intent: Intent }) =>
  icon ? (
    <IconContainer testID="alert-left-icon">
      <StyledIcon icon={icon} size="small" themeIntent={intent} />
    </IconContainer>
  ) : null;

/**
 * @deprecated Use 'success' | 'info' | 'warning' | 'error' instead.
 */
type DeprecatedIntent = 'notification';

type ValidIntent = 'success' | 'info' | 'warning' | 'error';

interface BasicAlertProps {
  /**
   * Alert title.
   */
  title?: string | ReactElement;
  /**
   * Alert content.
   */
  content: string | ReactElement;
  /**
   * Icon name of the alert.
   * - undefined: use default icon according to Alert intent.
   * - null: no icon at all.
   * - IconName: an icon identifier from hero-design icon list.
   */
  icon?: null | IconName;
  /**
   * Visual intent color to apply to alert.
   *
   *
   * ⚠️ 'notification' intent is deprecated and will be removed in the next major release. Please use other intents instead.
   */
  intent?: ValidIntent | DeprecatedIntent;
  /**
   * Closing callback. When onClose is available, an X button will be rendered on the right side of alert. The callback will be called when user clicks on X button.
   * - undefined: no action button.
   */
  onClose?: () => void;
  /**
   * Alert variant.
   */
  variant?: 'unrounded' | 'rounded';
  /**
   * Addtional style.
   */
  style?: StyleProp<ViewStyle>;
  /**
   * Testing id of the component.
   */
  testID?: string;
  /**
   * Action label at the right side of the alert.
   * - undefined: a close icon.
   */
  actionLabel?: string;
}

type AlertProps =
  | (BasicAlertProps & {
      actionLabel?: undefined;
    })
  | (BasicAlertProps & {
      onClose: () => void;
      /**
       * Action label at the right side of the alert.
       * - undefined: a close icon.
       */
      actionLabel: string;
    });

const Alert = ({
  content,
  icon,
  title,
  intent = 'info',
  onClose,
  variant = 'rounded',
  style,
  testID,
  actionLabel,
}: AlertProps): ReactElement => {
  useDeprecation(
    `Alert's notification intent is deprecated and will be removed in the next major release. Please use other intents instead.`,
    intent === 'notification'
  );

  return (
    <Container
      themeVariant={variant}
      themeIntent={intent}
      style={style}
      testID={testID}
    >
      <ContentContainer showDivider={!!onClose}>
        {icon !== null ? (
          <AlertIcon icon={icon || getIntentIcon(intent)} intent={intent} />
        ) : null}
        <TextContainer>
          {typeof title === 'string' ? (
            <StyledBody variant="small-bold" themeIntent={intent}>
              {title}
            </StyledBody>
          ) : (
            title
          )}
          {typeof content === 'string' ? (
            <StyledBody variant="small" themeIntent={intent}>
              {content}
            </StyledBody>
          ) : (
            content
          )}
        </TextContainer>
      </ContentContainer>
      {onClose ? (
        <CTAWrapper onPress={onClose} testID="alert-close-icon">
          {typeof actionLabel === 'string' ? (
            <StyledBody variant="small-bold" themeIntent={intent}>
              {actionLabel}
            </StyledBody>
          ) : (
            <StyledIcon icon="cancel" size="small" themeIntent={intent} />
          )}
        </CTAWrapper>
      ) : null}
    </Container>
  );
};

export default Alert;
