"use strict";

import { createContext, useContext, useEffect, useCallback, useMemo, useRef, useState } from 'react';
import { View, Text } from 'react-native';
import { OxyServices } from '../../core';
import { DeviceManager } from '../../utils/deviceManager';
import { useSessionSocket } from '../hooks/useSessionSocket';
import { toast } from '../../lib/sonner';
import { useAuthStore } from '../stores/authStore';

// Define the context shape
// NOTE: We intentionally avoid importing useFollow here to prevent a require cycle.
// If consumers relied on `const { useFollow } = useOxy()`, we provide a lazy proxy below.
import { jsx as _jsx } from "react/jsx-runtime";
// Create the context with default values
const OxyContext = /*#__PURE__*/createContext(null);

// Props for the OxyContextProvider

// Platform storage implementation

// Web localStorage implementation
class WebStorage {
  async getItem(key) {
    return localStorage.getItem(key);
  }
  async setItem(key, value) {
    localStorage.setItem(key, value);
  }
  async removeItem(key) {
    localStorage.removeItem(key);
  }
  async clear() {
    localStorage.clear();
  }
}

// React Native AsyncStorage implementation
let AsyncStorage;

// Determine the platform and set up storage
const isReactNative = () => {
  return typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
};

// Get appropriate storage for the platform
const getStorage = async () => {
  if (isReactNative()) {
    if (!AsyncStorage) {
      try {
        const asyncStorageModule = await import('@react-native-async-storage/async-storage');
        AsyncStorage = asyncStorageModule.default;
      } catch (error) {
        console.error('Failed to import AsyncStorage:', error);
        throw new Error('AsyncStorage is required in React Native environment');
      }
    }
    return AsyncStorage;
  }
  return new WebStorage();
};

