import React, { useEffect, useRef, useState } from 'react';
import { Text as RNText, TextProps, StyleSheet, Animated, Easing, View } from 'react-native';

export interface AwesomeTextProps extends TextProps {
  variant?: 'h1' | 'h2' | 'h3' | 'body' | 'caption';
  color?: string;
  weight?: 'normal' | 'bold' | 'light';
  align?: 'left' | 'center' | 'right';
  customStyle?: object;
  animation?: 'bounce' | 'zoom' | 'none';
  duration?: number;
  delay?: number;
  containerStyle?: object;
  minZoom?: number;
  maxZoom?: number;
}

const AwesomeText: React.FC<AwesomeTextProps> = ({
  variant = 'body',
  color = '#000000',
  weight = 'normal',
  align = 'left',
  customStyle,
  children,
  animation = 'none',
  duration = 1000,
  delay = 0,
  containerStyle,
  minZoom = 0.8,
  maxZoom = 1.2,
  ...props
}) => {
  const [isMounted, setIsMounted] = useState(false);
  // Animation values
  const bounceValue = useRef(new Animated.Value(0)).current;
  const zoomValue = useRef(new Animated.Value(1)).current;
  const animationRef = useRef<Animated.CompositeAnimation | null>(null);

  // Bounce Animation
  const startBounceAnimation = () => {
    if (animationRef.current) {
      animationRef.current.stop();
    }

    animationRef.current = Animated.loop(
      Animated.sequence([
        Animated.timing(bounceValue, {
          toValue: 1,
          duration: duration / 2,
          useNativeDriver: true,
          easing: Easing.out(Easing.bounce),
          isInteraction: false,
        }),
        Animated.timing(bounceValue, {
          toValue: 0,
          duration: duration / 2,
          useNativeDriver: true,
          easing: Easing.in(Easing.bounce),
          isInteraction: false,
        }),
      ]),
      { iterations: -1 }
    );
    
    animationRef.current.start();
  };

  // Zoom Animation
  const startZoomAnimation = () => {
    if (animationRef.current) {
      animationRef.current.stop();
    }

    animationRef.current = Animated.loop(
      Animated.sequence([
        Animated.timing(zoomValue, {
          toValue: maxZoom,
          duration: duration,
          useNativeDriver: true,
          easing: Easing.bezier(0.4, 0, 0.2, 1),
          isInteraction: false,
        }),
        Animated.timing(zoomValue, {
          toValue: minZoom,
          duration: duration,
          useNativeDriver: true,
          easing: Easing.bezier(0.4, 0, 0.2, 1),
          isInteraction: false,
        }),
      ]),
      { 
        iterations: -1,
        resetBeforeIteration: true
      }
    );
    
    animationRef.current.start();
  };

  useEffect(() => {
    setIsMounted(true);
    return () => setIsMounted(false);
  }, []);

  useEffect(() => {
    if (!isMounted) return;

    // Reset animations
    bounceValue.setValue(0);
    zoomValue.setValue(minZoom);

    // Start new animations after a small delay
    const animationTimeout = setTimeout(() => {
      if (animation === 'bounce') {
        requestAnimationFrame(() => startBounceAnimation());
      } else if (animation === 'zoom') {
        requestAnimationFrame(() => startZoomAnimation());
      }
    }, delay);

    // Cleanup function to stop animations
    return () => {
      clearTimeout(animationTimeout);
      if (animationRef.current) {
        animationRef.current.stop();
      }
      bounceValue.stopAnimation();
      zoomValue.stopAnimation();
    };
  }, [animation, duration, delay, bounceValue, zoomValue, isMounted]);

  const getVariantStyle = () => {
    switch (variant) {
      case 'h1':
        return styles.h1;
      case 'h2':
        return styles.h2;
      case 'h3':
        return styles.h3;
      case 'caption':
        return styles.caption;
      default:
        return styles.body;
    }
  };

  const getWeightStyle = () => {
    switch (weight) {
      case 'bold':
        return styles.bold;
      case 'light':
        return styles.light;
      default:
        return styles.normal;
    }
  };

  const getAnimationStyle = () => {
    if (animation === 'bounce') {
      return {
        transform: [
          {
            translateY: bounceValue.interpolate({
              inputRange: [0, 1],
              outputRange: [0, -15],
            }),
          },
        ],
      };
    }
    if (animation === 'zoom') {
      return {
        transform: [
          { scale: zoomValue }
        ],
      };
    }
    return {};
  };

  const AnimatedText = Animated.createAnimatedComponent(RNText);

  return (
    <View
      style={[styles.container, containerStyle]}
    >
      <AnimatedText
        style={[
          getVariantStyle(),
          getWeightStyle(),
          { color, textAlign: align },
          getAnimationStyle(),
          customStyle,
        ]}
        {...props}
      >
        {children}
      </AnimatedText>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    overflow: 'hidden',
    alignItems: 'center',
    justifyContent: 'center',
  },
  h1: {
    fontSize: 32,
    lineHeight: 40,
  },
  h2: {
    fontSize: 24,
    lineHeight: 32,
  },
  h3: {
    fontSize: 20,
    lineHeight: 28,
  },
  body: {
    fontSize: 16,
    lineHeight: 24,
  },
  caption: {
    fontSize: 12,
    lineHeight: 16,
  },
  bold: {
    fontWeight: 'bold',
  },
  normal: {
    fontWeight: 'normal',
  },
  light: {
    fontWeight: '300',
  },
});

export default AwesomeText; 