import { useEffect } from 'react';
import { AppState, I18nManager } from 'react-native';

I18nManager.allowRTL(true);
import { Stack, router } from 'expo-router';

import { StatusBar } from 'expo-status-bar';
import * as Notifications from 'expo-notifications';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { KeyboardProvider } from 'react-native-keyboard-controller';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { ActionSheetProvider } from '@expo/react-native-action-sheet';
import * as SplashScreen from 'expo-splash-screen';
import {
  useFonts,
  Nunito_400Regular,
  Nunito_600SemiBold,
  Nunito_700Bold,
  Nunito_800ExtraBold,
} from '@expo-google-fonts/nunito';
import { supabase } from '../lib/supabase';
import { useAuthStore } from '../stores/auth';
import { useThemeStore } from '../stores/theme';
import { useRealtimeDebugStore } from '../stores/realtimeDebug';
import { useColors } from '../lib/theme';
import { useLanguageStore } from '../stores/language';
import { useAppLockStore } from '../stores/appLock';
import { useLyraVoiceStore } from '../stores/lyraVoice';
import { AppLockGate } from '../components/AppLockGate';
import { DeviceLimitReachedSheet } from '../components/DeviceLimitReachedSheet';
import { DeviceApprovalIncomingSheet } from '../components/DeviceApprovalIncomingSheet';
import { DeviceApprovalPendingSheet } from '../components/DeviceApprovalPendingSheet';
import { useDeviceApprovalRealtime } from '../hooks/useDeviceApprovalRealtime';
import { useDevicesStore } from '../stores/devices';
import { OnlinePresenceProvider } from '../components/OnlinePresenceProvider';
import { usePushTokenRegistration } from '../hooks/usePushTokenRegistration';
import { useIncomingCalls } from '../hooks/useIncomingCalls';
import { useCallStore } from '../stores/call';
import { useCallKeepEvents } from '../hooks/useCallKeepEvents';
import '../lib/i18n'; // i18next-Init via Side-Effect
import '../global.css';

SplashScreen.preventAutoHideAsync();

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowBanner: true,
    shouldShowList: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      retry: 2,
      staleTime: 1000 * 60,
    },
  },
});

