import React, {Fragment, useEffect, useMemo, useState} from 'react';
import {StyleProp, ViewStyle, StyleSheet} from 'react-native';
import {BottomSheetScrollView, BottomSheetView} from '@gorhom/bottom-sheet';
import {
  BottomModalRoot,
  BottomModalRootProps,
  BottomModalFooter,
  BottomModalFooterProps,
  BottomModalHeader,
  BottomModalHeaderProps,
} from '@components/_core/Modals';
import {useSafeAreaBottomPadding} from '@hooks/useSafeAreaBottomPadding';
import {useKeyboard} from '@shared/hooks/useKeyboard';
import {SPACING} from '@shared/theme';

import {styles} from './styles';

export interface DialogProps
  extends Omit<BottomModalRootProps, 'footerComponent'>,
    Omit<BottomModalHeaderProps, 'style'> {
  footer?: BottomModalFooterProps;
  /**
   * Optional paddingBottom override for the footer when the keyboard is visible.
   * Useful for keeping a consistent gap between the keyboard and the footer.
   */
  footerKeyboardPaddingBottom?: number;
  /**
   * @deprecated Use `wrapperType` instead
   */
  scrollable?: boolean;
  contentStyle?: StyleProp<ViewStyle>;
  headerStyle?: StyleProp<ViewStyle>;
  /**
   * The type of wrapper to use for the content.
   * - `scrollable`: Use a `BottomSheetScrollView` to wrap the content.
   * - `view`: Use a `BottomSheetView` to wrap the content.
   * - `none`: Don't wrap the content.
   * @default 'view'
   */
  wrapperType?: 'scrollable' | 'view' | 'none';
}

export function Dialog({
  children,
  contentStyle,
  title,
  subtitle,
  titleNumberOfLines,
  onClose,
  scrollable = false,
  footer,
  footerKeyboardPaddingBottom,
  onGoBack,
  withBackButton,
  withCloseButton,
  headerStyle,
  wrapperType = 'view',
  isVisible,
  ...props
}: DialogProps) {
  const paddingBottom = useSafeAreaBottomPadding();
  const [footerHeight, setFooterHeight] = useState(0);
  const [isKeyboardVisible, setIsKeyboardVisible] = useState(false);

  useKeyboard(
    {
      dependency: isVisible,
      onShow: () => setIsKeyboardVisible(true),
      onHide: () => setIsKeyboardVisible(false),
    },
    true,
  );
  const WrapperComponent = useMemo(
    () =>
      scrollable || wrapperType === 'scrollable'
        ? BottomSheetScrollView
        : wrapperType === 'view'
        ? BottomSheetView
        : Fragment,
    [scrollable, wrapperType],
  );

  const headerComponent = useMemo(
    () => (
      <BottomModalHeader
        title={title}
        subtitle={subtitle}
        titleNumberOfLines={titleNumberOfLines}
        onClose={onClose}
        onGoBack={onGoBack}
        withBackButton={withBackButton}
        withCloseButton={withCloseButton}
        style={headerStyle}
      />
    ),
    [
      headerStyle,
      onClose,
      onGoBack,
      title,
      subtitle,
      titleNumberOfLines,
      withBackButton,
      withCloseButton,
    ],
  );

  // Need the StyleSheet.flatten to apply the styles correctly
  const contentStyles = StyleSheet.flatten([
    styles.content,
    {paddingBottom: (footerHeight || paddingBottom) + SPACING.x2},
    contentStyle,
  ]);

  useEffect(() => {
    if (!footer) {
      setFooterHeight(0);
    }
  }, [footer]);

  return (
    <BottomModalRoot
      isVisible={isVisible}
      footerComponent={
        footer ? (
          <BottomModalFooter
            footer={footer}
            setFooterHeight={setFooterHeight}
            style={
              isKeyboardVisible && footerKeyboardPaddingBottom !== undefined
                ? {paddingBottom: footerKeyboardPaddingBottom}
                : undefined
            }
          />
        ) : null
      }
      onClose={onClose}
      {...props}>
      <WrapperComponent
        {...(wrapperType === 'none' ? {} : {style: contentStyles})}>
        {headerComponent}
        {children}
      </WrapperComponent>
    </BottomModalRoot>
  );
}
