import { Toaster } from "@/components/ui/toaster";
import { Toaster as Sonner } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import { toast } from "@/hooks/use-toast";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter, Routes, Route, Navigate, useLocation } from "react-router-dom";
import { LoadedTestProvider } from "@/contexts/LoadedTestContext";
import { AuthProvider } from "@/contexts/AuthContext";
import { GuestProvider } from "@/contexts/GuestContext";
import { ProtectedRoute } from "@/components/ProtectedRoute";
import { AdminRoute } from "@/components/AdminRoute";
import { OnboardingGuard } from "@/components/OnboardingGuard";
import { LevelAccessGuard } from "@/components/LevelAccessGuard";
import { AppFooter as LayoutFooter } from "@/components/layout/AppFooter";
import { MobileBottomNav } from "@/components/layout/MobileBottomNav";
import StreakManager from "@/components/StreakManager";
import { lazy, Suspense, useEffect, useState, useCallback } from "react";
import { useIsMobileDevice } from "@/hooks/useIsMobileDevice";
import SplashScreen from "@/components/SplashScreen";
import { Capacitor } from "@capacitor/core";
import { useAuth } from "./contexts/AuthContext";
import { useGuest } from "./contexts/GuestContext";
import { useScrollToTop } from "@/hooks/useScrollToTop";
// NotificationOnboarding moved to Index.tsx to show only after onboarding completion
import { ErrorBoundary } from "@/components/ErrorBoundary";
import { BannerQueueProvider } from "@/hooks/useBannerQueue";
import { PWAInstallPrompt } from "@/components/PWAInstallPrompt";
import { AppRatingPrompt } from "@/components/AppRatingPrompt";
import { SmartUpgradePrompt } from "@/components/SmartUpgradePrompt";
import { CapacitorProvider } from "@/components/CapacitorProvider";
import GA4PageView from "@/components/GA4PageView";
import MetaPixelTracker from "@/components/MetaPixelTracker";
import { NativePushInitializer } from "@/components/NativePushInitializer";
import "driver.js/dist/driver.css";

// Eager load critical routes for instant navigation
import Index from "./pages/Index";
import Auth from "./pages/Auth";
import AuthConfirm from "./pages/AuthConfirm";
import Learning from "./pages/Learning";
import Profile from "./pages/Profile";
import PrivacyPolicy from "./pages/PrivacyPolicy";
import TermsOfService from "./pages/TermsOfService";
import TestPage from "./pages/TestPage";
import MyPracticeHistory from "./components/MyPracticeHistory";

// Simplified lazy loader with basic retry - no auto-reload to prevent infinite loops
const lazyWithRetry = (componentImport: () => Promise<any>, retries = 3) => {
  return lazy(async () => {
    let lastError;
    for (let i = 0; i < retries; i++) {
      try {
        return await componentImport();
      } catch (error) {
        lastError = error;
        console.warn(`[LazyLoad] Attempt ${i + 1}/${retries} failed:`, error);
        // Wait before retrying (exponential backoff)
        if (i < retries - 1) {
          await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 500));
        }
      }
    }
    console.error('[LazyLoad] All retry attempts failed:', lastError);
    // Don't auto-reload - let the error boundary handle it
    throw lastError;
  });
};

