/**
 * Application root component.
 *
 * Provider order (see `src/providers/PROVIDER_ORDER.md` for detailed contract):
 *  1. `ThemeProvider`                    — OUTERMOST; provides theme context to AppContents
 *  2. `FluentProvider`                   — supplies Fluent UI theme and design tokens
 *  3. `NotificationProvider`             — provides notification service to all descendants
 *  4. `ErrorBoundary`                    — catches catastrophic errors
 *  5. `BrowserRouter`                    — enables client-side routing via React Router
 *  6. `NavigationCancellationProvider`  — manages route-aware request cancellation
 *  7. `AuthProvider`                     — manages session state; validates on mount; uses useNavigate()
 *  8. `TimezoneProvider`                 — INNERMOST (inside protected routes); fetches timezone after auth
 *
 * CRITICAL: Provider order is order-sensitive. See PROVIDER_ORDER.md before refactoring.
 *
 * Routes:
 *  - `/setup`           — first-run setup wizard (always accessible; redirects to /login if already done)
 *  - `/login`           — master password login (redirects to /setup if not done)
 *  - `/`                — dashboard (protected, inside MainLayout)
 *  - `/map`             — world map (protected)
 *  - `/jails`           — jail list (protected)
 *  - `/jails/:name`     — jail detail (protected)
 *  - `/config`          — configuration editor (protected)
 *  - `/history`         — event history (protected)
 *  - `/blocklists`      — blocklist management (protected)
 *  All unmatched paths redirect to `/`.
 *
 * Error Boundaries:
 *  - Top-level ErrorBoundary wraps the entire app shell (rare full-page reload).
 *  - Each page route wrapped in PageErrorBoundary (page fails but nav persists).
 *  - Risky sections within pages wrapped in SectionErrorBoundary (graceful degradation).
 */

import { lazy, Suspense, useEffect } from "react";
import { FluentProvider, Spinner } from "@fluentui/react-components";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import { darkTheme, lightTheme } from "./theme/customTheme";
import { ThemeProvider, useThemeMode } from "./providers/ThemeProvider";
import { AuthProvider } from "./providers/AuthProvider";
import { TimezoneProvider } from "./providers/TimezoneProvider";
import { NavigationCancellationProvider } from "./providers/NavigationCancellationProvider";
import { NotificationProvider } from "./services/notificationService";
import { RequireAuth } from "./components/RequireAuth";
import { SetupGuard } from "./components/SetupGuard";
import { ErrorBoundary } from "./components/ErrorBoundary";
import { PageErrorBoundary } from "./components/PageErrorBoundary";
import { NotificationContainer } from "./components/NotificationContainer";
import { MainLayout } from "./layouts/MainLayout";
import { injectSkeletonStyles } from "./utils/skeletonStyles";
import { initializeWebVitals } from "./utils/metrics";

const SetupPage = lazy(() => import("./pages/SetupPage").then((m) => ({ default: m.SetupPage })));
const LoginPage = lazy(() => import("./pages/LoginPage").then((m) => ({ default: m.LoginPage })));
const DashboardPage = lazy(() => import("./pages/DashboardPage").then((m) => ({ default: m.DashboardPage })));
const MapPage = lazy(() => import("./pages/MapPage").then((m) => ({ default: m.MapPage })));
const JailsPage = lazy(() => import("./pages/JailsPage").then((m) => ({ default: m.JailsPage })));
const JailDetailPage = lazy(() => import("./pages/JailDetailPage").then((m) => ({ default: m.JailDetailPage })));
const ConfigPage = lazy(() => import("./pages/ConfigPage").then((m) => ({ default: m.ConfigPage })));
const HistoryPage = lazy(() => import("./pages/HistoryPage").then((m) => ({ default: m.HistoryPage })));
const BlocklistsPage = lazy(() => import("./pages/BlocklistsPage").then((m) => ({ default: m.BlocklistsPage })));

/**
 * Root application component — mounts providers and top-level routes.
 *
 * Provider stack (see PROVIDER_ORDER.md for detailed contract):
 *  - FluentProvider (2)                   — receives theme from useThemeMode()
 *  - NotificationProvider (3)             — provides notification service
 *  - ErrorBoundary (4)                    — catches catastrophic errors
 *  - BrowserRouter (5)                    — enables routing
 *  - NavigationCancellationProvider (6)  — manages route-aware request cancellation
 *  - AuthProvider (7)                    — session validation; uses useNavigate()
 *  - TimezoneProvider (8)                — inside protected routes only
 */