function RootLayoutInner() {
  const { loading, init, user } = useAuthStore();
  const initTheme = useThemeStore((s) => s.init);
  const colorScheme = useThemeStore((s) => s.colorScheme);
  const initLanguage = useLanguageStore((s) => s.init);
  const initAppLock = useAppLockStore((s) => s.init);
  const initLyraVoice = useLyraVoiceStore((s) => s.init);
  const appLockReady = useAppLockStore((s) => s.ready);
  const initRealtimeDebug = useRealtimeDebugStore((s) => s.init);
  const colors = useColors();
  const [fontsLoaded] = useFonts({
    Nunito_400Regular,
    Nunito_600SemiBold,
    Nunito_700Bold,
    Nunito_800ExtraBold,
  });

  // Push-Token-Registration nach Login (idempotent)
  usePushTokenRegistration(user?.id);

  // Eingehende Voice-Calls (Ring-Channel) — zeigt den Call-Screen wenn jemand
  // anruft. Foreground-only (Phase 1).
  useIncomingCalls(user?.id);

  // CallKit/ConnectionService Event-Bridge — mappt native UI-Actions
  // (Accept/Decline/Hangup im Lockscreen-CallKit-UI) auf useCallStore.
  useCallKeepEvents();

  // Apple-Style Device-Approval Realtime — lauscht auf neue Approval-Requests
  // für diesen User und zeigt das Incoming-Sheet wenn ein anderes Gerät
  // sich anmelden möchte.
  useDeviceApprovalRealtime(!!user?.id);

  // Push-Tap-Deep-Link: User tippt Notification → navigate zu Chat / Call
  useEffect(() => {
    const handle = (response: Notifications.NotificationResponse | null | undefined) => {
      if (!response) return;
      const data = response.notification.request.content.data as
        | {
            type?: 'dm' | 'room' | 'call';
            targetId?: string;
            callId?: string;
            from?: { id: string; nickname: string; avatar: string | null };
          }
        | undefined;
      if (!data?.type) return;
      if (data.type === 'dm' && data.targetId) {
        router.push({ pathname: '/dm', params: { userId: data.targetId } });
      } else if (data.type === 'room' && data.targetId) {
        router.push({ pathname: '/room', params: { roomId: data.targetId } });
      } else if (data.type === 'call' && data.callId && data.from) {
        // Eingehender Anruf — Realtime hat (vermutlich) keine Subscription
        // gehabt weil App im Background war. Wir simulieren receiveIncoming
        // damit der Standard-Accept/Decline-Flow greift. Falls der Caller in
        // der Zwischenzeit aufgelegt hat: ring-cancel kommt sobald Channel
        // subscribed, dann teardown.
        try {
          useCallStore.getState().receiveIncoming(data.callId, data.from);
          router.push('/call');
        } catch {
          // ignore — Call evtl. schon beendet
        }
      }
    };
    const sub = Notifications.addNotificationResponseReceivedListener(handle);
    // Cold-Start: App wurde durch Notification-Tap geöffnet
    Notifications.getLastNotificationResponseAsync().then(handle).catch(() => {});
    return () => sub.remove();
  }, []);

  useEffect(() => {
    init();
    initTheme();
    initLanguage();
    initAppLock();
    initLyraVoice();
    if (__DEV__) initRealtimeDebug();
  }, []);

  // Supabase-Doku-Pattern für RN: Token-Auto-Refresh nur wenn App aktiv ist.
  // Plus Foreground-Reconnect via onAuthStateChange (TOKEN_REFRESHED →
  // realtime.setAuth wird intern getriggert). Fixt den Realtime-Disconnect-Bug
  // bei lange eingeloggten Usern (siehe `project_session_2026-05-15_push.md`).
  useEffect(() => {
    const sub = AppState.addEventListener('change', (state) => {
      if (state === 'active') {
        supabase.auth.startAutoRefresh();
      } else {
        supabase.auth.stopAutoRefresh();
      }
    });
    return () => sub.remove();
  }, []);

  useEffect(() => {
    if (fontsLoaded && !loading && appLockReady) {
      SplashScreen.hideAsync();
    }
  }, [fontsLoaded, loading, appLockReady]);

  if (!fontsLoaded || loading || !appLockReady) {
    // Nativer expo-splash-screen bleibt sichtbar bis SplashScreen.hideAsync()
    // im Effect oben aufgerufen wird → kein Flicker durch zusätzlichen
    // React-Splash mehr (User-Feedback: "geht sehr schnell vorbei und zuckt")
    return null;
  }

  return (
    <OnlinePresenceProvider>
    <AppLockGate>
      <StatusBar style={colorScheme === 'dark' ? 'light' : 'dark'} />
      <DeviceLimitReachedSheet />
      <DeviceApprovalIncomingSheet />
      <DeviceApprovalPendingSheet
        onApproved={() => {
          // Slot wurde freigegeben — register retry
          useDevicesStore.getState().ensureRegistered().catch(() => {});
        }}
      />
      <Stack
        screenOptions={{
          headerShown: false,
          animation: 'slide_from_right',
          contentStyle: { backgroundColor: colors.bg },
        }}
      >
        <Stack.Screen name="index" />
        <Stack.Screen name="(auth)" />
        <Stack.Screen name="(app)" />
        <Stack.Screen
          name="lyra"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="urge"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_bottom',
          }}
        />
        <Stack.Screen
          name="call"
          options={{
            headerShown: false,
            presentation: 'fullScreenModal',
            animation: 'slide_from_bottom',
            gestureEnabled: false, // kein versehentliches Swipe-Dismiss im Call
          }}
        />
        <Stack.Screen
          name="dm"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="settings"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="profile/index"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="profile/[userId]"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="games"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="debug"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="help"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="magic"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'slide_from_right',
          }}
        />
        <Stack.Screen
          name="onboarding/index"
          options={{
            headerShown: false,
            presentation: 'card',
            animation: 'fade',
            gestureEnabled: false,
          }}
        />
      </Stack>
    </AppLockGate>
    </OnlinePresenceProvider>
  );
}

export default function RootLayout() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <KeyboardProvider>
        <QueryClientProvider client={queryClient}>
          <ActionSheetProvider>
            <SafeAreaProvider>
              <RootLayoutInner />
            </SafeAreaProvider>
          </ActionSheetProvider>
        </QueryClientProvider>
      </KeyboardProvider>
    </GestureHandlerRootView>
  );
}
