import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { polyfillCountryFlagEmojis } from "country-flag-emoji-polyfill";
import flagFontUrl from "country-flag-emoji-polyfill/dist/TwemojiCountryFlags.woff2?url";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { createBrowserRouter, Navigate, RouterProvider, useRouteError } from "react-router";
import { Toaster } from "sonner";
import { AppShell } from "@/components/AppShell";
import { Button } from "@/components/ui/button";
import { EmptyState } from "@/components/ui/feedback";
import { useI18n } from "@/i18n";
import { ApiError, errorMessage } from "@/lib/api";
import { homePath } from "@/lib/nav";
import { useCurrentUser } from "@/lib/queries";
import { useTheme } from "@/lib/theme";
import { TriangleAlert } from "lucide-react";
import "./index.css";

// Windows has no flag emojis (🇺🇸 shows as "US"); this loads a small self-hosted flag font only when needed.
polyfillCountryFlagEmojis("Twemoji Country Flags", flagFontUrl);

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 15_000,
      refetchOnWindowFocus: true,
      // Don't retry "you can't" / "not found" answers; retry network hiccups once.
      retry: (count, error) => !(error instanceof ApiError && error.status < 500) && count < 1,
    },
  },
});

function HomeRedirect() {
  const me = useCurrentUser();
  return <Navigate to={homePath(me.role)} replace />;
}

function RouteError() {
  const { t } = useI18n();
  const error = useRouteError();
  return (
    <EmptyState
      icon={TriangleAlert}
      title={t("shell.pageError")}
      action={<Button onClick={() => window.location.reload()}>{t("common.reload")}</Button>}
    >
      {errorMessage(error)}
    </EmptyState>
  );
}

/** Pop-up messages follow the light/dark mode of the app. */
function ThemedToaster() {
  const { theme } = useTheme();
  return <Toaster richColors position="top-right" closeButton theme={theme} />;
}

