import { lazy, Suspense } from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import { AuthProvider, useAuth } from "./lib/auth";
import type { User } from "../shared/types";
import { AppShell } from "./components/AppShell";
import { AdminShell } from "./components/AdminShell";
import { EmployeesPage } from "./pages/EmployeesPage";
import { ServicesPage } from "./pages/ServicesPage";
import { ClientsPage } from "./pages/ClientsPage";
import { TicketsPage } from "./pages/TicketsPage";
import { ClientDetailPage } from "./pages/ClientDetailPage";
import { CashPage } from "./pages/CashPage";
import { NotificationsPage } from "./pages/NotificationsPage";
import { SettingsPage } from "./pages/SettingsPage";
import { MyPerformancePage } from "./pages/MyPerformancePage";
import { AdminOverviewPage } from "./pages/admin/AdminOverviewPage";
import { AdminBusinessesPage } from "./pages/admin/AdminBusinessesPage";
import { AdminBusinessDetailPage } from "./pages/admin/AdminBusinessDetailPage";
import BookingPage from "./pages/public/BookingPage";

// Las dos páginas públicas van aparte del bundle principal por dos razones que
// apuntan en direcciones opuestas, y por eso importan las dos: quien ya tiene
// sesión nunca las ve y no debe descargarlas, y quien llega a la landing no debe
// descargar FullCalendar ni recharts para leer una página de venta.
//
// El login tiene que ser lazy junto con la landing, no solo la landing: es el único
// consumidor eager de framer-motion, y con él en el chunk de entrada Rollup mete
// `lib/motion` ahí también. Eso obliga al chunk de la landing a importar el de
// entrada, que a su vez arrastra `charts` y `calendar`. Medido: 39 kB gzip de
// motion en cada carga del panel, más recharts y FullCalendar en la landing.
const LandingPage = lazy(() => import("./pages/LandingPage"));
const LoginPage = lazy(() =>
  import("./pages/LoginPage").then((m) => ({ default: m.LoginPage }))
);

// Las dos únicas páginas que importan librerías pesadas: recharts (~111 KB gzip) y
// FullCalendar (~76 KB gzip). Eager, viven en el chunk de entrada, que se descarga
// en TODA visita — incluida la landing, que no grafica ni agenda nada. Su frontera
// de Suspense está en el <Outlet> de AppShell.
const DashboardPage = lazy(() =>
  import("./pages/DashboardPage").then((m) => ({ default: m.DashboardPage }))
);
const CalendarPage = lazy(() =>
  import("./pages/CalendarPage").then((m) => ({ default: m.CalendarPage }))
);

/** Destino del usuario según su rol. Única definición de la regla. */
export function homePathFor(user: User): string {
  if (user.role === "admin") return "/admin";
  return user.role === "owner" ? "/dashboard" : "/calendar";
}

function Splash() {
  return (
    <div className="flex h-screen-safe items-center justify-center bg-[#f6f7fb]">
      <div className="flex flex-col items-center gap-3 text-slate-500">
        <div className="h-9 w-9 animate-spin rounded-full border-2 border-brand-500 border-t-transparent" />
        <span className="text-sm font-medium">Cargando AgendaMax…</span>
      </div>
    </div>
  );
}

function AppRoutes() {
  const { user, loading } = useAuth();
  if (loading) return <Splash />;

  const home = user ? homePathFor(user) : "/login";
  const isAdmin = user?.role === "admin";

  return (
    <Routes>
      {/* ---- Públicas ---- */}
      <Route
        path="/"
        element={
          user ? (
            <Navigate to={home} replace />
          ) : (
            <Suspense fallback={<Splash />}>
              <LandingPage />
            </Suspense>
          )
        }
      />
      <Route
        path="/login"
        element={
          user ? (
            <Navigate to={home} replace />
          ) : (
            <Suspense fallback={<Splash />}>
              <LoginPage />
            </Suspense>
          )
        }
      />

      {/* Sin sesión, cualquier otra ruta manda al login. */}
      {!user && <Route path="*" element={<Navigate to="/login" replace />} />}

      {/* ---- Admin de plataforma ---- */}
      {user && isAdmin && (
        <Route element={<AdminShell />}>
          <Route path="/admin" element={<AdminOverviewPage />} />
          <Route path="/admin/businesses" element={<AdminBusinessesPage />} />
          <Route path="/admin/businesses/:id" element={<AdminBusinessDetailPage />} />
          <Route path="*" element={<Navigate to="/admin" replace />} />
        </Route>
      )}

      {/* ---- Negocio ---- */}
      {user && !isAdmin && (
        <Route element={<AppShell />}>
          {user.role === "owner" ? (
            <Route path="/dashboard" element={<DashboardPage />} />
          ) : (
            <Route path="/dashboard" element={<Navigate to="/calendar" replace />} />
          )}
          <Route path="/calendar" element={<CalendarPage />} />
          <Route path="/clients" element={<ClientsPage />} />
          <Route path="/clients/:id" element={<ClientDetailPage />} />
          <Route path="/me" element={<MyPerformancePage />} />
          {user.role === "owner" && <Route path="/employees" element={<EmployeesPage />} />}
          {user.role === "owner" && <Route path="/services" element={<ServicesPage />} />}
          {user.role === "owner" && <Route path="/tickets" element={<TicketsPage />} />}
          {user.role === "owner" && <Route path="/cash" element={<CashPage />} />}
          {user.role === "owner" && <Route path="/notifications" element={<NotificationsPage />} />}
          {user.role === "owner" && <Route path="/settings" element={<SettingsPage />} />}
          {/* La autorización real vive en los middlewares del servidor; esto es UX. */}
          <Route path="/admin/*" element={<Navigate to={home} replace />} />
          <Route path="*" element={<Navigate to={home} replace />} />
        </Route>
      )}
    </Routes>
  );
}

export default function App() {
  return (
    <Routes>
      {/* Reservas públicas: fuera del AuthProvider a propósito, no asumas usuario. */}
      <Route path="/b/:slug" element={<BookingPage />} />
      <Route
        path="*"
        element={
          <AuthProvider>
            <AppRoutes />
          </AuthProvider>
        }
      />
    </Routes>
  );
}
