import type { ReactElement } from 'react';
import React, { useEffect, useLayoutEffect, useRef } from 'react';
import { Animated, LayoutAnimation } from 'react-native';
import {
  Container,
  ContentContainer,
  IconContainer,
  CTAWrapper,
  TextContainer,
  StyledBody,
  StyledIcon,
} from './StyledToast';
import { useToastConfig } from './ToastContext';
import type { IconName } from '../Icon';
import type { IntentType, ToastProps } from './types';

const getIntentIcon = (intent: IntentType): IconName | undefined => {
  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 ToastIcon = ({
  themeIntent,
  icon,
}: {
  icon?: IconName;
  themeIntent: IntentType;
}) =>
  icon ? (
    <IconContainer testID="toast-left-icon">
      <StyledIcon icon={icon} size="small" themeIntent={themeIntent} />
    </IconContainer>
  ) : null;

const Toast = ({
  content,
  icon,
  variant = 'default',
  intent = 'info',
  style,
  duration = 2000,
  autoDismiss = true,
  onAction,
  actionLabel,
  onDismiss,
  distance = 0,
}: ToastProps): ReactElement => {
  const animatedValue = useRef(new Animated.Value(0)).current;
  const toastConfig = useToastConfig();

  useEffect(() => {
    if (autoDismiss && duration >= 0) {
      const id = setTimeout(() => onDismiss?.(), duration);

      return () => clearTimeout(id);
    }
  }, []);

  useEffect(() => {
    const animation = Animated.timing(animatedValue, {
      toValue: 1,
      useNativeDriver: true,
    });

    animation.start();

    return () => animation.stop();
  }, []);

  useLayoutEffect(() => {
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
  });

  const interpolateY = animatedValue.interpolate({
    inputRange: [0, 1],
    outputRange:
      toastConfig.position === 'top' ? [-20, distance] : [20, -distance],
  });

  return (
    <Container
      testID="toast-container"
      themeVariant={variant}
      themeIntent={intent}
      style={[
        style,
        {
          opacity: animatedValue,
          transform: [{ translateY: interpolateY }],
        },
      ]}
    >
      <ContentContainer showDivider={!!actionLabel}>
        {icon !== null ? (
          <ToastIcon
            themeIntent={intent}
            icon={icon || getIntentIcon(intent)}
          />
        ) : null}
        <TextContainer>
          {typeof content === 'string' ? (
            <StyledBody variant="small" themeIntent={intent}>
              {content}
            </StyledBody>
          ) : (
            content
          )}
        </TextContainer>
      </ContentContainer>
      {actionLabel ? (
        <CTAWrapper
          testID="toast-action-button"
          onPress={() => {
            onAction?.();
            onDismiss?.();
          }}
        >
          {typeof actionLabel === 'string' ? (
            <StyledBody variant="small-bold" themeIntent={intent}>
              {actionLabel}
            </StyledBody>
          ) : (
            actionLabel
          )}
        </CTAWrapper>
      ) : null}
    </Container>
  );
};

export default Toast;
