import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
import { Stack, router, useRootNavigationState, useSegments } from 'expo-router';
import * as SplashScreen from 'expo-splash-screen';
import { StatusBar } from 'expo-status-bar';
import { useEffect, useRef } from 'react';
import 'react-native-reanimated';
import { StripeProvider } from '@stripe/stripe-react-native';

import { LoadingSpinner } from '@/components/ui/LoadingSpinner';
import { ToastProvider } from '@/components/ui/Toast';
import { AuthProvider, useAuth } from '@/contexts/AuthContext';
import { BeneficiaryProvider } from '@/contexts/BeneficiaryContext';
import { BLEProvider, useBLE } from '@/contexts/BLEContext';
import { useColorScheme } from '@/hooks/use-color-scheme';
import { setOnLogoutBLECleanupCallback } from '@/services/api';
import { performanceService, PERFORMANCE_THRESHOLDS } from '@/services/performance';

// Mark app startup as early as possible
performanceService.markAppStart();

// Stripe publishable key (test mode) - must match backend STRIPE_PUBLISHABLE_KEY
const STRIPE_PUBLISHABLE_KEY = 'pk_test_51P3kdqP0gvUw6M9C7ixPQHqbPcvga4G5kAYx1h6QXQAt1psbrC2rrmOojW0fTeQzaxD1Q9RKS3zZ23MCvjjZpWLi00eCFWRHMk';

// Prevent auto-hide, ignore errors if splash not available
SplashScreen.preventAutoHideAsync().catch(() => {});

// Track if splash screen was hidden to prevent double-hiding
let splashHidden = false;

function RootLayoutNav() {
  const colorScheme = useColorScheme();
  const { isAuthenticated, isInitializing, user } = useAuth();
  const { cleanupBLE } = useBLE();
  const segments = useSegments();
  const navigationState = useRootNavigationState();

  // Track if initial redirect was done
  const hasInitialRedirect = useRef(false);

  // Set up BLE cleanup callback for logout
  // Use ref to ensure callback is always current and stable
  const cleanupBLERef = useRef(cleanupBLE);
  useEffect(() => {
    cleanupBLERef.current = cleanupBLE;
  }, [cleanupBLE]);

  useEffect(() => {
    // Set callback that calls the current ref (always up-to-date)
    setOnLogoutBLECleanupCallback(() => cleanupBLERef.current());

    // Cleanup: remove callback on unmount
    return () => {
      setOnLogoutBLECleanupCallback(null);
    };
  }, []); // Empty deps - set once, callback uses ref

  useEffect(() => {
    // Wait for navigation to be ready
    if (!navigationState?.key) {
      return;
    }

    // Wait for INITIAL auth check to complete
    if (isInitializing) {
      return;
    }

    // Hide splash screen safely (only once)
    if (!splashHidden) {
      splashHidden = true;
      SplashScreen.hideAsync().catch(() => {});

      // Track app startup performance
      const startupDuration = performanceService.markAppReady();
      if (__DEV__) {
        const status = startupDuration <= PERFORMANCE_THRESHOLDS.appStartup ? '✓' : '✗';
        console.log(`[Performance] App startup: ${startupDuration}ms ${status} (target: ${PERFORMANCE_THRESHOLDS.appStartup}ms)`);
      }
    }

    const inAuthGroup = segments[0] === '(auth)';
    const inTabsGroup = segments[0] === '(tabs)';

    // INITIAL REDIRECT (only once after app starts):
    if (!hasInitialRedirect.current) {
      hasInitialRedirect.current = true;

      // Not authenticated → redirect to login
      if (!isAuthenticated && !inAuthGroup) {
        router.replace('/(auth)/login');
        return;
      }

      // Authenticated but in auth group → this means user just logged in
      // Let the auth screens handle navigation via NavigationController
      // They will call navigateAfterLogin() to determine the correct route
      if (isAuthenticated && inAuthGroup) {
        // Don't redirect - let auth screens finish their flow
        return;
      }

      // Authenticated and in tabs group → user opened app while logged in
      // Check if user should be in onboarding flow
      if (isAuthenticated && inTabsGroup && user) {
        // If user has no name, redirect to complete profile
        if (!user.firstName) {
          router.replace('/(auth)/enter-name');
          return;
        }
        // Otherwise, stay on current tab - user is properly authenticated
      }
    }

    // ONGOING PROTECTION:
    // If user logs out, redirect to login
    if (!isAuthenticated && inTabsGroup) {
      router.replace('/(auth)/login');
      return;
    }

  }, [isAuthenticated, isInitializing, navigationState?.key, user]);
  // IMPORTANT: segments not in deps - we don't want to react to navigation changes

  if (isInitializing) {
    return <LoadingSpinner fullScreen message="Loading..." />;
  }

  return (
    <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
      <Stack screenOptions={{ headerShown: false }}>
        <Stack.Screen name="(auth)" />
        <Stack.Screen name="(tabs)" />
        <Stack.Screen name="modal" options={{ presentation: 'modal', title: 'Modal' }} />
      </Stack>
      <StatusBar style="auto" />
    </ThemeProvider>
  );
}

export default function RootLayout() {
  return (
    <StripeProvider
      publishableKey={STRIPE_PUBLISHABLE_KEY}
      merchantIdentifier="merchant.com.wellnuo.app"
    >
      <AuthProvider>
        <BeneficiaryProvider>
          <BLEProvider>
            <ToastProvider>
              <RootLayoutNav />
            </ToastProvider>
          </BLEProvider>
        </BeneficiaryProvider>
      </AuthProvider>
    </StripeProvider>
  );
}
