import React, { useEffect, useState, useMemo, useCallback, useRef } from "react";
import { Stack } from "expo-router";
import { StatusBar } from "expo-status-bar";
import { PortalHost } from "@rn-primitives/portal";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { ModalToast } from "@/components/ModalToast";
import "@/global.css";
import { SafeAreaProvider } from "react-native-safe-area-context";
import {
  View as RNView,
  ActivityIndicator,
  AppState,
  AppStateStatus,
} from "react-native";
import { NAV_THEME, loadTheme } from "@/lib/theme";
import { SirouRouterProvider, useSirouRouter } from "@sirou/react-native";
import { refreshTokens } from "@/lib/api-middlewares";
import { ThemeProvider, NavigationIndependentTree } from "@react-navigation/native";
import { routes } from "@/lib/routes";
import { authGuard, guestGuard } from "@/lib/auth-guards";
import { useAuthStore } from "@/lib/auth-store";
import { usePinStore } from "@/lib/pin-store";
import { useFonts } from "expo-font";
import { useColorScheme } from "nativewind";
import { useSegments, useLocalSearchParams, useRouter } from "expo-router";

/**
 * GlobalGuard: Handles all routing security and authentication redirects.
 */
function GlobalGuard() {
  const segments = useSegments();
  const params = useLocalSearchParams();
  const router = useRouter();
  const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
  const sirou = useSirouRouter();
  const [isMounted, setIsMounted] = useState(false);

  useEffect(() => {
    setIsMounted(true);
  }, []);

  useEffect(() => {
    if (!isMounted || !segments) return;

    const performGuardCheck = async () => {
      const routeName = segments.length > 0 ? segments.join("/") : "root";
      const isAuthPage =
        segments[0] === "login" ||
        segments[0] === "register" ||
        segments[0] === "otp";

      if (!isAuthenticated && !isAuthPage) {
        console.log(`[GlobalGuard] Unauthorized on "${routeName}". Ejecting...`);
        router.replace("/login");
        return;
      }

      if (isAuthenticated && isAuthPage) {
        console.log(`[GlobalGuard] Authenticated user on auth page.`);
        const { hasPin } = usePinStore.getState();
        router.replace(hasPin ? "/" : "/set-pin");
        return;
      }

      try {
        const result = await (sirou as any).checkGuards(routeName, params);
        if (!result.allowed && result.redirect) {
          console.log(`[GlobalGuard] Sirou Guard Redirect -> ${result.redirect}`);
          router.replace(result.redirect as any);
        }
      } catch (e: any) {
        console.warn(`[GlobalGuard] guard crash:`, e.message);
      }
    };

    performGuardCheck();
  }, [segments, params, sirou, isMounted, isAuthenticated]);

  return null;
}

/**
 * PinGuard: Only locks on cold start (app killed & reopened).
 * No session timeout, no inactivity lock, no background checks.
 * Also redirects to set-pin if user is authenticated but has no PIN.
 */
function PinGuard() {
  const segments = useSegments();
  const router = useRouter();
  const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
  const initialCheckDone = useRef(false);

  useEffect(() => {
    if (!isAuthenticated || segments.length === 0) return;

    const pinRoutes = ["pin-lock", "set-pin", "forgot-pin", "forgot-pin-verify"];

    const checkPinRedirect = () => {
      const { hasPin: hp, isLocked } = usePinStore.getState();
      const route = segments[0];

      if (!hp && !pinRoutes.includes(route)) {
        router.replace("/set-pin");
        return;
      }

      if (hp && isLocked() && !pinRoutes.includes(route)) {
        router.replace("/pin-lock");
      }
    };

    // Cold start only — defer to next tick so Stack navigator is fully mounted
    if (!initialCheckDone.current) {
      initialCheckDone.current = true;
      setTimeout(() => checkPinRedirect(), 0);
    }
  }, [segments, isAuthenticated]);

  return null;
}