// Each page is downloaded only when it is first opened, so the app starts quickly on phones.
const router = createBrowserRouter([
  // The student portal: its own small layout and sign-in (a secure link), separate from the staff pages.
  { path: "/s/expired", lazy: async () => ({ Component: (await import("@/portal/PortalLayout")).PortalExpired }) },
  {
    path: "/s",
    lazy: async () => ({ Component: (await import("@/portal/PortalLayout")).PortalLayout }),
    errorElement: <RouteError />,
    children: [
      { index: true, lazy: async () => ({ Component: (await import("@/portal/PortalLayout")).PortalHome }) },
      { path: "practice", lazy: async () => ({ Component: (await import("@/portal/PracticePage")).PracticePage }) },
      { path: "ds160", lazy: async () => ({ Component: (await import("@/portal/Ds160Page")).Ds160Page }) },
      { path: "messages", lazy: async () => ({ Component: (await import("@/portal/Ds160Page")).MessagesPage }) },
      { path: "payments", lazy: async () => ({ Component: (await import("@/portal/PaymentsPage")).PaymentsPage }) },
      { path: "*", element: <Navigate to="/s" replace /> },
    ],
  },
  // Signing in: its own page, because nobody is signed in yet.
  { path: "/sign-in", lazy: async () => ({ Component: (await import("@/routes/auth/SignInPage")).SignInPage }), errorElement: <RouteError /> },
  {
    path: "/",
    element: <AppShell />,
    errorElement: <RouteError />,
    children: [
      { index: true, element: <HomeRedirect /> },
      { path: "home", lazy: async () => ({ Component: (await import("@/routes/HomePages")).HomePage }) },
      { path: "students", lazy: async () => ({ Component: (await import("@/routes/students/StudentsPage")).StudentsPage }) },
      {
        path: "students/new",
        lazy: async () => ({ Component: (await import("@/routes/students/StudentNewPage")).StudentNewPage }),
      },
      {
        path: "students/:sid",
        lazy: async () => ({ Component: (await import("@/routes/students/StudentPage")).StudentPage }),
      },
      { path: "generations", lazy: async () => ({ Component: (await import("@/routes/GenerationsPage")).GenerationsPage }) },
      { path: "overview", lazy: async () => ({ Component: (await import("@/routes/team/InsightPages")).OverviewPage }) },
      { path: "approvals", lazy: async () => ({ Component: (await import("@/routes/team/ApprovalsPage")).ApprovalsPage }) },
      { path: "team", lazy: async () => ({ Component: (await import("@/routes/team/TeamPage")).TeamPage }) },
      { path: "requests", lazy: async () => ({ Component: (await import("@/routes/team/RequestsPage")).RequestsPage }) },
      { path: "suggestions", lazy: async () => ({ Component: (await import("@/routes/team/InsightPages")).SuggestionsPage }) },
      { path: "activity", lazy: async () => ({ Component: (await import("@/routes/team/InsightPages")).ActivityPage }) },
      { path: "visa", lazy: async () => ({ Component: (await import("@/routes/visa/VisaPages")).VisaTrackerPage }) },
      { path: "calendar", lazy: async () => ({ Component: (await import("@/routes/visa/VisaPages")).CalendarPage }) },
      { path: "questions", lazy: async () => ({ Component: (await import("@/routes/visa/VisaPages")).QuestionsPage }) },
      { path: "visa-stats", lazy: async () => ({ Component: (await import("@/routes/visa/VisaPages")).VisaStatsPage }) },
      { path: "inbox", lazy: async () => ({ Component: (await import("@/routes/portal/StaffPortal")).InboxPage }) },
      { path: "finance", lazy: async () => ({ Component: (await import("@/routes/finance/FinancePages")).FinancePage }) },
      { path: "finance/fees", lazy: async () => ({ Component: (await import("@/routes/finance/FeesPage")).FeesPage }) },
      { path: "finance/invoices", lazy: async () => ({ Component: (await import("@/routes/finance/InvoicePages")).InvoicesPage }) },
      { path: "finance/invoices/:id", lazy: async () => ({ Component: (await import("@/routes/finance/InvoicePages")).InvoicePage }) },
      { path: "finance/payments", lazy: async () => ({ Component: (await import("@/routes/finance/PaymentPages")).PaymentsPage }) },
      { path: "finance/receipts/:id", lazy: async () => ({ Component: (await import("@/routes/finance/PaymentPages")).ReceiptPage }) },
      { path: "finance/refunds", lazy: async () => ({ Component: (await import("@/routes/finance/PaymentPages")).RefundsPage }) },
      { path: "finance/budget", lazy: async () => ({ Component: (await import("@/routes/finance/FinancePages")).BudgetPage }) },
      { path: "finance/expenses", lazy: async () => ({ Component: (await import("@/routes/finance/ExpensesPage")).ExpensesPage }) },
      { path: "finance/reports", lazy: async () => ({ Component: (await import("@/routes/finance/FinancePages")).ReportsPage }) },
      { path: "finance/students/:sid", lazy: async () => ({ Component: (await import("@/routes/finance/BillingPanel")).StudentBillingPage }) },
      { path: "it", lazy: async () => ({ Component: (await import("@/routes/it/ItHomePage")).ItHomePage }) },
      { path: "it/accounts", lazy: async () => ({ Component: (await import("@/routes/it/AccountsPage")).AccountsPage }) },
      { path: "it/security", lazy: async () => ({ Component: (await import("@/routes/it/SecurityPage")).SecurityPage }) },
      { path: "it/data", lazy: async () => ({ Component: (await import("@/routes/it/DataPage")).DataPage }) },
      { path: "it/api-keys", lazy: async () => ({ Component: (await import("@/routes/it/ApiKeysPage")).ApiKeysPage }) },
      { path: "it/devices", lazy: async () => ({ Component: (await import("@/routes/it/DevicesPage")).DevicesPage }) },
      { path: "it/helpdesk", lazy: async () => ({ Component: (await import("@/routes/it/HelpdeskPages")).HelpdeskPage }) },
      { path: "it/emergency", lazy: async () => ({ Component: (await import("@/routes/it/EmergencyPage")).EmergencyPage }) },
      { path: "settings", lazy: async () => ({ Component: (await import("@/routes/it/SettingsPage")).SettingsPage }) },
      { path: "help", lazy: async () => ({ Component: (await import("@/routes/it/HelpdeskPages")).HelpPage }) },
      { path: "alerts", lazy: async () => ({ Component: (await import("@/routes/AlertsPage")).AlertsPage }) },
      { path: "bot", lazy: async () => ({ Component: (await import("@/routes/BotsPage")).BotsPage }) },
      { path: "profile", lazy: async () => ({ Component: (await import("@/routes/ProfilePage")).ProfilePage }) },
      { path: "*", lazy: async () => ({ Component: (await import("@/routes/HomePages")).ComingSoonPage }) },
    ],
  },
]);

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <QueryClientProvider client={queryClient}>
      <RouterProvider router={router} />
      <ThemedToaster />
    </QueryClientProvider>
  </StrictMode>,
);