function AppContents(): React.JSX.Element {
  const { colorMode } = useThemeMode();
  const theme = colorMode === "dark" ? darkTheme : lightTheme;

  // Inject skeleton animation styles once at app startup
  injectSkeletonStyles();

  // Initialize web vitals tracking on component mount
  useEffect(() => {
    initializeWebVitals();
  }, []);

  return (
    // 2. FluentProvider — supplies Fluent UI theme and tokens
    <FluentProvider theme={theme}>
      {/* 3. NotificationProvider — makes notification service available */}
      <NotificationProvider>
        {/* 4. ErrorBoundary — catches catastrophic errors that would crash the app */}
        <ErrorBoundary
          title="Application Error"
          message="The application encountered a critical error. Reloading may help."
          isFullPage={true}
        >
          {/* Notification container must be rendered inside ErrorBoundary */}
          <NotificationContainer />
          {/* 5. BrowserRouter — enables routing; required by AuthProvider's useNavigate() */}
          <BrowserRouter future={{ v7_startTransition: true, v7_relativeSplatPath: true }}>
            {/* 6. NavigationCancellationProvider — manages route-aware request cancellation */}
            <NavigationCancellationProvider>
              <Suspense fallback={<Spinner size="large" label="Loading…" />}>
                {/* 7. AuthProvider — validates session on mount; must be inside BrowserRouter */}
                <AuthProvider>
                  <Routes>
                    {/* Setup wizard — always accessible; redirects to /login if already done */}
                    <Route
                      path="/setup"
                      element={
                        <PageErrorBoundary pageName="Setup">
                          <SetupPage />
                        </PageErrorBoundary>
                      }
                    />

                    {/* Login — requires setup to be complete */}
                    <Route
                      path="/login"
                      element={
                        <PageErrorBoundary pageName="Login">
                          <SetupGuard>
                            <LoginPage />
                          </SetupGuard>
                        </PageErrorBoundary>
                      }
                    />

                    {/* Protected routes — require setup AND authentication */}
                    <Route
                      element={
                        <SetupGuard>
                          <RequireAuth>
                            {/* 8. TimezoneProvider — INNERMOST; fetches timezone after auth validation */}
                            <TimezoneProvider>
                              <MainLayout />
                            </TimezoneProvider>
                          </RequireAuth>
                        </SetupGuard>
                      }
                    >
                      <Route
                        index
                        element={
                          <PageErrorBoundary pageName="Dashboard">
                            <DashboardPage />
                          </PageErrorBoundary>
                        }
                      />
                      <Route
                        path="/map"
                        element={
                          <PageErrorBoundary pageName="Map">
                            <MapPage />
                          </PageErrorBoundary>
                        }
                      />
                      <Route
                        path="/jails"
                        element={
                          <PageErrorBoundary pageName="Jails">
                            <JailsPage />
                          </PageErrorBoundary>
                        }
                      />
                      <Route
                        path="/jails/:name"
                        element={
                          <PageErrorBoundary pageName="Jail Details">
                            <JailDetailPage />
                          </PageErrorBoundary>
                        }
                      />
                      <Route
                        path="/config"
                        element={
                          <PageErrorBoundary pageName="Configuration">
                            <ConfigPage />
                          </PageErrorBoundary>
                        }
                      />
                      <Route
                        path="/history"
                        element={
                          <PageErrorBoundary pageName="History">
                            <HistoryPage />
                          </PageErrorBoundary>
                        }
                      />
                      <Route
                        path="/blocklists"
                        element={
                          <PageErrorBoundary pageName="Blocklists">
                            <BlocklistsPage />
                          </PageErrorBoundary>
                        }
                      />
                    </Route>

                    {/* Fallback — redirect unknown paths to dashboard */}
                    <Route path="*" element={<Navigate to="/" replace />} />
                  </Routes>
                </AuthProvider>
              </Suspense>
            </NavigationCancellationProvider>
          </BrowserRouter>
        </ErrorBoundary>
      </NotificationProvider>
    </FluentProvider>
  );
}

function App(): React.JSX.Element {
  // ThemeProvider (1. OUTERMOST) — provides theme context needed by AppContents
  return (
    <ThemeProvider>
      <AppContents />
    </ThemeProvider>
  );
}

export default App;
