import { lazy, Suspense } from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import { PublicLayout } from "./layouts/PublicLayout";
import { useSession } from "./store/session";
import { HomePage } from "../pages/HomePage";
import { NotFoundPage } from "../pages/NotFoundPage";
import { Skeleton } from "../shared/ui/States";

const MaterialsPage = lazy(() =>
  import("../pages/MaterialsPage").then((module) => ({
    default: module.MaterialsPage,
  })),
);
const MaterialPage = lazy(() =>
  import("../pages/MaterialPage").then((module) => ({
    default: module.MaterialPage,
  })),
);
const EventsPage = lazy(() =>
  import("../pages/EventsPage").then((module) => ({
    default: module.EventsPage,
  })),
);
const AboutPage = lazy(() =>
  import("../pages/AboutPage").then((module) => ({
    default: module.AboutPage,
  })),
);
const MediaChannelsPage = lazy(() =>
  import("../pages/MediaChannelsPage").then((module) => ({
    default: module.MediaChannelsPage,
  })),
);
const LoginPage = lazy(() =>
  import("../pages/LoginPage").then((module) => ({
    default: module.LoginPage,
  })),
);
const ForbiddenPage = lazy(() =>
  import("../pages/ForbiddenPage").then((module) => ({
    default: module.ForbiddenPage,
  })),
);

const CabinetLayout = lazy(() =>
  import("./layouts/CabinetLayout").then((module) => ({
    default: module.CabinetLayout,
  })),
);
const CabinetHomePage = lazy(() =>
  import("../pages/cabinet/CabinetHomePage").then((module) => ({
    default: module.CabinetHomePage,
  })),
);
const ProfilePage = lazy(() =>
  import("../pages/cabinet/ProfilePage").then((module) => ({
    default: module.ProfilePage,
  })),
);
const EditorPage = lazy(() =>
  import("../pages/cabinet/EditorPage").then((module) => ({
    default: module.EditorPage,
  })),
);
const MaterialFormPage = lazy(() =>
  import("../pages/cabinet/MaterialFormPage").then((module) => ({
    default: module.MaterialFormPage,
  })),
);
const ModeratorPage = lazy(() =>
  import("../pages/cabinet/ModeratorPage").then((module) => ({
    default: module.ModeratorPage,
  })),
);
const AdminPage = lazy(() =>
  import("../pages/cabinet/AdminPage").then((module) => ({
    default: module.AdminPage,
  })),
);

function CabinetFallback() {
  return (
    <div className="grid gap-4 p-6">
      <Skeleton className="h-8 w-64" />
      <Skeleton className="h-32 w-full" />
      <Skeleton className="h-56 w-full" />
    </div>
  );
}

function RequireAuth({ children, roles }) {
  const user = useSession((state) => state.user);
  if (!user) return <Navigate to="/login" replace />;
  if (roles && !roles.includes(user.role)) return <Navigate to="/403" replace />;
  return children;
}

export function App() {
  return (
    <Suspense fallback={<CabinetFallback />}>
      <Routes>
        <Route element={<PublicLayout />}>
          <Route index element={<HomePage />} />
          <Route path="materials" element={<MaterialsPage />} />
          <Route path="materials/:slug" element={<MaterialPage />} />
          <Route path="events" element={<EventsPage />} />
          <Route path="media" element={<MediaChannelsPage />} />
          <Route path="about" element={<AboutPage />} />
        </Route>

        <Route path="/login" element={<LoginPage />} />
        <Route path="/403" element={<ForbiddenPage />} />

        <Route
          path="/cabinet"
          element={
            <RequireAuth>
              <CabinetLayout />
            </RequireAuth>
          }
        >
          <Route index element={<CabinetHomePage />} />
          <Route path="profile" element={<ProfilePage />} />
          <Route
            path="editor"
            element={
              <RequireAuth roles={["editor", "admin"]}>
                <EditorPage />
              </RequireAuth>
            }
          />
          <Route
            path="editor/new"
            element={
              <RequireAuth roles={["editor", "admin"]}>
                <MaterialFormPage />
              </RequireAuth>
            }
          />
          <Route
            path="moderation"
            element={
              <RequireAuth roles={["moderator", "admin"]}>
                <ModeratorPage />
              </RequireAuth>
            }
          />
          <Route
            path="admin"
            element={
              <RequireAuth roles={["admin"]}>
                <AdminPage />
              </RequireAuth>
            }
          />
        </Route>

        <Route path="*" element={<NotFoundPage />} />
      </Routes>
    </Suspense>
  );
}