// Lazy load less frequently accessed pages with resilient loading
const TestResults = lazyWithRetry(() => import("./pages/TestResults"));
const DiagnosticTest = lazyWithRetry(() => import("./pages/DiagnosticTest"));
const Onboarding = lazyWithRetry(() => import("./pages/Onboarding"));
const TestCenter = lazyWithRetry(() => import("./pages/TestCenter"));
const Friends = lazyWithRetry(() => import("./pages/Friends"));
const BulkIdiomModuleGenerator = lazyWithRetry(() => import("./pages/BulkIdiomModuleGenerator"));
const DailyChallenge = lazyWithRetry(() => import("./pages/DailyChallenge"));
const Subscription = lazyWithRetry(() => import("./pages/Subscription"));
const BillingHistory = lazyWithRetry(() => import("./pages/BillingHistory"));
const PaymentSuccess = lazyWithRetry(() => import("./pages/PaymentSuccess"));
const PaymentCancel = lazyWithRetry(() => import("./pages/PaymentCancel"));
const Support = lazyWithRetry(() => import("./pages/Support"));
const LogoComparison = lazyWithRetry(() => import("./pages/LogoComparison"));
const NotFound = lazyWithRetry(() => import("./pages/NotFound"));
const AdminNotificationTester = lazyWithRetry(() => import("./pages/AdminNotificationTester"));
const EmailNotificationTester = lazyWithRetry(() => import("./pages/EmailNotificationTester"));
const FcmTestPage = lazyWithRetry(() => import("./pages/FcmTestPage"));
const HelpCenter = lazyWithRetry(() => import("./pages/HelpCenter"));
const GroupChallengeTestEnhanced = lazyWithRetry(() => import("./pages/GroupChallengeTestEnhanced"));
const InstallApp = lazyWithRetry(() => import("./pages/InstallApp"));
const ScreenshotGenerator = lazyWithRetry(() => import("./pages/ScreenshotGenerator"));
const GroupTransferResponse = lazyWithRetry(() => import("./pages/GroupTransferResponse"));
const AdminPushNotifications = lazyWithRetry(() => import("./pages/admin/AdminPushNotifications"));
const ChallengeResultPreview = lazyWithRetry(() => import("./pages/admin/ChallengeResultPreview"));

// Loading fallback component - fills viewport to prevent layout shift
const PageLoader = () => (
  <div className="fixed inset-0 flex items-center justify-center bg-gradient-to-br from-primary/5 via-background to-secondary/5">
    <div className="text-center">
      <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4"></div>
      <p className="text-muted-foreground">Loading...</p>
    </div>
  </div>
);

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5 * 60_000, // 5 minutes for less critical data
      gcTime: 10 * 60_000, // 10 minutes
      refetchOnWindowFocus: false,
      refetchOnMount: false,
      retry: 1,
    },
  },
});

const App = () => {
  const [showSplash, setShowSplash] = useState(() => {
    // Show splash for native apps AND PWA standalone mode
    if (Capacitor.isNativePlatform()) return true;
    // Check PWA standalone mode (Android Chrome / iOS Safari)
    const isStandalone = window.matchMedia('(display-mode: standalone)').matches
      || (navigator as any).standalone === true;
    return isStandalone;
  });

  const handleSplashComplete = useCallback(() => {
    setShowSplash(false);
  }, []);

  return (
    <CapacitorProvider>
      {showSplash && <SplashScreen onComplete={handleSplashComplete} />}
      <QueryClientProvider client={queryClient}>
        <AuthProvider>
          <GuestProvider>
            <LoadedTestProvider>
              <TooltipProvider>
                <Toaster />
                <Sonner />
                <BrowserRouter>
                  <GA4PageView />
                  <MetaPixelTracker />
                  <AppContent />
                </BrowserRouter>
              </TooltipProvider>
            </LoadedTestProvider>
          </GuestProvider>
        </AuthProvider>
      </QueryClientProvider>
    </CapacitorProvider>
  );
};

// Catch-all for /admin/* — redirects typos to canonical paths, else 404
const AdminFallback = () => {
  const { pathname } = useLocation();
  const lower = pathname.toLowerCase().replace(/\/+$/, '');

  // Any variant of /admin/push-notificat... → canonical path
  if (lower.startsWith('/admin/push-notificat')) {
    return <Navigate to="/admin/push-notifications" replace />;
  }

  return <NotFound />;
};