/**
 * SessionHeartbeat: Proactively refreshes tokens.
 */
function SessionHeartbeat() {
  const isAuthenticated = useAuthStore((s) => s.isAuthenticated);

  useEffect(() => {
    if (!isAuthenticated) return;

    const INTERVAL_MS = 5 * 60 * 1000;
    const performRefresh = async (reason: string) => {
      try {
        console.log(`[SessionHeartbeat] Refresh triggered by: ${reason}`);
        await refreshTokens();
      } catch (err) {
        console.warn(`[SessionHeartbeat] Refresh failed (${reason}):`, err);
      }
    };

    performRefresh("Mount");
    const interval = setInterval(() => performRefresh("Interval"), INTERVAL_MS);

    const subscription = AppState.addEventListener("change", (nextAppState) => {
      if (nextAppState === "active") {
        performRefresh("Foreground");
      }
    });

    return () => {
      clearInterval(interval);
      subscription.remove();
    };
  }, [isAuthenticated]);

  return null;
}

export default function RootLayout() {
  const { colorScheme, setColorScheme } = useColorScheme();
  const [isMounted, setIsMounted] = useState(false);
  const [authHydrated, setAuthHydrated] = useState(false);
  const [pinHydrated, setPinHydrated] = useState(false);
  const [isThemeRestored, setIsThemeRestored] = useState(false);
  
  const [fontsLoaded] = useFonts({
    "DMSans-Regular": require("../assets/fonts/DMSans-Regular.ttf"),
    "DMSans-Bold": require("../assets/fonts/DMSans-Bold.ttf"),
    "DMSans-Medium": require("../assets/fonts/DMSans-Medium.ttf"),
    "DMSans-SemiBold": require("../assets/fonts/DMSans-SemiBold.ttf"),
    "DMSans-Light": require("../assets/fonts/DMSans-Light.ttf"),
    "DMSans-ExtraLight": require("../assets/fonts/DMSans-ExtraLight.ttf"),
    "DMSans-Thin": require("../assets/fonts/DMSans-Thin.ttf"),
    "DMSans-Black": require("../assets/fonts/DMSans-Black.ttf"),
    "DMSans-ExtraBold": require("../assets/fonts/DMSans-ExtraBold.ttf"),
  });

  useEffect(() => {
    setIsMounted(true);
    
    // Auth Hydration
    const initializeAuth = () => {
      if (useAuthStore.persist.hasHydrated()) {
        setAuthHydrated(true);
      } else {
        useAuthStore.persist.onFinishHydration(() => setAuthHydrated(true));
      }
    };
    
    // Pin Hydration
    const initializePin = () => {
      if (usePinStore.persist.hasHydrated()) {
        setPinHydrated(true);
      } else {
        usePinStore.persist.onFinishHydration(() => setPinHydrated(true));
      }
    };
    
    // Theme Restoration
    const initializeTheme = async () => {
      try {
        const savedTheme = await loadTheme();
        if (savedTheme && savedTheme !== "system") {
          setColorScheme(savedTheme);
        }
      } catch (e) {
        console.warn("[RootLayout] Theme restore failed:", e);
      } finally {
        setIsThemeRestored(true);
      }
    };

    initializeAuth();
    initializePin();
    initializeTheme();
  }, []);

  const theme = useMemo(() => {
    const isDark = colorScheme === "dark";
    return isDark ? NAV_THEME.dark : NAV_THEME.light;
  }, [colorScheme]);

  if (!isMounted || !authHydrated || !pinHydrated || !fontsLoaded || !isThemeRestored) {
    return (
      <RNView
        style={{
          flex: 1,
          alignItems: "center",
          justifyContent: "center",
          backgroundColor: "#ffffff",
        }}
      >
        <ActivityIndicator size="large" color="#ea580c" />
      </RNView>
    );
  }

  return (
    <NavigationIndependentTree>
      <ThemeProvider value={theme}>
        <GestureHandlerRootView style={{ flex: 1 }}>
          <SafeAreaProvider>
            <SirouRouterProvider config={routes} guards={[authGuard, guestGuard]}>
              <RNView style={{ flex: 1, backgroundColor: theme.colors.background }}>
                <StatusBar style={colorScheme === "dark" ? "light" : "dark"} />
                <GlobalGuard />
                <Stack
                  screenOptions={{
                    headerShown: false,
                  }}
                >
                  <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
                  <Stack.Screen name="sms-scan" options={{ headerShown: false }} />
                  <Stack.Screen name="proforma" options={{ title: "Proforma", headerShown: false }} />
                  <Stack.Screen name="proforma/[id]" options={{ title: "Proforma request" }} />
                  <Stack.Screen name="proforma/edit" options={{ title: "Edit Proforma" }} />
                  <Stack.Screen name="invoices/[id]" options={{ title: "Invoice" }} />
                  <Stack.Screen name="invoices/create" options={{ title: "Add Invoice", headerShown: false }} />
                  <Stack.Screen name="invoices/edit" options={{ title: "Edit Invoice" }} />
                  <Stack.Screen name="payments/[id]" options={{ title: "Payment" }} />
                  <Stack.Screen name="payment-requests/[id]" options={{ title: "Payment Request" }} />
                  <Stack.Screen name="notifications/index" options={{ title: "Notifications" }} />
                  <Stack.Screen name="notifications/settings" options={{ title: "Notification settings" }} />
                  <Stack.Screen name="help" options={{ headerShown: false }} />
                  <Stack.Screen name="faq" options={{ headerShown: false }} />
                  <Stack.Screen name="terms" options={{ headerShown: false }} />
                  <Stack.Screen name="privacy" options={{ headerShown: false }} />
                  <Stack.Screen name="history" options={{ headerShown: false }} />
                  <Stack.Screen name="company" options={{ headerShown: false }} />
                  <Stack.Screen name="company-details" options={{ headerShown: false }} />
                  <Stack.Screen name="company/edit" options={{ title: "Edit Company", headerShown: false }} />
                  <Stack.Screen name="login" options={{ title: "Sign in", headerShown: false }} />
                  <Stack.Screen name="otp" options={{ title: "Verify OTP", headerShown: false }} />
                  <Stack.Screen name="register" options={{ title: "Create account", headerShown: false }} />
                  <Stack.Screen name="reports/index" options={{ title: "Reports" }} />
                  <Stack.Screen name="documents/index" options={{ title: "Documents" }} />
                  <Stack.Screen name="settings" options={{ title: "Settings" }} />
                  <Stack.Screen name="profile" options={{ headerShown: false }} />
                  <Stack.Screen name="edit-profile" options={{ headerShown: false }} />
                  <Stack.Screen name="user/create" options={{ headerShown: false }} />
                  <Stack.Screen name="verify-payment" options={{ title: "Verify Payment", headerShown: false }} />
                  <Stack.Screen name="verify-payment-result" options={{ title: "Verification Result", headerShown: false }} />
                  <Stack.Screen name="set-pin" options={{ title: "Set PIN", headerShown: false }} />
                  <Stack.Screen name="pin-lock" options={{ headerShown: false }} />
                  <Stack.Screen name="forgot-pin" options={{ title: "Forgot PIN", headerShown: false }} />
                  <Stack.Screen name="forgot-pin-verify" options={{ title: "Reset PIN", headerShown: false }} />
                  <Stack.Screen name="customers/create" options={{ title: "Add Customer", headerShown: false }} />
                  <Stack.Screen name="customers/[id]" options={{ title: "Customer" }} />
                </Stack>
                <SessionHeartbeat />
                <PinGuard />
                <PortalHost />
                <ModalToast />
              </RNView>
            </SirouRouterProvider>
          </SafeAreaProvider>
        </GestureHandlerRootView>
      </ThemeProvider>
    </NavigationIndependentTree>
  );
}
