
import { lazy, Suspense, useEffect } from "react";
import { BrowserRouter as Router, Routes, Route, Outlet, Navigate } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Toaster } from "sonner";
import { ThemeProvider } from "./contexts/ThemeContext";
import { AuthProvider } from "./contexts/AuthContext";
import { OfflineProvider } from "./contexts/OfflineContext";
import { FormatProvider } from "./contexts/FormatContext";
import { ProtectedRoute } from "./components/auth/ProtectedRoute";
import { CashierProtectedRoute } from "./components/auth/CashierProtectedRoute";
import { MainLayout } from "./components/layout/MainLayout";
import { ErrorBoundary } from "./components/ui/ErrorBoundary";
import { InstallPrompt } from "./components/pwa/InstallPrompt";
import { usePWAUpdate } from "./hooks/usePWAUpdate";
// Eager — needed at cold-start / auth check
import Index from "./pages/Index";
import TrackOrder from "./pages/TrackOrder";
import Install from "./pages/Install";
import NotFound from "./pages/NotFound";
import SelectClient from "./pages/SelectClient";
// Lazy — heavy pages loaded on first navigation
const Dashboard = lazy(() => import("./pages/Dashboard"));
const Clients = lazy(() => import("./pages/Clients"));
const ClientDetails = lazy(() => import("./pages/ClientDetails"));
const Sales = lazy(() => import("./pages/Sales"));
const SaleDetail = lazy(() => import("./pages/SaleDetail"));
const Orders = lazy(() => import("./pages/Orders"));
const Settings = lazy(() => import("./pages/Settings"));
const NewStatistics = lazy(() => import("./pages/NewStatistics"));
const SalesChanges = lazy(() => import("./pages/SalesChanges"));
const GraduationsAnalysis = lazy(() => import("./pages/GraduationsAnalysis"));
const Cashier = lazy(() => import("./pages/Cashier"));
const InvoicesPage = lazy(() => import("./pages/InvoicesPage").then(m => ({ default: m.InvoicesPage })));
import "./App.css";

const PageFallback = () => (
  <div className="flex items-center justify-center min-h-[60vh]">
    <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
  </div>
);

const PageErrorFallback = () => (
  <div className="flex flex-col items-center justify-center min-h-[60vh] p-4">
    <div className="max-w-md w-full p-6 bg-card text-card-foreground rounded-lg shadow-md text-center">
      <h2 className="text-lg font-semibold text-destructive mb-2">Error en esta sección</h2>
      <p className="text-muted-foreground mb-4 text-sm">
        Ocurrió un error al cargar esta página. El resto de la aplicación sigue funcionando.
      </p>
      <button
        onClick={() => window.location.reload()}
        className="px-4 py-2 bg-primary text-primary-foreground rounded-md text-sm hover:bg-primary/90"
      >
        Recargar página
      </button>
    </div>
  </div>
);

// Initialize QueryClient outside component to prevent recreation
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5 * 60 * 1000,
      refetchOnWindowFocus: false,
      retry: 1,
    },
    mutations: {
      retry: 1,
    },
  },
});

function App() {
  // Initialize PWA update functionality
  usePWAUpdate();

  // Mobile App Return Freeze Fix:
  // Shadcn/Radix UI applies pointer-events: none to the body when a dialog is open.
  // If the user backgrounds the app (switches tabs/apps) while animating, the cleanup might fail
  // leaving the app completely unresponsive to touch upon returning.
  useEffect(() => {
    const handleVisibilityChange = () => {
      // When the user returns to the app (it becomes visible again)
      if (document.visibilityState === "visible") {
        // Force unlock the body pointer events if they got stuck
        if (document.body.style.pointerEvents === 'none') {
          document.body.style.pointerEvents = 'auto';
          // Also attempt to remove the inline style entirely to let CSS classes take over
          document.body.style.removeProperty('pointer-events');
        }
        // Radix UI also uses data-scroll-locked, we can remove it as a last resort
        // but rely primarily on the CSS override for it.
      }
    };

    document.addEventListener("visibilitychange", handleVisibilityChange);

    // Also run it on initial mount just in case of weird PWA restore state
    handleVisibilityChange();

    return () => {
      document.removeEventListener("visibilitychange", handleVisibilityChange);
    };
  }, []);

  return (
    <ErrorBoundary>
      <QueryClientProvider client={queryClient}>
        <ThemeProvider>
          <ErrorBoundary>
            <Router>
              <AuthProvider>
                <OfflineProvider>
                  <FormatProvider>
                    <Toaster position="top-right" richColors />
                    <InstallPrompt />
                    <Routes>
                      <Route path="/" element={<Index />} />
                      <Route path="/consulta" element={<TrackOrder />} />
                      <Route path="/track" element={<TrackOrder />} />
                      <Route path="/install" element={<Install />} />
                      <Route path="/cashier" element={
                        <CashierProtectedRoute>
                          <ErrorBoundary fallback={<PageErrorFallback />}>
                            <Suspense fallback={<PageFallback />}>
                              <Cashier />
                            </Suspense>
                          </ErrorBoundary>
                        </CashierProtectedRoute>
                      } />
                      <Route element={
                        <ProtectedRoute>
                          <MainLayout>
                            <ErrorBoundary>
                              <Suspense fallback={<PageFallback />}>
                                <Outlet />
                              </Suspense>
                            </ErrorBoundary>
                          </MainLayout>
                        </ProtectedRoute>
                      }>
                        <Route path="/dashboard" element={<Dashboard />} />
                        <Route path="/clients" element={<Clients />} />
                        <Route path="/clients/:id" element={<ClientDetails />} />
                        <Route
                          path="/invoices"
                          element={
                            <ProtectedRoute allowedRoles={['admin']}>
                              <InvoicesPage />
                            </ProtectedRoute>
                          }
                        />
                        <Route path="/sales" element={<Sales />} />
                        <Route path="/sales/:id" element={<SaleDetail />} />
                        <Route path="/select-client" element={<SelectClient />} />
                        <Route path="/orders" element={<Orders />} />
                        <Route path="/new-statistics" element={<NewStatistics />} />
                        <Route path="/sales-changes" element={<SalesChanges />} />
                        <Route path="/graduations-analysis" element={<GraduationsAnalysis />} />
                        <Route path="/settings" element={<Settings />} />
                        <Route path="*" element={<NotFound />} />
                      </Route>
                    </Routes>
                  </FormatProvider>
                </OfflineProvider>
              </AuthProvider>
            </Router>
          </ErrorBoundary>
        </ThemeProvider>
      </QueryClientProvider>
    </ErrorBoundary>
  );
}

export default App;
