import React, {useCallback, useMemo, useState} from 'react';
import {LayoutChangeEvent, View} from 'react-native';
import Animated, {
  useAnimatedScrollHandler,
  useAnimatedStyle,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';
import {
  KeyboardAwareScrollView,
  KeyboardAwareScrollViewProps,
} from 'react-native-keyboard-controller';
import {Button} from '@components/_HuGo/Button';
import {useSafeAreaBottomPadding} from '@hooks/useSafeAreaBottomPadding';
import {useTheme} from '@shared/theme';

import {styles} from './styles';

const AnimatedKeyboardAwareScrollView = Animated.createAnimatedComponent(
  KeyboardAwareScrollView,
);

export interface ScrollViewWithFooterProps
  extends KeyboardAwareScrollViewProps {
  submitText: string;
  onSubmit: () => void;
  buttonSubmitDisabled?: boolean;
  sticky?: boolean;
  isButtonLoading?: boolean;
  cancelText?: string;
  onCancel?: () => void;
  buttonCancelDisabled?: boolean;
  footerRatio?: number;
}

export function ScrollViewWithFooter({
  children,
  contentContainerStyle,
  submitText,
  onSubmit,
  buttonSubmitDisabled,
  sticky = true,
  isButtonLoading,
  cancelText,
  onCancel,
  buttonCancelDisabled,
  footerRatio = 1.5,
  ...props
}: ScrollViewWithFooterProps) {
  const {theme} = useTheme();
  const [footerHeight, setFooterHeight] = useState(0);

  const paddingBottom = useSafeAreaBottomPadding();
  const prevScrollY = useSharedValue(0);
  const footerOffset = useSharedValue(0);

  const paddingBottomContent = useMemo(
    () => footerHeight * footerRatio,
    [footerHeight, footerRatio],
  );
  const onLayoutFooter = useCallback(
    (event: LayoutChangeEvent) =>
      setFooterHeight(event.nativeEvent.layout.height),
    [],
  );

  // Scroll handler to update footer visibility
  const onScroll = useAnimatedScrollHandler({
    onScroll: event => {
      if (sticky) {
        return;
      }
      const currentY = event.contentOffset.y;
      const contentHeight = event.contentSize.height;
      const viewportHeight = event.layoutMeasurement.height;

      const isAtBottom = contentHeight - viewportHeight - currentY <= 10;

      if (!isAtBottom) {
        footerOffset.value = withTiming(
          currentY > prevScrollY.value ? 0 : footerHeight,
          {duration: 300},
        );
      }
      prevScrollY.value = currentY;
    },
  });

  const footerTranslateY = useAnimatedStyle(() =>
    sticky ? {} : {transform: [{translateY: footerOffset.value}]},
  );

  return (
    <View style={styles.container}>
      <AnimatedKeyboardAwareScrollView
        bounces={false}
        onScroll={onScroll}
        contentContainerStyle={[
          {paddingBottom: paddingBottomContent},
          contentContainerStyle,
        ]}
        scrollEventThrottle={16}
        {...props}>
        {children}
      </AnimatedKeyboardAwareScrollView>
      <Animated.View
        onLayout={onLayoutFooter}
        style={[
          {
            paddingBottom,
            backgroundColor: theme.background.layout.tertiary,
            shadowColor: theme.shadow.inverted,
          },
          styles.footer,
          footerTranslateY,
        ]}>
        <Button
          size="lg"
          text={submitText}
          onPress={onSubmit}
          disabled={buttonSubmitDisabled}
          isLoading={isButtonLoading}
        />
        {cancelText && onCancel && (
          <Button
            size="lg"
            text={cancelText}
            onPress={onCancel}
            disabled={buttonCancelDisabled}
            variant="secondary"
          />
        )}
      </Animated.View>
    </View>
  );
}
