import {useCallback, useEffect, useMemo, useState} from 'react';
import {LayoutChangeEvent, StyleProp, View, ViewStyle} from 'react-native';
import {useTranslation} from 'react-i18next';
import {IconPlayerStop} from '@tabler/icons-react-native';
import {Pressable} from '@components/_core/Pressable';
import {Typography} from '@components/_core/Typography';
import {useTheme} from '@shared/theme';

import {ButtonSize} from '../../interfaces';
import {getColorsByVariant} from '../../utils';
import {
  AI_BUTTON_GRADIENT_COLORS,
  AI_BUTTON_GRADIENT_PRESSED_COLORS,
} from './constants';
import {AnimatedAIGradient} from './components/AnimatedAIGradient';
import {AnimatedSparklesIcon} from './components/AnimatedSparklesIcon';
import {styles} from './styles';

interface Props {
  text: string;
  testID?: string;
  hitSlop?: number;
  size?: ButtonSize;
  disabled?: boolean;
  onPress?: () => void;
  isInProgress?: boolean;
  style?: StyleProp<ViewStyle>;
}

export function AIButton({
  text,
  style,
  testID,
  hitSlop,
  onPress,
  disabled,
  size = 'sm',
  isInProgress = false,
}: Props) {
  const {t} = useTranslation();
  const {theme, iconSizes} = useTheme();
  const [isPressed, setIsPressed] = useState(false);
  const [contentWidth, setContentWidth] = useState(0);

  useEffect(() => {
    setContentWidth(0);
  }, [text, size]);

  const {backgroundColor, textColor} = useMemo(
    () =>
      getColorsByVariant({
        theme,
        disabled,
        variant: 'primary',
      }),
    [disabled, theme],
  );

  const onPressIn = useCallback(() => {
    if (!disabled && !isInProgress) {
      setIsPressed(true);
    }
  }, [disabled, isInProgress]);

  const onPressOut = useCallback(() => {
    setIsPressed(false);
  }, []);

  const accessibilityLabel = isInProgress ? t('general.stop') : text;

  const onIdleContentLayout = useCallback(
    (event: LayoutChangeEvent) => {
      if (!isInProgress) {
        setContentWidth(event.nativeEvent.layout.width);
      }
    },
    [isInProgress],
  );

  const lockedWidthStyle =
    isInProgress && contentWidth > 0 ? {minWidth: contentWidth} : undefined;

  const contentStyle = [
    styles.gradient,
    styles[size],
    isInProgress && styles.gradientInProgress,
  ];

  const content = isInProgress ? (
    <IconPlayerStop size={iconSizes.x6} color={textColor} />
  ) : (
    <>
      <AnimatedSparklesIcon
        size={iconSizes.x4}
        color={textColor}
        isAnimating={!disabled}
      />
      <Typography
        numberOfLines={1}
        weight="semiBold"
        color={textColor}
        style={styles.text}
        variant={size === 'sm' ? 'xs' : 's'}>
        {text}
      </Typography>
    </>
  );

  return (
    <Pressable
      testID={testID}
      hitSlop={hitSlop}
      activeOpacity={1}
      disabled={disabled}
      onPressIn={onPressIn}
      onPressOut={onPressOut}
      onPress={onPress}
      accessibilityRole="button"
      backgroundColor="transparent"
      style={[styles.container, style]}
      accessibilityLabel={accessibilityLabel}
      accessibilityState={{disabled: !!disabled, busy: isInProgress}}>
      {disabled ? (
        <View
          onLayout={onIdleContentLayout}
          style={[contentStyle, lockedWidthStyle, {backgroundColor}]}>
          {content}
        </View>
      ) : isInProgress ? (
        <View
          style={[
            contentStyle,
            lockedWidthStyle,
            {backgroundColor: theme.button.background.primary.focus},
          ]}>
          {content}
        </View>
      ) : (
        <View collapsable={false} onLayout={onIdleContentLayout}>
          <AnimatedAIGradient
            style={contentStyle}
            isAnimating={!disabled}
            isPressed={isPressed && !disabled}
            defaultColors={AI_BUTTON_GRADIENT_COLORS}
            pressedColors={AI_BUTTON_GRADIENT_PRESSED_COLORS}>
            {content}
          </AnimatedAIGradient>
        </View>
      )}
    </Pressable>
  );
}
