"use strict";

import { useCallback, useRef, useState, useEffect, useMemo, forwardRef, useImperativeHandle } from 'react';
import { View, Text, StyleSheet, Platform, Animated, StatusBar, Keyboard, AppState } from 'react-native';
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { OxyContextProvider, useOxy } from '../context/OxyContext';
import OxyRouter from '../navigation/OxyRouter';
import { FontLoader, setupFonts } from './FontLoader';
import { Toaster } from '../../lib/sonner';
import { QueryClient, QueryClientProvider, focusManager } from '@tanstack/react-query';

// Import bottom sheet components directly - no longer a peer dependency
import { BottomSheetModal, BottomSheetBackdrop, BottomSheetModalProvider, BottomSheetScrollView } from '@gorhom/bottom-sheet';
import { useWindowDimensions } from 'react-native';

// Initialize fonts automatically
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
setupFonts();

/**
 * Enhanced OxyProvider component
 * 
 * This component serves two purposes:
 * 1. As a context provider for authentication and session management across the app
 * 2. As a UI component for authentication and account management using a bottom sheet
 */
const OxyProvider = props => {
  const {
    oxyServices,
    children,
    contextOnly = false,
    onAuthStateChange,
    storageKeyPrefix,
    showInternalToaster = true,
    baseURL,
    // Add support for baseURL
    ...bottomSheetProps
  } = props;

  // Create typed internal bottom sheet controller ref
  const internalBottomSheetRef = useRef(null);

  // Initialize React Query Client (use provided client or create a default one once)
  const queryClientRef = useRef(null);
  if (!queryClientRef.current) {
    queryClientRef.current = props.queryClient ?? new QueryClient({
      defaultOptions: {
        queries: {
          staleTime: 30_000,
          gcTime: 5 * 60_000,
          retry: 2,
          refetchOnReconnect: true,
          refetchOnWindowFocus: false
        },
        mutations: {
          retry: 1
        }
      }
    });
  }

  // Hook React Query focus manager into React Native AppState
  useEffect(() => {
    const subscription = AppState.addEventListener('change', state => {
      focusManager.setFocused(state === 'active');
    });
    return () => {
      subscription.remove();
    };
  }, []);

  // Mirror internal controller to external ref if provided (back-compat)
  useEffect(() => {
    if (props.bottomSheetRef) {
      props.bottomSheetRef.current = internalBottomSheetRef.current;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.bottomSheetRef]);

  // If contextOnly is true, we just provide the context without the bottom sheet UI
  if (contextOnly) {
    return /*#__PURE__*/_jsx(QueryClientProvider, {
      client: queryClientRef.current,
      children: /*#__PURE__*/_jsx(OxyContextProvider, {
        oxyServices: oxyServices,
        baseURL: baseURL,
        storageKeyPrefix: storageKeyPrefix,
        onAuthStateChange: onAuthStateChange,
        children: children
      })
    });
  }

  // Otherwise, provide both the context and the bottom sheet UI
  return /*#__PURE__*/_jsx(QueryClientProvider, {
    client: queryClientRef.current,
    children: /*#__PURE__*/_jsx(OxyContextProvider, {
      oxyServices: oxyServices,
      baseURL: baseURL,
      storageKeyPrefix: storageKeyPrefix,
      onAuthStateChange: onAuthStateChange,
      bottomSheetRef: internalBottomSheetRef,
      children: /*#__PURE__*/_jsx(FontLoader, {
        children: /*#__PURE__*/_jsxs(GestureHandlerRootView, {
          style: styles.gestureHandlerRoot,
          children: [/*#__PURE__*/_jsxs(BottomSheetModalProvider, {
            children: [/*#__PURE__*/_jsx(StatusBar, {
              translucent: true,
              backgroundColor: "transparent"
            }), /*#__PURE__*/_jsxs(SafeAreaProvider, {
              children: [/*#__PURE__*/_jsx(OxyBottomSheet, {
                ...bottomSheetProps,
                ref: internalBottomSheetRef,
                oxyServices: oxyServices
              }), children]
            })]
          }), !showInternalToaster && /*#__PURE__*/_jsx(View, {
            style: styles.toasterContainer,
            children: /*#__PURE__*/_jsx(Toaster, {
              position: "bottom-center",
              swipeToDismissDirection: "left",
              offset: 15
            })
          })]
        })
      })
    })
  });
};

/**
 * OxyBottomSheet component - A bottom sheet-based authentication and account management UI
 * 
 * This is the original OxyProvider UI functionality, now extracted into its own component
 * and reimplemented using BottomSheetModal for better Android compatibility
 */

const OxyBottomSheet = /*#__PURE__*/forwardRef(({
  oxyServices: providedOxyServices,
  initialScreen = 'SignIn',
  onClose,
  onAuthenticated,
  theme = 'light',
  customStyles = {},
  autoPresent = false,
  showInternalToaster = true,
  appInsets
}, ref) => {
  // Helper function to determine if native driver should be used
  const shouldUseNativeDriver = () => {
    return Platform.OS === 'ios';
  };
  // Get window dimensions for max height calculation
  const {
    height: windowHeight
  } = useWindowDimensions();
  // Get oxyServices from context if not provided as prop
  const contextOxy = useOxy();
  const oxyServices = providedOxyServices || contextOxy?.oxyServices;
  // Use the internal ref (which is passed as a prop from OxyProvider)
  const modalRef = useRef(null);
  const isOpenRef = useRef(false);
  const navigationRef = useRef(null);

  // Remove contentHeight, containerWidth, and snap point state/logic
  // Animation values - keep for content fade/slide
  const fadeAnim = useRef(new Animated.Value(Platform.OS === 'android' ? 1 : 0)).current;
  const slideAnim = useRef(new Animated.Value(Platform.OS === 'android' ? 0 : 50)).current;
  // Expose a clean, typed imperative API
  useImperativeHandle(ref, () => ({
    present: () => {
      if (!isOpenRef.current) modalRef.current?.present?.();
    },
    dismiss: () => modalRef.current?.dismiss?.(),
    expand: () => {
      // Ensure presented, then animate content in
      if (!isOpenRef.current) modalRef.current?.present?.();
      Animated.parallel([Animated.timing(fadeAnim, {
        toValue: 1,
        duration: 300,
        useNativeDriver: shouldUseNativeDriver()
      }), Animated.spring(slideAnim, {
        toValue: 0,
        friction: 8,
        tension: 40,
        useNativeDriver: shouldUseNativeDriver()
      })]).start();
    },
    collapse: () => modalRef.current?.collapse?.(),
    snapToIndex: index => modalRef.current?.snapToIndex?.(index),
    snapToPosition: position => modalRef.current?.snapToPosition?.(position),
    navigate: (screen, props) => {
      if (navigationRef.current) {
        navigationRef.current(screen, props);
        return;
      }
      if (typeof document !== 'undefined') {
        const event = new CustomEvent('oxy:navigate', {
          detail: {
            screen,
            props
          }
        });
        document.dispatchEvent(event);
      } else {
        globalThis.oxyNavigateEvent = {
          screen,
          props
        };
      }
    }
  }), [fadeAnim, slideAnim]);
  // Keyboard handling (unchanged)
  const [keyboardVisible, setKeyboardVisible] = useState(false);
  const [keyboardHeight, setKeyboardHeight] = useState(0);
  const insets = useSafeAreaInsets();

  // Calculate max height for dynamic sizing (screen height minus insets and margin)
  const maxHeight = useMemo(() => {
    const topInset = (insets?.top ?? 0) + (appInsets?.top ?? 0);
    const bottomInset = (insets?.bottom ?? 0) + (appInsets?.bottom ?? 0);
    return windowHeight - topInset - bottomInset - 20; // 20px margin
  }, [windowHeight, insets?.top, insets?.bottom, appInsets?.top, appInsets?.bottom]);
  useEffect(() => {
    // Use 'did' events on iOS to avoid multiple intermediate willShow updates
    const showEvent = Platform.OS === 'ios' ? 'keyboardDidShow' : 'keyboardDidShow';
    const hideEvent = Platform.OS === 'ios' ? 'keyboardDidHide' : 'keyboardDidHide';
    let lastH = 0;
    let lastTs = 0;
    const MIN_DELTA = 8;
    const MIN_INTERVAL = 80; // ms
    const onShow = e => {
      const h = e?.endCoordinates?.height ?? 0;
      const now = Date.now();
      if (Math.abs(h - lastH) < MIN_DELTA && now - lastTs < MIN_INTERVAL) return;
      lastH = h;
      lastTs = now;
      setKeyboardVisible(true);
      setKeyboardHeight(h);
    };
    const onHide = () => {
      lastH = 0;
      lastTs = Date.now();
      setKeyboardVisible(false);
      setKeyboardHeight(0);
    };
    const showSub = Keyboard.addListener(showEvent, onShow);
    const hideSub = Keyboard.addListener(hideEvent, onHide);
    return () => {
      showSub.remove();
      hideSub.remove();
    };
  }, []);
  // Present the modal when component mounts, but only if autoPresent is true
  useEffect(() => {
    if (autoPresent && modalRef.current) {
      const timer = setTimeout(() => {
        modalRef.current?.present();
        Animated.parallel([Animated.timing(fadeAnim, {
          toValue: 1,
          duration: 300,
          useNativeDriver: shouldUseNativeDriver()
        }), Animated.spring(slideAnim, {
          toValue: 0,
          friction: 8,
          tension: 40,
          useNativeDriver: shouldUseNativeDriver()
        })]).start();
      }, 100);
      return () => clearTimeout(timer);
    }
  }, [modalRef, autoPresent]);
  // Close the bottom sheet with animation (unchanged)
  const handleClose = useCallback(() => {
    Animated.timing(fadeAnim, {
      toValue: 0,
      duration: Platform.OS === 'android' ? 100 : 200,
      useNativeDriver: shouldUseNativeDriver()
    }).start(() => {
      modalRef.current?.dismiss();
      if (onClose) {
        setTimeout(() => {
          onClose();
        }, Platform.OS === 'android' ? 150 : 100);
      }
    });
  }, [onClose]);
  // Handle authentication success (unchanged)
  const handleAuthenticated = useCallback(user => {
    fadeAnim.stopAnimation();
    slideAnim.stopAnimation();
    if (onAuthenticated) {
      onAuthenticated(user);
    }
    modalRef.current?.dismiss();
    if (onClose) {
      setTimeout(() => {
        onClose();
      }, 100);
    }
  }, [onAuthenticated, onClose]);
  // Backdrop rendering (unchanged)
  const renderBackdrop = useCallback(props => /*#__PURE__*/_jsx(BottomSheetBackdrop, {
    ...props,
    disappearsOnIndex: -1,
    appearsOnIndex: 0,
    opacity: 0.5
  }), []);

  // Modernized BottomSheetModal usage
  return /*#__PURE__*/_jsxs(BottomSheetModal, {
    ref: modalRef,
    index: 0,
    enableDynamicSizing: true,
    maxDynamicContentSize: maxHeight,
    enablePanDownToClose: true,
    backdropComponent: renderBackdrop,
    backgroundStyle: [{
      borderBottomLeftRadius: 0,
      borderBottomRightRadius: 0,
      borderTopLeftRadius: 35,
      borderTopRightRadius: 35
    }],
    handleIndicatorStyle: {
      backgroundColor: customStyles.handleColor || (theme === 'light' ? '#CCCCCC' : '#444444'),
      width: 40,
      height: 4
    },
    handleStyle: {
      position: 'absolute',
      top: 0,
      left: 0,
      right: 0
    },
    style: styles.bottomSheetContainer,
    keyboardBehavior: "interactive",
    keyboardBlurBehavior: "restore",
    android_keyboardInputMode: "adjustPan",
    enableOverDrag: false,
    enableContentPanningGesture: true,
    enableHandlePanningGesture: true,
    overDragResistanceFactor: 2.5,
    enableBlurKeyboardOnGesture: true,
    detached: true,
    topInset: (insets?.top ?? 0) + (appInsets?.top ?? 0),
    bottomInset: (Platform.OS === 'android' ? keyboardVisible ? keyboardHeight : 0 : 0) + (appInsets?.bottom ?? 0),
    onChange: index => {
      isOpenRef.current = index !== -1;
    },
    onDismiss: () => {
      isOpenRef.current = false;
    },
    children: [/*#__PURE__*/_jsx(BottomSheetScrollView, {
      style: [styles.contentContainer],
      contentContainerStyle: styles.scrollContentContainer,
      showsVerticalScrollIndicator: true,
      bounces: false,
      nestedScrollEnabled: true,
      children: /*#__PURE__*/_jsx(Animated.View, {
        style: [styles.animatedContent, Platform.OS === 'android' ? {
          opacity: 1
        } : {
          opacity: fadeAnim,
          transform: [{
            translateY: slideAnim
          }]
        }],
        children: /*#__PURE__*/_jsx(View, {
          style: [styles.centeredContentWrapper, {
            paddingBottom: (insets?.bottom ?? 0) + (appInsets?.bottom ?? 0)
          }],
          children: oxyServices ? /*#__PURE__*/_jsx(OxyRouter, {
            oxyServices: oxyServices,
            initialScreen: initialScreen,
            onClose: handleClose,
            onAuthenticated: handleAuthenticated,
            theme: theme,
            navigationRef: navigationRef,
            containerWidth: 800 // static, since dynamic sizing is used
          }) : /*#__PURE__*/_jsx(View, {
            style: styles.errorContainer,
            children: /*#__PURE__*/_jsx(Text, {
              children: "OxyServices not available"
            })
          })
        })
      })
    }), showInternalToaster && /*#__PURE__*/_jsx(View, {
      style: styles.toasterContainer,
      children: /*#__PURE__*/_jsx(Toaster, {
        position: "bottom-center",
        swipeToDismissDirection: "left"
      })
    })]
  });
});
const styles = StyleSheet.create({
  bottomSheetContainer: {
    maxWidth: 800,
    width: '100%',
    alignSelf: 'center',
    marginHorizontal: 'auto'
  },
  contentContainer: {
    width: '100%',
    borderTopLeftRadius: 35,
    borderTopRightRadius: 35
  },
  scrollContentContainer: {
    // Content will size naturally, ScrollView handles overflow
  },
  centeredContentWrapper: {
    width: '100%',
    alignSelf: 'center'
  },
  animatedContent: {
    width: '100%'
  },
  indicator: {
    width: 40,
    height: 4,
    marginTop: 8,
    marginBottom: 8,
    borderRadius: 35
  },
  errorContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  gestureHandlerRoot: {
    flex: 1,
    position: 'relative',
    backgroundColor: 'transparent',
    ...Platform.select({
      android: {
        height: '100%',
        width: '100%'
      }
    })
  },
  toasterContainer: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    zIndex: 9999,
    elevation: 9999,
    // For Android
    pointerEvents: 'box-none' // Allow touches to pass through to underlying components
  }
});
export default OxyProvider;
//# sourceMappingURL=OxyProvider.js.map