import React, { useCallback } from 'react';
import { FlatList, FlatListProps, ViewStyle, RefreshControl } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
  withDelay,
  withSpring,
  FadeIn,
  SlideInRight,
  Layout,
} from 'react-native-reanimated';
import { useTheme } from '../../theme/ThemeContext';

const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);

interface AnimatedListProps<T> extends Omit<FlatListProps<T>, 'renderItem'> {
  renderItem: (info: { item: T; index: number }) => React.ReactElement;
  /** Delay base entre items en ms */
  staggerDelay?: number;
  /** Tipo de animación de entrada */
  animationType?: 'fade' | 'slide' | 'spring';
  /** Mostrar animación al refrescar */
  animateOnRefresh?: boolean;
  /** Callback de refresh */
  onRefresh?: () => Promise<void> | void;
  /** Está refrescando */
  isRefreshing?: boolean;
}

/**
 * Item animado wrapper
 */
function AnimatedItem({
  children,
  index,
  staggerDelay,
  animationType,
}: {
  children: React.ReactNode;
  index: number;
  staggerDelay: number;
  animationType: 'fade' | 'slide' | 'spring';
}) {
  const delay = Math.min(index * staggerDelay, 500); // Cap máximo de delay

  const entering = (() => {
    switch (animationType) {
      case 'slide':
        return SlideInRight.delay(delay).duration(300);
      case 'spring':
        return FadeIn.delay(delay).springify();
      case 'fade':
      default:
        return FadeIn.delay(delay).duration(300);
    }
  })();

  return (
    <Animated.View entering={entering} layout={Layout.springify()}>
      {children}
    </Animated.View>
  );
}

/**
 * FlatList con animaciones de entrada staggered
 */
export function AnimatedList<T>({
  data,
  renderItem,
  staggerDelay = 50,
  animationType = 'fade',
  animateOnRefresh = true,
  onRefresh,
  isRefreshing = false,
  ...props
}: AnimatedListProps<T>) {
  const { colors } = useTheme();
  const [key, setKey] = React.useState(0);

  const handleRefresh = useCallback(async () => {
    if (onRefresh) {
      await onRefresh();
      if (animateOnRefresh) {
        setKey((prev) => prev + 1);
      }
    }
  }, [onRefresh, animateOnRefresh]);

  const animatedRenderItem = useCallback(
    ({ item, index }: { item: T; index: number }) => (
      <AnimatedItem
        index={index}
        staggerDelay={staggerDelay}
        animationType={animationType}
      >
        {renderItem({ item, index })}
      </AnimatedItem>
    ),
    [renderItem, staggerDelay, animationType]
  );

  return (
    <FlatList
      key={key}
      data={data}
      renderItem={animatedRenderItem}
      refreshControl={
        onRefresh ? (
          <RefreshControl
            refreshing={isRefreshing}
            onRefresh={handleRefresh}
            tintColor={colors.primary}
            colors={[colors.primary]}
          />
        ) : undefined
      }
      {...(props as any)}
    />
  );
}

/**
 * Hook para crear estilos animados de item de lista
 */
export function useListItemEntering(index: number, baseDelay = 50) {
  const delay = Math.min(index * baseDelay, 500);

  return FadeIn.delay(delay).duration(300);
}

/**
 * Componente para animar un item individual
 */
export function AnimatedListItem({
  children,
  index,
  baseDelay = 50,
  style,
}: {
  children: React.ReactNode;
  index: number;
  baseDelay?: number;
  style?: ViewStyle;
}) {
  const entering = useListItemEntering(index, baseDelay);

  return (
    <Animated.View entering={entering} style={style}>
      {children}
    </Animated.View>
  );
}