// Storage keys for sessions
const getStorageKeys = (prefix = 'oxy_session') => ({
  activeSessionId: `${prefix}_active_session_id`,
  // Only store the active session ID
  language: `${prefix}_language` // Store the selected language
});
export const OxyProvider = ({
  children,
  oxyServices: providedOxyServices,
  baseURL,
  storageKeyPrefix = 'oxy_session',
  onAuthStateChange,
  onError,
  bottomSheetRef
}) => {
  // Create oxyServices automatically if not provided
  const oxyServicesRef = useRef(null);
  if (!oxyServicesRef.current) {
    if (providedOxyServices) {
      oxyServicesRef.current = providedOxyServices;
    } else if (baseURL) {
      oxyServicesRef.current = new OxyServices({
        baseURL
      });
    } else {
      throw new Error('Either oxyServices or baseURL must be provided to OxyContextProvider');
    }
  }
  const oxyServices = oxyServicesRef.current;

  // Zustand state
  const user = useAuthStore(state => state.user);
  const isAuthenticated = useAuthStore(state => state.isAuthenticated);
  const isLoading = useAuthStore(state => state.isLoading);
  const error = useAuthStore(state => state.error);
  const loginSuccess = useAuthStore(state => state.loginSuccess);
  const loginFailure = useAuthStore(state => state.loginFailure);
  const logoutStore = useAuthStore(state => state.logout);

  // Local state for non-auth fields
  const [minimalUser, setMinimalUser] = useState(null);
  const [sessions, setSessions] = useState([]);
  const [activeSessionId, setActiveSessionId] = useState(null);
  const [storage, setStorage] = useState(null);
  const [currentLanguage, setCurrentLanguage] = useState('en-US');

  // Normalize language codes to BCP-47 (e.g., en-US)
  const normalizeLanguageCode = useCallback(lang => {
    if (!lang) return null;
    if (lang.includes('-')) return lang;
    const map = {
      en: 'en-US',
      es: 'es-ES',
      ca: 'ca-ES',
      fr: 'fr-FR',
      de: 'de-DE',
      it: 'it-IT',
      pt: 'pt-PT',
      ja: 'ja-JP',
      ko: 'ko-KR',
      zh: 'zh-CN',
      ar: 'ar-SA'
    };
    return map[lang] || lang;
  }, []);
  // Add a new state to track token restoration
  const [tokenReady, setTokenReady] = useState(false);

  // Storage keys (memoized to prevent infinite loops)
  const keys = useMemo(() => getStorageKeys(storageKeyPrefix), [storageKeyPrefix]);

  // Clear all storage - defined before initAuth to avoid dependency issues
  const clearAllStorage = useCallback(async () => {
    if (!storage) return;
    try {
      await storage.removeItem(keys.activeSessionId);
    } catch (err) {
      console.error('Clear storage error:', err);
    }
  }, [storage, keys]);

  // Initialize storage
  useEffect(() => {
    const initStorage = async () => {
      try {
        const platformStorage = await getStorage();
        setStorage(platformStorage);
      } catch (error) {
        console.error('Init storage failed', error);
        useAuthStore.setState({
          error: 'Failed to initialize storage'
        });
      }
    };
    initStorage();
  }, []);

  // Initialize authentication state
  useEffect(() => {
    const initAuth = async () => {
      if (!storage) return;
      useAuthStore.setState({
        isLoading: true
      });
      try {
        setTokenReady(false);

        // Load saved language preference
        const savedLanguageRaw = await storage.getItem(keys.language);
        const savedLanguage = normalizeLanguageCode(savedLanguageRaw) || savedLanguageRaw;
        if (savedLanguage) {
          setCurrentLanguage(savedLanguage);
        }

        // Try to restore active session from storage
        const storedActiveSessionId = await storage.getItem(keys.activeSessionId);
        if (storedActiveSessionId) {
          try {
            const validation = await oxyServices.validateSession(storedActiveSessionId, {
              useHeaderValidation: true
            });
            if (validation.valid) {
              setActiveSessionId(storedActiveSessionId);
              await oxyServices.getTokenBySession(storedActiveSessionId);
              const fullUser = await oxyServices.getUserBySession(storedActiveSessionId);
              loginSuccess(fullUser);
              setMinimalUser({
                id: fullUser.id,
                username: fullUser.username,
                avatar: fullUser.avatar
              });
              // Apply server language if present
              if (fullUser?.language) {
                try {
                  const serverLang = normalizeLanguageCode(fullUser.language) || fullUser.language;
                  await storage.setItem(keys.language, serverLang);
                  setCurrentLanguage(serverLang);
                } catch (e) {
                  console.warn('Failed to apply server language preference', e);
                }
              }
              const serverSessions = await oxyServices.getSessionsBySessionId(storedActiveSessionId);
              const clientSessions = serverSessions.map(s => ({
                sessionId: s.sessionId,
                deviceId: s.deviceId,
                expiresAt: s.expiresAt || new Date().toISOString(),
                lastActive: s.lastActive || new Date().toISOString(),
                userId: s.userId || fullUser.id
              }));
              setSessions(clientSessions);
              onAuthStateChange?.(fullUser);
            } else {
              await clearAllStorage();
            }
          } catch (e) {
            console.error('Session validation error', e);
            await clearAllStorage();
          }
        }
        setTokenReady(true);
      } catch (e) {
        console.error('Auth init error', e);
        await clearAllStorage();
      } finally {
        useAuthStore.setState({
          isLoading: false
        });
      }
    };
    initAuth();
  }, [storage, oxyServices, keys, onAuthStateChange, loginSuccess, clearAllStorage]);

  // Remove invalid session - refresh sessions from backend
  const removeInvalidSession = useCallback(async sessionId => {
    // Remove from local state
    const filteredSessions = sessions.filter(s => s.sessionId !== sessionId);
    setSessions(filteredSessions);

    // If there are other sessions, switch to the first one
    if (filteredSessions.length > 0) {
      await switchToSession(filteredSessions[0].sessionId);
    } else {
      // No valid sessions left
      setActiveSessionId(null);
      logoutStore();
      setMinimalUser(null);
      await storage?.removeItem(keys.activeSessionId);
      if (onAuthStateChange) {
        onAuthStateChange(null);
      }
    }
  }, [sessions, storage, keys, onAuthStateChange, logoutStore]);

  // Save active session ID to storage (only session ID, no user data)
  const saveActiveSessionId = useCallback(async sessionId => {
    if (!storage) return;
    await storage.setItem(keys.activeSessionId, sessionId);
  }, [storage, keys.activeSessionId]);

  // Switch to a different session
  const switchToSession = useCallback(async sessionId => {
    try {
      useAuthStore.setState({
        isLoading: true
      });

      // Get access token for this session
      await oxyServices.getTokenBySession(sessionId);

      // Load full user data
      const fullUser = await oxyServices.getUserBySession(sessionId);
      setActiveSessionId(sessionId);
      loginSuccess(fullUser);
      setMinimalUser({
        id: fullUser.id,
        username: fullUser.username,
        avatar: fullUser.avatar
      });
      await saveActiveSessionId(sessionId);
      // Apply server language if present
      if (fullUser?.language) {
        try {
          const serverLang = normalizeLanguageCode(fullUser.language) || fullUser.language;
          await storage?.setItem(keys.language, serverLang);
          setCurrentLanguage(serverLang);
        } catch (e) {
          console.warn('Failed to apply server language after switch', e);
        }
      }
      if (onAuthStateChange) {
        onAuthStateChange(fullUser);
      }
    } catch (error) {
      console.error('Switch session error:', error);
      useAuthStore.setState({
        error: 'Failed to switch session'
      });
    } finally {
      useAuthStore.setState({
        isLoading: false
      });
    }
  }, [oxyServices, onAuthStateChange, loginSuccess, saveActiveSessionId]);

  // Login method - only store session ID, retrieve data from backend
  const login = useCallback(async (username, password, deviceName) => {
    if (!storage) throw new Error('Storage not initialized');
    useAuthStore.setState({
      isLoading: true,
      error: null
    });
    try {
      // Get device fingerprint for enhanced device identification
      const deviceFingerprint = DeviceManager.getDeviceFingerprint();

      // Get or generate persistent device info
      const deviceInfo = await DeviceManager.getDeviceInfo();
      console.log('Auth - Using device fingerprint:', deviceFingerprint);
      console.log('Auth - Using device ID:', deviceInfo.deviceId);
      const response = await oxyServices.signIn(username, password, deviceName || deviceInfo.deviceName || DeviceManager.getDefaultDeviceName(), deviceFingerprint);

      // Handle MFA requirement
      if (response && response.mfaRequired) {
        const err = new Error('Multi-factor authentication required');
        err.code = 'MFA_REQUIRED';
        err.mfaToken = response.mfaToken;
        err.expiresAt = response.expiresAt;
        throw err;
      }

      // Set as active session (only store session ID)
      setActiveSessionId(response.sessionId);
      await saveActiveSessionId(response.sessionId);

      // Get access token for API calls
      await oxyServices.getTokenBySession(response.sessionId);

      // Load full user data from backend
      const fullUser = await oxyServices.getUserBySession(response.sessionId);
      loginSuccess(fullUser);
      setMinimalUser(response.user);

      // Load sessions from backend
      const serverSessions = await oxyServices.getSessionsBySessionId(response.sessionId);
      const clientSessions = serverSessions.map(serverSession => ({
        sessionId: serverSession.sessionId,
        deviceId: serverSession.deviceId,
        expiresAt: serverSession.expiresAt || new Date().toISOString(),
        lastActive: serverSession.lastActive || new Date().toISOString(),
        userId: serverSession.userId || fullUser.id
      }));
      setSessions(clientSessions);
      if (onAuthStateChange) {
        onAuthStateChange(fullUser);
      }
      return fullUser;
    } catch (error) {
      loginFailure(error.message || 'Login failed');
      throw error;
    } finally {
      useAuthStore.setState({
        isLoading: false
      });
    }
  }, [storage, oxyServices, saveActiveSessionId, loginSuccess, setMinimalUser, onAuthStateChange, loginFailure]);

  // Logout method
  const logout = useCallback(async targetSessionId => {
    if (!activeSessionId) return;
    try {
      const sessionToLogout = targetSessionId || activeSessionId;
      await oxyServices.logoutSession(activeSessionId, sessionToLogout);

      // Remove session from local state
      const filteredSessions = sessions.filter(s => s.sessionId !== sessionToLogout);
      setSessions(filteredSessions);

      // If logging out active session
      if (sessionToLogout === activeSessionId) {
        if (filteredSessions.length > 0) {
          // Switch to another session
          await switchToSession(filteredSessions[0].sessionId);
        } else {
          // No sessions left
          setActiveSessionId(null);
          logoutStore();
          setMinimalUser(null);
          await storage?.removeItem(keys.activeSessionId);
          if (onAuthStateChange) {
            onAuthStateChange(null);
          }
        }
      }
    } catch (error) {
      console.error('Logout error:', error);
      useAuthStore.setState({
        error: 'Logout failed'
      });
    }
  }, [activeSessionId, oxyServices, sessions, switchToSession, logoutStore, setMinimalUser, storage, keys.activeSessionId, onAuthStateChange]);

  // Logout all sessions
  const logoutAll = useCallback(async () => {
    console.log('logoutAll called with activeSessionId:', activeSessionId);
    if (!activeSessionId) {
      console.error('No active session ID found, cannot logout all');
      useAuthStore.setState({
        error: 'No active session found'
      });
      throw new Error('No active session found');
    }
    if (!oxyServices) {
      console.error('OxyServices not initialized');
      useAuthStore.setState({
        error: 'Service not available'
      });
      throw new Error('Service not available');
    }
    try {
      console.log('Calling oxyServices.logoutAllSessions with sessionId:', activeSessionId);
      await oxyServices.logoutAllSessions(activeSessionId);
      console.log('logoutAllSessions completed successfully');

      // Clear all local data
      setSessions([]);
      setActiveSessionId(null);
      logoutStore();
      setMinimalUser(null);
      await clearAllStorage();
      console.log('Local storage cleared');
      if (onAuthStateChange) {
        onAuthStateChange(null);
        console.log('Auth state change callback called');
      }
    } catch (error) {
      console.error('Logout all error:', error);
      useAuthStore.setState({
        error: `Logout all failed: ${error instanceof Error ? error.message : 'Unknown error'}`
      });
      throw error;
    }
  }, [activeSessionId, oxyServices, logoutStore, setMinimalUser, clearAllStorage, onAuthStateChange]);

  // Effect to restore token on app load or session switch
  useEffect(() => {
    const restoreToken = async () => {
      if (activeSessionId && oxyServices) {
        try {
          await oxyServices.getTokenBySession(activeSessionId);
          setTokenReady(true);
        } catch (err) {
          // If token restoration fails, force logout
          await logout();
          setTokenReady(false);
        }
      } else {
        setTokenReady(true); // No session, so token is not needed
      }
    };
    restoreToken();
    // Only run when activeSessionId or oxyServices changes
  }, [activeSessionId, oxyServices, logout]);

  // Sign up method
  const signUp = useCallback(async (username, email, password) => {
    if (!storage) throw new Error('Storage not initialized');
    useAuthStore.setState({
      isLoading: true,
      error: null
    });
    try {
      // Create new account using the OxyServices signUp method
      const response = await oxyServices.signUp(username, email, password);
      console.log('SignUp successful:', response);

      // Now log the user in to create a session
      // This will handle the session creation and device registration
      const user = await login(username, password);
      return user;
    } catch (error) {
      loginFailure(error.message || 'Sign up failed');
      throw error;
    } finally {
      useAuthStore.setState({
        isLoading: false
      });
    }
  }, [storage, oxyServices, login, loginFailure]);

  // Complete MFA login by verifying TOTP
  const completeMfaLogin = useCallback(async (mfaToken, code) => {
    if (!storage) throw new Error('Storage not initialized');
    useAuthStore.setState({
      isLoading: true,
      error: null
    });
    try {
      const response = await oxyServices.verifyTotpLogin(mfaToken, code);

      // Set as active session
      setActiveSessionId(response.sessionId);
      await saveActiveSessionId(response.sessionId);

      // Fetch access token and user data
      await oxyServices.getTokenBySession(response.sessionId);
      const fullUser = await oxyServices.getUserBySession(response.sessionId);
      loginSuccess(fullUser);
      setMinimalUser({
        id: fullUser.id,
        username: fullUser.username,
        avatar: fullUser.avatar
      });
      // Apply server language if present
      if (fullUser?.language) {
        try {
          const serverLang = normalizeLanguageCode(fullUser.language) || fullUser.language;
          await storage.setItem(keys.language, serverLang);
          setCurrentLanguage(serverLang);
        } catch (e) {
          console.warn('Failed to apply server language on MFA login', e);
        }
      }

      // Load sessions list
      const serverSessions = await oxyServices.getSessionsBySessionId(response.sessionId);
      const clientSessions = serverSessions.map(s => ({
        sessionId: s.sessionId,
        deviceId: s.deviceId,
        expiresAt: s.expiresAt || new Date().toISOString(),
        lastActive: s.lastActive || new Date().toISOString(),
        userId: s.userId || fullUser.id
      }));
      setSessions(clientSessions);
      // Apply server language if present
      if (fullUser?.language) {
        try {
          await storage.setItem(keys.language, fullUser.language);
          setCurrentLanguage(fullUser.language);
        } catch (e) {
          console.warn('Failed to apply server language on MFA login', e);
        }
      }
      if (onAuthStateChange) onAuthStateChange(fullUser);
      return fullUser;
    } catch (error) {
      loginFailure(error.message || 'MFA verification failed');
      throw error;
    } finally {
      useAuthStore.setState({
        isLoading: false
      });
    }
  }, [storage, oxyServices, loginSuccess, loginFailure, saveActiveSessionId, onAuthStateChange]);

  // Switch session method
  const switchSession = useCallback(async sessionId => {
    await switchToSession(sessionId);
  }, [switchToSession]);

  // Remove session method
  const removeSession = useCallback(async sessionId => {
    await logout(sessionId);
  }, [logout]);

  // Refresh sessions method
  const refreshSessions = useCallback(async () => {
    console.log('refreshSessions called with activeSessionId:', activeSessionId);
    if (!activeSessionId) {
      console.log('refreshSessions: No activeSessionId, returning');
      return;
    }
    try {
      console.log('refreshSessions: Calling getSessionsBySessionId...');
      const serverSessions = await oxyServices.getSessionsBySessionId(activeSessionId);
      console.log('refreshSessions: Server sessions received:', serverSessions);

      // Update local sessions with server data
      const updatedSessions = serverSessions.map(serverSession => ({
        sessionId: serverSession.sessionId,
        deviceId: serverSession.deviceId,
        expiresAt: serverSession.expiresAt || new Date().toISOString(),
        lastActive: serverSession.lastActive || new Date().toISOString(),
        userId: serverSession.userId || user?.id
      }));
      console.log('refreshSessions: Updated sessions:', updatedSessions);
      setSessions(updatedSessions);
      console.log('refreshSessions: Sessions updated in state');
    } catch (error) {
      console.error('Refresh sessions error:', error);

      // If the current session is invalid, try to find another valid session
      if (sessions.length > 1) {
        console.log('Current session invalid, trying to switch to another session...');
        const otherSessions = sessions.filter(s => s.sessionId !== activeSessionId);
        for (const session of otherSessions) {
          try {
            // Try to validate this session
            await oxyServices.validateSession(session.sessionId, {
              useHeaderValidation: true
            });
            console.log('Found valid session, switching to:', session.sessionId);
            await switchToSession(session.sessionId);
            return; // Successfully switched to another session
          } catch (sessionError) {
            console.log('Session validation failed for:', session.sessionId, sessionError);
            continue; // Try next session
          }
        }
      }

      // If no valid sessions found, clear all sessions
      console.log('No valid sessions found, clearing all sessions');
      setSessions([]);
      setActiveSessionId(null);
      logoutStore();
      setMinimalUser(null);
      await clearAllStorage();
      if (onAuthStateChange) {
        onAuthStateChange(null);
      }
    }
  }, [activeSessionId, oxyServices, user?.id, sessions, switchToSession, logoutStore, setMinimalUser, clearAllStorage, onAuthStateChange]);

  // Device management methods
  const getDeviceSessions = useCallback(async () => {
    if (!activeSessionId) throw new Error('No active session');
    try {
      return await oxyServices.getDeviceSessions(activeSessionId);
    } catch (error) {
      console.error('Get device sessions error:', error);
      throw error;
    }
  }, [activeSessionId, oxyServices]);
  const logoutAllDeviceSessions = useCallback(async () => {
    if (!activeSessionId) throw new Error('No active session');
    try {
      await oxyServices.logoutAllDeviceSessions(activeSessionId);

      // Clear all local sessions since we logged out from all devices
      setSessions([]);
      setActiveSessionId(null);
      logoutStore();
      setMinimalUser(null);
      await clearAllStorage();
      if (onAuthStateChange) {
        onAuthStateChange(null);
      }
    } catch (error) {
      console.error('Logout all device sessions error:', error);
      throw error;
    }
  }, [activeSessionId, oxyServices, logoutStore, setMinimalUser, clearAllStorage, onAuthStateChange]);
  const updateDeviceName = useCallback(async deviceName => {
    if (!activeSessionId) throw new Error('No active session');
    try {
      await oxyServices.updateDeviceName(activeSessionId, deviceName);

      // Update local device info
      await DeviceManager.updateDeviceName(deviceName);
    } catch (error) {
      console.error('Update device name error:', error);
      throw error;
    }
  }, [activeSessionId, oxyServices]);

  // Language management method
  const setLanguage = useCallback(async languageId => {
    if (!storage) throw new Error('Storage not initialized');
    try {
      // Save language preference
      await storage.setItem(keys.language, languageId);
      setCurrentLanguage(languageId);
      console.log(`Language changed to ${languageId}`);

      // TODO: Here you can add any additional logic needed for app-wide language updates
      // such as updating i18n configuration, refreshing translations, etc.
    } catch (error) {
      console.error('Error saving language preference:', error);
      throw error;
    }
  }, [storage, keys.language]);

  // Bottom sheet control methods
  const showBottomSheet = useCallback(screenOrConfig => {
    if (__DEV__) console.log('showBottomSheet called with:', screenOrConfig);
    if (bottomSheetRef?.current) {
      if (__DEV__) console.log('bottomSheetRef is available');

      // First, show the bottom sheet
      if (bottomSheetRef.current.expand) {
        if (__DEV__) console.log('Expanding bottom sheet');
        bottomSheetRef.current.expand();
      } else if (bottomSheetRef.current.present) {
        if (__DEV__) console.log('Presenting bottom sheet');
        bottomSheetRef.current.present();
      } else {
        console.warn('No expand or present method available on bottomSheetRef');
        if (__DEV__) console.log('Available methods on bottomSheetRef.current:', Object.keys(bottomSheetRef.current));
      }

      // Then navigate to the specified screen if provided
      if (screenOrConfig) {
        // Add a small delay to ensure the bottom sheet is opened first
        setTimeout(() => {
          if (typeof screenOrConfig === 'string') {
            // Simple screen name
            if (__DEV__) console.log('Navigating to screen:', screenOrConfig);
            bottomSheetRef.current?.navigate?.(screenOrConfig);
          } else {
            // Screen with props
            if (__DEV__) console.log('Navigating to screen with props:', screenOrConfig.screen, screenOrConfig.props);
            bottomSheetRef.current?.navigate?.(screenOrConfig.screen, screenOrConfig.props);
          }
        }, 100);
      }
    } else {
      console.warn('bottomSheetRef is not available');
      console.warn('To fix this, ensure you pass a bottomSheetRef to OxyProvider:');
      console.warn('<OxyProvider baseURL="..." bottomSheetRef={yourBottomSheetRef}>');
    }
  }, [bottomSheetRef]);
  const hideBottomSheet = useCallback(() => {
    if (bottomSheetRef?.current) {
      bottomSheetRef.current.dismiss?.();
    }
  }, [bottomSheetRef]);

  // Integrate socket for real-time session updates
  useSessionSocket({
    userId: user?.id,
    activeSessionId,
    refreshSessions,
    logout,
    baseURL: oxyServices.getBaseURL(),
    onRemoteSignOut: useCallback(() => {
      toast.info('You have been signed out remotely.');
      logout();
    }, [logout])
  });

  // Context value - optimized to prevent unnecessary re-renders
  // Lazy proxy to load the hook only when accessed, breaking the static import cycle.
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
  const useFollowProxy = userId => {
    try {
      // Dynamically require to avoid top-level cycle
      // eslint-disable-next-line @typescript-eslint/no-var-requires
      const mod = require('../hooks/useFollow');
      if (mod && typeof mod.useFollow === 'function') {
        return mod.useFollow(userId);
      }
      console.warn('useFollow module did not export a function as expected');
      return {
        isFollowing: false,
        isLoading: false,
        error: null,
        toggleFollow: async () => {},
        setFollowStatus: () => {},
        fetchStatus: async () => {},
        clearError: () => {},
        followerCount: null,
        followingCount: null,
        isLoadingCounts: false,
        fetchUserCounts: async () => {},
        setFollowerCount: () => {},
        setFollowingCount: () => {}
      };
    } catch (e) {
      console.warn('Failed to dynamically load useFollow hook:', e);
      return {
        isFollowing: false,
        isLoading: false,
        error: null,
        toggleFollow: async () => {},
        setFollowStatus: () => {},
        fetchStatus: async () => {},
        clearError: () => {},
        followerCount: null,
        followingCount: null,
        isLoadingCounts: false,
        fetchUserCounts: async () => {},
        setFollowerCount: () => {},
        setFollowingCount: () => {}
      };
    }
  };
  const contextValue = useMemo(() => ({
    user,
    minimalUser,
    sessions,
    activeSessionId,
    isAuthenticated,
    isLoading,
    error,
    currentLanguage,
    login,
    logout,
    logoutAll,
    signUp,
    completeMfaLogin,
    switchSession,
    removeSession,
    refreshSessions,
    setLanguage,
    getDeviceSessions,
    logoutAllDeviceSessions,
    updateDeviceName,
    oxyServices,
    bottomSheetRef,
    showBottomSheet,
    hideBottomSheet,
    useFollow: useFollowProxy
  }), [user?.id,
  // Only depend on user ID, not the entire user object
  minimalUser?.id, sessions.length,
  // Only depend on sessions count, not the entire array
  activeSessionId, isAuthenticated, isLoading, error, currentLanguage, login, logout, logoutAll, signUp, completeMfaLogin, switchSession, removeSession, refreshSessions, setLanguage, getDeviceSessions, logoutAllDeviceSessions, updateDeviceName, oxyServices, bottomSheetRef, showBottomSheet, hideBottomSheet]);

  // Wrap children rendering to block until token is ready
  if (!tokenReady) {
    return /*#__PURE__*/_jsx(View, {
      style: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
      },
      children: /*#__PURE__*/_jsx(Text, {
        children: "Loading authentication..."
      })
    });
  }
  return /*#__PURE__*/_jsx(OxyContext.Provider, {
    value: contextValue,
    children: children
  });
};

// Alias for backward compatibility
export const OxyContextProvider = OxyProvider;

// Hook to use the context
export const useOxy = () => {
  const context = useContext(OxyContext);
  if (!context) {
    throw new Error('useOxy must be used within an OxyContextProvider');
  }
  return context;
};
export default OxyContext;
//# sourceMappingURL=OxyContext.js.map