const AppContent = () => {
  const { user, loading, isValidating } = useAuth();
  const { isGuest } = useGuest();
  const location = useLocation();
  const [loadingTimedOut, setLoadingTimedOut] = useState(false);
  const isMobileDevice = useIsMobileDevice();
  
  // Scroll to top on route change
  useScrollToTop();

  // Mobile Bottom Nav visibility (keep in sync with MobileBottomNav)
  const hiddenPaths = [
    "/auth",
    "/onboarding",
    "/diagnostic",
    "/install",
    "/learning",
    "/test",
    "/group",
  ];
  const showMobileBottomNav = !hiddenPaths.some((p) =>
    location.pathname.startsWith(p)
  );
  
  // Only apply mobile nav padding if actually showing the nav (mobile device + allowed path)
  const shouldApplyMobileNavPadding = showMobileBottomNav && isMobileDevice;
  
  useEffect(() => {
    if (loading || isValidating) {
      const timeout = setTimeout(() => {
        setLoadingTimedOut(true);
      }, 3000);
      return () => clearTimeout(timeout);
    } else {
      setLoadingTimedOut(false);
    }
  }, [loading, isValidating]);
  
  // Prefetch likely next routes after auth is ready
  useEffect(() => {
    if (loading || isValidating) return;

    const prefetch = () => {
      import("./pages/Friends");
      import("./pages/DailyChallenge");
      import("./pages/Subscription");
      import("./pages/TestResults");
    };

    const timeoutId = setTimeout(prefetch, 500);
    return () => clearTimeout(timeoutId);
  }, [loading, isValidating]);

  // Log iOS device info for debugging (only once auth loading is done)
  useEffect(() => {
    if (loading || isValidating) return;
    const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
    if (isIOS) {
      console.log('[iOS] Device detected:', {
        userAgent: navigator.userAgent,
        viewport: { width: window.innerWidth, height: window.innerHeight },
        platform: navigator.platform,
      });
    }
  }, [loading, isValidating]);

  // Public routes that should never be blocked by auth loading
  const publicRoutes = ['/support', '/privacy-policy', '/terms-of-service', '/install', '/auth', '/logos'];
  const isPublicRoute = publicRoutes.some(r => location.pathname.startsWith(r));

  // Force-redirect common admin push URL typos before route matching
  const isAdminPushTypoPath = location.pathname.startsWith('/admin/push-notificati')
    && location.pathname !== '/admin/push-notifications';

  const isAdminModerationPath = location.pathname.startsWith('/admin/moderat');

  if (isAdminPushTypoPath) {
    return <Navigate to="/admin/push-notifications" replace />;
  }

  if (isAdminModerationPath) {
    return <Navigate to="/profile?tab=settings&admin=moderation" replace />;
  }

  // Block rendering until session is validated OR timeout occurs (skip for public routes and guests)
  if ((loading || isValidating) && !loadingTimedOut && !isPublicRoute && !isGuest) {
    return (
      <div className="fixed inset-0 flex items-center justify-center bg-gradient-to-br from-primary/5 via-background to-secondary/5 z-50">
        <div className="text-center">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4"></div>
          <p className="text-muted-foreground font-medium">Loading IdiomIgnite...</p>
        </div>
      </div>
    );
  }
  
  return (
    <ErrorBoundary>
    <BannerQueueProvider>
      {/* PWA Install Prompt (web only) */}
      <PWAInstallPrompt />
      
      {/* App Rating Prompt (native only) */}
      <AppRatingPrompt />
      
      {/* Smart upgrade prompt for free users (global) */}
      <SmartUpgradePrompt />
      
      {/* Native Push Notification Initializer */}
      <NativePushInitializer />
      
      {/* Global Streak Manager - runs on all routes after auth (skip for guests) */}
      {user && !isGuest && <StreakManager />}
      
      <Suspense fallback={<PageLoader />}>
        <div
          className={cn(
            // Only apply bottom padding on mobile devices when nav is visible
          shouldApplyMobileNavPadding 
              ? "pb-[calc(env(safe-area-inset-bottom,0px)+70px)]" 
              : "pb-[var(--safe-bottom)]"
          )}
        >
          <Routes>
            {/* Public routes */}
            <Route path="/auth" element={<Auth />} />
            <Route path="/auth/confirm" element={<AuthConfirm />} />
            <Route path="/privacy-policy" element={<PrivacyPolicy />} />
            <Route path="/terms-of-service" element={<TermsOfService />} />
            <Route path="/logos" element={<LogoComparison />} />
            <Route path="/install" element={<InstallApp />} />
            <Route path="/support" element={<Support />} />
            <Route path="/help" element={<ProtectedRoute><OnboardingGuard><HelpCenter /></OnboardingGuard></ProtectedRoute>} />
            
            {/* Onboarding route - protected but no onboarding guard */}
            <Route path="/onboarding" element={<ProtectedRoute><Onboarding /></ProtectedRoute>} />
            <Route path="/diagnostic" element={<ProtectedRoute><DiagnosticTest /></ProtectedRoute>} />
            
            {/* Protected routes - require authentication AND onboarding completion */}
            <Route path="/" element={<ProtectedRoute><OnboardingGuard><Index /></OnboardingGuard></ProtectedRoute>} />
            {/* Redirect /learning to home page */}
            <Route path="/learning" element={<Navigate to="/" replace />} />
            <Route path="/learning/:level" element={<ProtectedRoute><OnboardingGuard><LevelAccessGuard><Learning /></LevelAccessGuard></OnboardingGuard></ProtectedRoute>} />
            <Route path="/test/:level" element={<ProtectedRoute><OnboardingGuard><LevelAccessGuard><TestPage /></LevelAccessGuard></OnboardingGuard></ProtectedRoute>} />
            <Route path="/test/:level/:module" element={<ProtectedRoute><OnboardingGuard><LevelAccessGuard><TestPage /></LevelAccessGuard></OnboardingGuard></ProtectedRoute>} />
            <Route path="/test-results" element={<ProtectedRoute><OnboardingGuard><TestResults /></OnboardingGuard></ProtectedRoute>} />
            <Route path="/subscription" element={<ProtectedRoute><Subscription /></ProtectedRoute>} />
            <Route path="/billing-history" element={<ProtectedRoute><BillingHistory /></ProtectedRoute>} />
            {/* Payment routes - no onboarding guard to allow immediate access after payment */}
            <Route path="/payment-success" element={<ProtectedRoute><PaymentSuccess /></ProtectedRoute>} />
            <Route path="/payment-cancel" element={<ProtectedRoute><PaymentCancel /></ProtectedRoute>} />
            <Route path="/daily-challenge" element={<ProtectedRoute><OnboardingGuard><DailyChallenge /></OnboardingGuard></ProtectedRoute>} />
            <Route path="/friends" element={<ProtectedRoute><OnboardingGuard><Friends /></OnboardingGuard></ProtectedRoute>} />
            <Route path="/my-practice-history" element={<ProtectedRoute><OnboardingGuard><MyPracticeHistory /></OnboardingGuard></ProtectedRoute>} />
            <Route path="/group/:groupId/challenge/:challengeId" element={<ProtectedRoute><OnboardingGuard><GroupChallengeTestEnhanced /></OnboardingGuard></ProtectedRoute>} />
            <Route path="/profile" element={<ProtectedRoute><OnboardingGuard><Profile /></OnboardingGuard></ProtectedRoute>} />
            
            {/* Admin-only routes */}
            <Route path="/test-center" element={<AdminRoute><TestCenter /></AdminRoute>} />
            <Route path="/test" element={<AdminRoute><TestPage /></AdminRoute>} />
            <Route path="/bulk-generator" element={<AdminRoute><BulkIdiomModuleGenerator /></AdminRoute>} />
            <Route path="/admin/notifications" element={<AdminRoute><AdminNotificationTester /></AdminRoute>} />
            <Route path="/admin/email-tester" element={<AdminRoute><EmailNotificationTester /></AdminRoute>} />
            <Route path="/admin/fcm-test" element={<ProtectedRoute><FcmTestPage /></ProtectedRoute>} />
            <Route path="/admin/screenshots" element={<AdminRoute><ScreenshotGenerator /></AdminRoute>} />
            <Route path="/admin/push-notifications" element={<AdminRoute><AdminPushNotifications /></AdminRoute>} />
            <Route path="/admin/moderation" element={<AdminRoute><Navigate to="/profile?tab=settings&admin=moderation" replace /></AdminRoute>} />
            <Route path="/admin/challenge-preview" element={<AdminRoute><ChallengeResultPreview /></AdminRoute>} />

            {/* Admin catch-all — handles typos like /admin/push-notificatic */}
            <Route path="/admin/*" element={<AdminFallback />} />
            
            {/* Group ownership transfer response page */}
            <Route path="/group-transfer/:token" element={<ProtectedRoute><GroupTransferResponse /></ProtectedRoute>} />
            
            <Route path="*" element={<NotFound />} />
          </Routes>
        </div>
      </Suspense>
      
      {/* Mobile Bottom Navigation */}
      <MobileBottomNav />
      
      {/* Global Footer - hidden on mobile/tablet when bottom nav is visible */}
      <div className="hidden lg:block">
        <LayoutFooter />
      </div>
    </BannerQueueProvider>
    </ErrorBoundary>
  );
};


export default App;
