import { Stack } from "expo-router";
import {
  Inter_400Regular,
  Inter_500Medium,
  Inter_600SemiBold,
  Inter_700Bold,
} from "@expo-google-fonts/inter";
import {
  PlayfairDisplay_600SemiBold,
  PlayfairDisplay_700Bold,
} from "@expo-google-fonts/playfair-display";
import { useFonts } from "expo-font";
import * as SplashScreen from "expo-splash-screen";
import { useEffect, type ReactNode } from "react";
import { Platform, View } from "react-native";
import { StatusBar } from "expo-status-bar";
import "react-native-reanimated";
import { SafeAreaProvider } from "react-native-safe-area-context";

import { BrandBackground } from "@/components/BrandBackground";
import { LoadingScreen } from "@/components/LoadingScreen";
import { AccountsProvider, useAccounts } from "@/contexts/AccountsContext";
import { AuthProvider, useSession } from "@/contexts/AuthContext";
import { ThemeProvider, useAppTheme } from "@/contexts/ThemeContext";
import { TRPCProvider } from "@/lib/trpc";
import { ensureWidgetBrandAssets } from "@/lib/widget-brand-assets";

export { ErrorBoundary } from "expo-router";

SplashScreen.preventAutoHideAsync();

function AppServices({ children }: { children: ReactNode }) {
  const { apiUrl, authStoragePrefix, activeAccountId } = useAccounts();
  const remountKey = `${activeAccountId ?? "guest"}:${apiUrl}`;

  return (
    <AuthProvider apiUrl={apiUrl} storagePrefix={authStoragePrefix} key={remountKey}>
      <TRPCProvider apiUrl={apiUrl} key={remountKey}>
        {children}
      </TRPCProvider>
    </AuthProvider>
  );
}

function ThemedChrome({ children }: { children: ReactNode }) {
  const { isDark } = useAppTheme();

  return (
    <View style={{ flex: 1, backgroundColor: "transparent" }}>
      <BrandBackground />
      <View style={{ flex: 1, zIndex: 1 }}>
        <StatusBar style={isDark ? "light" : "dark"} />
        {children}
      </View>
    </View>
  );
}

export default function RootLayout() {
  const [loaded, error] = useFonts({
    SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
    Inter_400Regular,
    Inter_500Medium,
    Inter_600SemiBold,
    Inter_700Bold,
    PlayfairDisplay_600SemiBold,
    PlayfairDisplay_700Bold,
  });

  useEffect(() => {
    if (error) throw error;
  }, [error]);

  useEffect(() => {
    if (loaded) {
      SplashScreen.hideAsync();
    }
  }, [loaded]);

  useEffect(() => {
    if (Platform.OS === "ios") {
      void ensureWidgetBrandAssets();
    }
  }, []);

  if (!loaded) {
    return null;
  }

  return (
    <SafeAreaProvider>
      <ThemeProvider>
        <ThemedChrome>
          <AccountsProvider>
            <AppServices>
              <RootNavigator />
            </AppServices>
          </AccountsProvider>
        </ThemedChrome>
      </ThemeProvider>
    </SafeAreaProvider>
  );
}

function RootNavigator() {
  const { data: session, isPending } = useSession();

  if (isPending) {
    return <LoadingScreen message="Checking session…" />;
  }

  const isAuthenticated = Boolean(session?.user);

  return (
    <Stack
      screenOptions={{
        headerShown: false,
        contentStyle: { backgroundColor: "transparent" },
      }}
    >
      <Stack.Protected guard={!isAuthenticated}>
        <Stack.Screen name="(auth)" />
      </Stack.Protected>
      <Stack.Protected guard={isAuthenticated}>
        <Stack.Screen name="(app)" />
      </Stack.Protected>
    </Stack>
  );
}
