/**
 * App — top-level provider stack and route tree.
 *
 * Provider order (outermost first):
 *   MantineProvider → QueryClientProvider → BrowserRouter → SessionProvider → routes
 *
 * Route tree:
 *   /login            → LoginPage (public)
 *   /change-password  → ProtectedRoute → ChangePasswordPage (forced password change gate)
 *   /                 → ProtectedRoute → AppLayout → HomePage
 *   /config           → ProtectedRoute → AppLayout → ConfigPage
 *   /records          → ProtectedRoute → AppLayout → RecordsPage
 *   /energy           → ProtectedRoute → AppLayout → EnergyPage
 *
 * AppLayout renders a sidebar (AppSidebar) on the left; page content via <Outlet/> on the right.
 * /login and /change-password have no sidebar layout.
 */

import { useState } from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { BrowserRouter, Routes, Route, Outlet } from 'react-router-dom'
import { MantineProvider, AppShell, Burger } from '@mantine/core'

// Mantine requires its CSS to be imported once.
import '@mantine/core/styles.css'

import { SessionProvider } from './auth/SessionProvider'
import { ProtectedRoute } from './auth/ProtectedRoute'
import { LoginPage } from './pages/LoginPage'
import { HomePage } from './pages/HomePage'
import { ConfigPage } from './pages/ConfigPage'
import { RecordsPage } from './pages/RecordsPage'
import { EnergyPage } from './pages/EnergyPage'
import { ChangePasswordPage } from './pages/ChangePasswordPage'
import { AppSidebar } from './components/AppSidebar'

// ---------------------------------------------------------------------------
// TanStack Query client (singleton, created outside render to avoid re-creation)
// ---------------------------------------------------------------------------

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      // Don't retry on 4xx — we handle 401 in the middleware
      retry: (failureCount, error) => {
        if (error instanceof Error && 'status' in error) {
          const status = (error as unknown as { status: number }).status
          if (status >= 400 && status < 500) return false
        }
        return failureCount < 2
      },
    },
  },
})

// ---------------------------------------------------------------------------
// App shell layout (used by all protected pages)
// ---------------------------------------------------------------------------

function AppLayout() {
  // Mobile navbar open/close state — controlled here so the Burger and
  // AppShell share the same state.
  const [navbarOpen, setNavbarOpen] = useState(false)

  return (
    <AppShell
      navbar={{
        width: 220,
        breakpoint: 'sm',
        collapsed: { mobile: !navbarOpen },
      }}
      header={{ height: { base: 48, sm: 0 } }}
      padding="md"
    >
      {/* Burger shown on mobile only (hidden on sm+) */}
      <AppShell.Header hiddenFrom="sm" p="xs">
        <Burger
          opened={navbarOpen}
          onClick={() => setNavbarOpen((o) => !o)}
          size="sm"
          aria-label="Toggle navigation"
          data-testid="nav-burger"
        />
      </AppShell.Header>

      <AppSidebar onNavClick={() => setNavbarOpen(false)} />

      <AppShell.Main>
        <Outlet />
      </AppShell.Main>
    </AppShell>
  )
}

// ---------------------------------------------------------------------------
// Root app
// ---------------------------------------------------------------------------

export default function App() {
  return (
    <MantineProvider defaultColorScheme="auto">
      <QueryClientProvider client={queryClient}>
        <BrowserRouter>
          <SessionProvider>
            <Routes>
              {/* Public routes */}
              <Route path="/login" element={<LoginPage />} />

              {/* Forced password change — protected (must be logged in) but outside AppLayout */}
              <Route
                path="/change-password"
                element={
                  <ProtectedRoute>
                    <ChangePasswordPage />
                  </ProtectedRoute>
                }
              />

              {/* Protected routes — all nested under AppLayout (sidebar) */}
              <Route
                element={
                  <ProtectedRoute>
                    <AppLayout />
                  </ProtectedRoute>
                }
              >
                <Route index element={<HomePage />} />
                <Route path="/config" element={<ConfigPage />} />
                <Route path="/records" element={<RecordsPage />} />
                <Route path="/energy" element={<EnergyPage />} />
              </Route>
            </Routes>
          </SessionProvider>
        </BrowserRouter>
      </QueryClientProvider>
    </MantineProvider>
  )
}
