import React, {
  ForwardedRef,
  forwardRef,
  ReactNode,
  useCallback,
  useImperativeHandle,
  useMemo,
  useRef,
} from 'react';
import { Keyboard } from 'react-native';
import BottomSheetCore, {
  BottomSheetView,
  useBottomSheetDynamicSnapPoints,
} from '@gorhom/bottom-sheet';
import { X } from 'phosphor-react-native';
import Animated, {
  Extrapolate,
  interpolate,
  useAnimatedStyle,
} from 'react-native-reanimated';
import { Box } from '../Box';
import { Text } from '../Text';
import { TouchableComponent } from '../TouchableComponent';
import { Divisor } from '../Divisor';
import { colors } from '../../theme/theme';
import type { BottomSheetDefaultBackdropProps } from '@gorhom/bottom-sheet/lib/typescript/components/bottomSheetBackdrop/types';

export interface IBottomSheet {
  title: string;
  children: ReactNode;
  full?: boolean;
  backDrop?: boolean;
  backDropColor?: string;
  onChange?: (index: number) => void;
  onClose?: () => void;
}

export const BottomSheet = forwardRef(
  (
    {
      title,
      children,
      full = false,
      onChange,
      onClose,
      backDrop = false,
      backDropColor = colors.yankeesBlue,
    }: IBottomSheet,
    ref: ForwardedRef<{ show: () => void; hide: () => void } | undefined>
  ) => {
    const bottomSheetModalRef = useRef<BottomSheetCore>(null);
    const initialSnapPoints = useMemo(() => ['CONTENT_HEIGHT', '100%'], []);

    const {
      animatedHandleHeight,
      animatedSnapPoints,
      animatedContentHeight,
      handleContentLayout,
    } = useBottomSheetDynamicSnapPoints(initialSnapPoints);

    const show = useCallback(() => {
      if (full) {
        bottomSheetModalRef.current?.expand();
      } else {
        bottomSheetModalRef.current?.snapToIndex(0);
      }
    }, [full]);

    const hide = useCallback(() => {
      Keyboard.dismiss();
      bottomSheetModalRef.current?.close();
    }, []);

    useImperativeHandle(ref, () => ({ show, hide }));

    const CustomBackdrop = ({
      animatedIndex,
      style,
    }: BottomSheetDefaultBackdropProps) => {
      const containerAnimatedStyle = useAnimatedStyle(() => ({
        opacity: interpolate(
          animatedIndex.value,
          [-1, 1],
          [0, 1],
          Extrapolate.CLAMP
        ),
      }));

      const containerStyle = useMemo(
        () => [
          style,
          {
            backgroundColor: backDropColor,
          },
          containerAnimatedStyle,
        ],
        [style, containerAnimatedStyle]
      );

      return <Animated.View style={containerStyle} pointerEvents={'none'} />;
    };

    const renderBackdrop = useCallback(
      (props: any) => <CustomBackdrop {...props} />,
      []
    );

    return (
      <BottomSheetCore
        ref={bottomSheetModalRef}
        snapPoints={animatedSnapPoints}
        enablePanDownToClose={true}
        index={-1}
        handleHeight={animatedHandleHeight}
        contentHeight={animatedContentHeight}
        onClose={onClose}
        onChange={onChange}
        backdropComponent={backDrop ? renderBackdrop : null}
      >
        <BottomSheetView onLayout={handleContentLayout}>
          <Box
            padding={'spacing-s'}
            flexDirection={'row'}
            justifyContent={'space-between'}
          >
            <Text variant={'H4'}>{title}</Text>
            <TouchableComponent onPress={hide}>
              <X size={20} />
            </TouchableComponent>
          </Box>
          <Divisor type="line" />
          <Box paddingHorizontal={'spacing-s'} paddingVertical={'spacing-m'}>
            {children}
          </Box>
        </BottomSheetView>
      </BottomSheetCore>
    );
  }
);
