import React, {memo, useMemo} from 'react';
import {StyleProp, ViewStyle} from 'react-native';
import Animated, {
  Easing,
  EntryAnimationsValues,
  ExitAnimationsValues,
  LayoutAnimationConfig,
  withTiming,
} from 'react-native-reanimated';
import {Typography} from '@components/_core/Typography';
import {useTheme} from '@shared/theme';

import {BadgeVariant} from './interfaces';
import {getVariantColor, styles} from './styles';

export interface BadgeProps {
  show?: boolean;
  variant?: BadgeVariant;
  value?: number;
  style?: StyleProp<ViewStyle>;
}

const customEntering = (_: EntryAnimationsValues) => {
  'worklet';
  const animations = {
    transform: [
      {scale: withTiming(1, {duration: 250, easing: Easing.elastic(1)})},
    ],
  };
  const initialValues = {transform: [{scale: 0}]};
  return {initialValues, animations};
};

const customExiting = (_: ExitAnimationsValues) => {
  'worklet';
  const animations = {
    transform: [{scale: withTiming(0, {duration: 250, easing: Easing.linear})}],
  };
  const initialValues = {transform: [{scale: 1}]};
  return {initialValues, animations};
};

function BadgeComponent({
  style,
  show,
  value = 0,
  variant = 'primary',
}: BadgeProps) {
  const {theme} = useTheme();

  // Memoize expensive calculations
  const backgroundColor = useMemo(
    () => getVariantColor(variant, theme),
    [variant, theme],
  );

  // Group value-related calculations together
  const valueCalculations = useMemo(() => {
    const isBigValue = value > 99;
    const displayText = value ? (isBigValue ? '+99' : value.toString()) : '';

    return {
      isBigValue,
      displayText,
    };
  }, [value]);

  const badgeStyles = useMemo(
    () => [
      styles.container,
      valueCalculations.isBigValue && styles.bigContainer,
      {backgroundColor},
      style,
    ],
    [valueCalculations.isBigValue, backgroundColor, style],
  );

  const dotStyles = useMemo(
    () => [
      styles.dot,
      {borderColor: theme.background.layout.tertiary, backgroundColor},
      style,
    ],
    [theme.background.layout.tertiary, backgroundColor, style],
  );

  const memoizedStyle = useMemo<StyleProp<ViewStyle>>(() => {
    return [value || variant === 'info' ? badgeStyles : dotStyles];
  }, [value, variant, badgeStyles, dotStyles]);

  return (
    <LayoutAnimationConfig skipEntering>
      {show && (
        <Animated.View
          entering={customEntering}
          exiting={customExiting}
          style={memoizedStyle}>
          {!!value && (
            <Typography
              variant="xxs"
              weight="semiBold"
              color={theme.text.neutral.inverted}
              id="badgeText">
              {valueCalculations.displayText}
            </Typography>
          )}
        </Animated.View>
      )}
    </LayoutAnimationConfig>
  );
}

export const Badge = memo(BadgeComponent);

export {BADGE_SIZES} from './styles';
