import { Toaster } from "@/components/ui/toaster";
import { Toaster as Sonner } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
import { lazy, Suspense, useEffect, useRef, useState } from "react";
import { AuthProvider, useAuth } from "@/context/AuthContext";
import { AppTypeProvider } from "@/context/AppTypeContext";
import { UserRoleProvider } from "@/context/UserRoleContext";
import { CartProvider } from "@/context/CartContext";
import { PreOrderProvider } from "@/context/PreOrderContext";
import AppRouter from "@/components/AppRouter";
import Login from "./pages/Login";

// Lazy-load admin code so it's never bundled with the customer app
const AdminApp = lazy(() => import("@/components/AdminApp"));
import NotFound from "./pages/NotFound";
import { CookieBanner } from "@/components/privacy/CookieBanner";
import { SecurityHeaders } from "@/components/SecurityHeaders";
import LoadingOptimizer from "@/components/LoadingOptimizer";
import FaviconManager from "@/components/FaviconManager";
import MetaTagManager from "@/components/MetaTagManager";
import AuthLoadingSkeleton from "@/components/AuthLoadingSkeleton";

const queryClient = new QueryClient();

// Gate all routes on AuthContext readiness so guests and signed-in users
// see the same skeleton until auth state is resolved.
const AuthGate = ({ children }: { children: React.ReactNode }) => {
  const { loading } = useAuth();
  const mainRef = useRef<HTMLDivElement>(null);
  const wasLoadingRef = useRef(loading);
  const [announcement, setAnnouncement] = useState<string>(
    loading ? "Loading application, please wait." : ""
  );

  useEffect(() => {
    if (wasLoadingRef.current && !loading) {
      // Auth just finished — announce and move focus to main content.
      setAnnouncement("Application ready.");
      // Defer focus until after content paints.
      requestAnimationFrame(() => {
        mainRef.current?.focus();
      });
      // Clear announcement so subsequent re-renders don't re-announce.
      const t = setTimeout(() => setAnnouncement(""), 1000);
      wasLoadingRef.current = false;
      return () => clearTimeout(t);
    }
    if (loading) {
      wasLoadingRef.current = true;
      setAnnouncement("Loading application, please wait.");
    }
  }, [loading]);

  if (loading) return <AuthLoadingSkeleton />;

  return (
    <>
      {/* Polite live region announces auth-ready state to screen readers */}
      <div
        role="status"
        aria-live="polite"
        aria-atomic="true"
        className="sr-only"
      >
        {announcement}
      </div>
      <div
        ref={mainRef}
        id="main-content"
        tabIndex={-1}
        className="outline-none"
      >
        {children}
      </div>
    </>
  );
};

// Protected Route Component with optimized loading
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
  const { user, loading } = useAuth();
  
  // Show loading only when truly loading
  if (loading) {
    return (
      <div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 flex items-center justify-center">
        <div className="text-center">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-2"></div>
          <p className="text-sm text-muted-foreground">Loading...</p>
        </div>
      </div>
    );
  }
  
  // Redirect to login if not authenticated
  if (!user) {
    return <Navigate to="/login" replace />;
  }
  
  return <>{children}</>;
};

const App = () => (
  <QueryClientProvider client={queryClient}>
    <TooltipProvider>
      <SecurityHeaders />
      <LoadingOptimizer />
      <FaviconManager />
      <MetaTagManager />
      <Toaster />
      <Sonner />
      <BrowserRouter>
        <AuthProvider>
          <UserRoleProvider>
            <CartProvider>
              <PreOrderProvider>
                <AppTypeProvider>
                  <AuthGate>
                    <Routes>
                    <Route path="/login" element={<Login />} />
                    <Route path="/admin/*" element={
                      <Suspense fallback={<AuthLoadingSkeleton />}>
                        <AdminApp />
                      </Suspense>
                    } />
                    <Route path="/*" element={<AppRouter />} />
                    </Routes>
                  </AuthGate>
                  <CookieBanner />
                </AppTypeProvider>
              </PreOrderProvider>
            </CartProvider>
          </UserRoleProvider>
        </AuthProvider>
      </BrowserRouter>
    </TooltipProvider>
  </QueryClientProvider>
);

export default App;