import React from 'react';
import type {
  FlatListProps,
  ScrollViewProps as RnScrollViewProps,
  SectionListProps,
} from 'react-native';
import { Animated } from 'react-native';
import type { ActionGroupProps } from '../FAB/ActionGroup';
import type { FABProps } from '../FAB/FAB';
import AnimatedFAB from './AnimatedFAB';

interface AnimatedScrollerProps<T> {
  /**
   * Scroll component, it can be ScrollView, FlatList or SectionList.
   */
  ScrollComponent: React.ReactElement<
    RnScrollViewProps | FlatListProps<T> | SectionListProps<T>
  >;
  /**
   * FAB or FAB.ActionGroup props.
   */
  fabProps: FABProps | ActionGroupProps;
}

function AnimatedScroller<T>({
  ScrollComponent,
  fabProps,
}: AnimatedScrollerProps<T>) {
  const contentOffsetY = React.useRef(new Animated.Value(0)).current;
  const contentHeight = React.useRef(new Animated.Value(0)).current;
  const layoutHeight = React.useRef(new Animated.Value(0)).current;

  // Common props for all ScrollView, FlatList and SectionList.
  const { onScroll, scrollEventThrottle } = ScrollComponent.props;

  return (
    <>
      {React.cloneElement(ScrollComponent, {
        ...ScrollComponent.props,
        scrollEventThrottle: scrollEventThrottle || 100,
        onScroll: Animated.event(
          [
            {
              nativeEvent: {
                contentOffset: { y: contentOffsetY },
                contentSize: { height: contentHeight },
                layoutMeasurement: { height: layoutHeight },
              },
            },
          ],
          {
            useNativeDriver: false,
            listener: onScroll,
          }
        ),
      })}

      {!!fabProps && (
        <AnimatedFAB
          fabProps={fabProps}
          contentOffsetY={contentOffsetY}
          contentHeight={contentHeight}
          layoutHeight={layoutHeight}
        />
      )}
    </>
  );
}

export default AnimatedScroller;
