import React, { Suspense, lazy, useEffect, useMemo, useState } from "react";

import { Box, Button, CssBaseline, IconButton, Typography } from "@mui/material";
import useMediaQuery from "@mui/material/useMediaQuery";
import { CssVarsProvider } from "@mui/material/styles";

import DashboardIcon from "@mui/icons-material/Dashboard";
import WorkOutlineIcon from "@mui/icons-material/WorkOutline";
import ViewKanbanIcon from "@mui/icons-material/ViewKanban";
import BusinessIcon from "@mui/icons-material/Business";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import SettingsIcon from "@mui/icons-material/Settings";
import AlarmIcon from "@mui/icons-material/Alarm";
import AccountCircleIcon from "@mui/icons-material/AccountCircle";
import ShieldIcon from "@mui/icons-material/Shield";
import SearchIcon from "@mui/icons-material/Search";
import MemoryIcon from "@mui/icons-material/Memory";

import { Navigate, Route, Routes, useLocation, useNavigate, createBrowserRouter, RouterProvider } from "react-router-dom";

import { getTheme } from "./theme";
import { ToastProvider } from "./toast";
import { ConfirmProvider } from "./confirm";
import { PromptProvider } from "./prompt";

import JobTable from "./components/JobTable";
import type { JobTableColumns } from "./components/JobTable";
import { I18nProvider, useI18n } from "./i18n/I18nProvider";
import LoginPage from "./pages/LoginPage";
import ForgotPasswordPage from "./pages/ForgotPasswordPage";
import ResetPasswordPage from "./pages/ResetPasswordPage";
import RouteErrorPage from "./pages/RouteErrorPage";
import { api } from "./api";
import { clearAuthToken, getAuthToken } from "./auth";
import AppShell, { NavItem } from "./layout/AppShell";
import { clearAccentColor, getAccentColor, getThemeModePref, setAccentColor, setThemeModePref, ThemeModePref } from "./themePrefs";

const AddJobModal = lazy(() => import("./components/AddJobModal"));
const KanbanBoard = lazy(() => import("./components/KanbanBoard"));
const DashboardView = lazy(() => import("./components/DashboardView"));
const CompaniesTable = lazy(() => import("./components/CompaniesTable"));
const SettingsView = lazy(() => import("./components/SettingsView"));
const RemindersView = lazy(() => import("./components/RemindersView"));
const QuickCommandDialog = lazy(() => import("./components/QuickCommandDialog"));
const ProfilePage = lazy(() => import("./pages/ProfilePage"));
const AdminAuditPage = lazy(() => import("./pages/AdminAuditPage"));
const AdminUsersPage = lazy(() => import("./pages/AdminUsersPage"));
const AdminSystemPage = lazy(() => import("./pages/AdminSystemPage"));
const NotFoundPage = lazy(() => import("./pages/NotFoundPage"));

type AuthConfig = { requireAuth: boolean };
type MeResponse = {
  provider?: "local" | "google" | "external";
  id?: string;
  email?: string;
  userName?: string;
  firstName?: string;
  lastName?: string;
  displayName?: string;
  avatarImageDataUrl?: string;
  roles?: string[];
};

function breadcrumbsFor(path: string, t: (k: any) => string): string[] {
  if (path.startsWith("/dashboard")) return [t("home"), t("analytics"), t("overview")];
  if (path.startsWith("/jobs")) return [t("home"), t("jobApplications")];
  if (path.startsWith("/reminders")) return [t("home"), t("reminders")];
  if (path.startsWith("/kanban")) return [t("home"), t("kanbanBoard")];
  if (path.startsWith("/companies")) return [t("home"), t("companies")];
  if (path.startsWith("/trash")) return [t("home"), t("trash")];
  if (path.startsWith("/settings")) return [t("home"), t("settings")];
  if (path.startsWith("/profile")) return [t("home"), t("account"), t("profile")];
  if (path.startsWith("/admin/audit")) return [t("home"), t("admin"), t("auditLog")];
  if (path.startsWith("/admin/users")) return [t("home"), t("admin"), t("users")];
  if (path.startsWith("/admin/system")) return [t("home"), t("admin"), t("system")];
  return [t("home")];
}

function titleFor(path: string, t: (k: any) => string): string {
  if (path === "/dashboard") return t("dashboard");
  if (path.startsWith("/reminders")) return t("reminders");
  if (path.startsWith("/jobs")) return t("jobApplications");
  if (path.startsWith("/kanban")) return t("kanbanBoard");
  if (path.startsWith("/companies")) return t("companies");
  if (path.startsWith("/trash")) return t("trash");
  if (path.startsWith("/settings")) return t("settings");
  if (path.startsWith("/profile")) return t("profile");
  if (path.startsWith("/admin/audit")) return t("auditLog");
  if (path.startsWith("/admin/users")) return t("users");
  if (path.startsWith("/admin/system")) return t("systemStatus");
  return t("appTitle");
}

function PageLoader() {
  return <Box sx={{ p: 4 }}><Typography variant="h6">Loading...</Typography></Box>;
}

function Shell({ jobPageSize, setJobPageSize, jobColumns, setJobColumns, themeMode, onThemeModeChange, accentColor, onAccentColorChange, onResetAccentColor }: { jobPageSize: 15 | 20 | 25; setJobPageSize: (n: 15 | 20 | 25) => void; jobColumns: JobTableColumns; setJobColumns: (c: JobTableColumns) => void; themeMode: ThemeModePref; onThemeModeChange: (v: ThemeModePref) => void; accentColor: string; onAccentColorChange: (v: string) => void; onResetAccentColor: () => void; }) {
  const location = useLocation();
  const navigate = useNavigate();
  const { t } = useI18n();
  const compactHeaderActions = useMediaQuery("(max-width:767.95px)");

  const [addOpen, setAddOpen] = useState(false);
  const [quickOpen, setQuickOpen] = useState(false);
  const [refreshToken, setRefreshToken] = useState(0);
  const [requireAuth, setRequireAuth] = useState<boolean | null>(null);
  const [isAdmin, setIsAdmin] = useState(false);
  const [me, setMe] = useState<MeResponse | null>(null);
  const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false);
  const [notifCount, setNotifCount] = useState(0);

  const path = location.pathname;
  const isJobs = path.startsWith("/jobs");

  useEffect(() => {
    api.get<AuthConfig>("/auth/config").then((r) => setRequireAuth(Boolean(r.data?.requireAuth))).catch(() => setRequireAuth(false));
  }, []);
  useEffect(() => {
    api.get<MeResponse>("/auth/me").then((r) => { setMe(r.data); setIsAdmin(Boolean(r.data?.roles?.includes("Admin"))); }).catch(() => { setMe(null); setIsAdmin(false); });
  }, []);
  useEffect(() => {
    const load = () => {
      api.get<any[]>("/jobapplications/reminders", { params: { upcomingDays: 14 } }).then((r) => setNotifCount(Array.isArray(r.data) ? r.data.length : 0)).catch(() => setNotifCount(0));
    };
    load();
    const id = window.setInterval(load, 60000);
    return () => window.clearInterval(id);
  }, []);
  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setQuickOpen(true);
      }
    };
    window.addEventListener("keydown", onKeyDown);
    return () => window.removeEventListener("keydown", onKeyDown);
  }, []);

  const token = getAuthToken();
  if (requireAuth === null) return <Box sx={{ p: 4 }}><Typography variant="h6">Loading...</Typography></Box>;
  if (requireAuth && !token) return <Navigate to="/login" replace state={{ from: path }} />;

  const pageTitle = titleFor(path, t);
  const breadcrumbs = breadcrumbsFor(path, t);
  const setAndPersistPageSize = (n: 15 | 20 | 25) => { setJobPageSize(n); window.localStorage.setItem("jobPageSize", String(n)); };
  const setAndPersistColumns = (next: JobTableColumns) => { setJobColumns(next); window.localStorage.setItem("jobColumns", JSON.stringify(next)); };
  const fullName = [me?.firstName, me?.lastName].filter(Boolean).join(" ");

  const nav: NavItem[] = [
    { to: "/dashboard", label: t("dashboard"), icon: <DashboardIcon fontSize="small" />, section: t("manage") },
    { to: "/jobs", label: t("jobApplications"), icon: <WorkOutlineIcon fontSize="small" />, section: t("manage") },
    { to: "/reminders", label: t("reminders"), icon: <AlarmIcon fontSize="small" />, badgeCount: notifCount, section: t("manage") },
    { to: "/kanban", label: t("kanbanBoard"), icon: <ViewKanbanIcon fontSize="small" />, section: t("manage") },
    { to: "/companies", label: t("companies"), icon: <BusinessIcon fontSize="small" />, section: t("manage") },
    { to: "/trash", label: t("trash"), icon: <DeleteOutlineIcon fontSize="small" />, section: t("manage") },
  ];

  const navBottom: NavItem[] = [
    { to: "/admin/audit", label: t("auditLog"), icon: <ShieldIcon fontSize="small" />, hidden: !isAdmin, section: t("admin") },
    { to: "/admin/users", label: t("users"), icon: <AccountCircleIcon fontSize="small" />, hidden: !isAdmin, section: t("admin") },
    { to: "/admin/system", label: t("system"), icon: <MemoryIcon fontSize="small" />, hidden: !isAdmin, section: t("admin") },
    { to: "/profile", label: t("profile"), icon: <AccountCircleIcon fontSize="small" />, section: t("account") },
    { to: "/settings", label: t("settings"), icon: <SettingsIcon fontSize="small" />, section: t("account") },
  ];

  const rightActions = (
    <Box
      sx={{
        display: "flex",
        alignItems: "center",
        gap: 1,
        flexWrap: "nowrap",
        justifyContent: "flex-end",
        width: { xs: "100%", sm: "auto" },
        flex: { xs: 1, sm: "0 0 auto" },
      }}
    >
      {compactHeaderActions ? (
        <IconButton
          color="secondary"
          size="small"
          title={t("quickSearch")}
          onClick={() => setQuickOpen(true)}
          sx={{ border: "1px solid", borderColor: "divider", borderRadius: 2.5, width: 42, height: 42, flex: "0 0 auto" }}
        >
          <SearchIcon fontSize="small" />
        </IconButton>
      ) : (
        <Button variant="outlined" startIcon={<SearchIcon />} onClick={() => setQuickOpen(true)}>{t("quickSearch")}</Button>
      )}
      {isJobs ? (
        <Button variant="contained" onClick={() => setAddOpen(true)} sx={{ flex: { xs: 1, sm: "0 0 auto" }, minHeight: 42 }}>
          {t("addJob")}
        </Button>
      ) : null}
    </Box>
  );

  return (
    <>
      <AppShell
        pageTitle={pageTitle}
        breadcrumbs={breadcrumbs}
        pathname={path}
        nav={nav}
        navBottom={navBottom}
        drawerOpen={mobileDrawerOpen}
        onToggleDrawer={setMobileDrawerOpen}
        onNavigate={(to) => { setMobileDrawerOpen(false); navigate(to); }}
        user={{ email: me?.email, userName: me?.userName, displayName: me?.displayName || fullName || undefined, avatarImageDataUrl: me?.avatarImageDataUrl, roleLabel: isAdmin ? t("superAdmin") : t("user") }}
        notificationsCount={notifCount}
        onOpenNotifications={() => navigate("/reminders")}
        onOpenSettings={() => navigate("/settings")}
        onOpenProfile={() => navigate("/profile")}
        onSignOut={() => { clearAuthToken(); navigate("/login"); }}
        rightActions={rightActions}
      >
        <Suspense fallback={<PageLoader />}>
          <Routes>
            <Route path="/" element={<Navigate to="/jobs" replace />} />
            <Route path="/dashboard" element={<DashboardView />} />
            <Route path="/jobs" element={<JobTable refreshToken={refreshToken} pageSize={jobPageSize} onPageSizeChange={setAndPersistPageSize} columns={jobColumns} onColumnsChange={setAndPersistColumns} mode="jobs" />} />
            <Route path="/reminders" element={<RemindersView />} />
            <Route path="/kanban" element={<KanbanBoard />} />
            <Route path="/companies" element={<CompaniesTable />} />
            <Route path="/profile" element={<ProfilePage />} />
            <Route path="/admin/audit" element={<AdminAuditPage />} />
            <Route path="/admin/users" element={<AdminUsersPage />} />
            <Route path="/admin/system" element={<AdminSystemPage />} />
            <Route path="/trash" element={<JobTable refreshToken={refreshToken} pageSize={jobPageSize} onPageSizeChange={setAndPersistPageSize} columns={jobColumns} onColumnsChange={setAndPersistColumns} mode="trash" />} />
            <Route path="/settings" element={<SettingsView pageSize={jobPageSize} onPageSizeChange={setAndPersistPageSize} columns={jobColumns} onColumnsChange={setAndPersistColumns} themeMode={themeMode} onThemeModeChange={onThemeModeChange} accentColor={accentColor} onAccentColorChange={onAccentColorChange} onResetAccentColor={onResetAccentColor} />} />
            <Route path="*" element={<NotFoundPage />} />
          </Routes>
        </Suspense>
      </AppShell>

      <Suspense fallback={null}>
        <AddJobModal open={addOpen} onClose={() => setAddOpen(false)} onCreated={() => { setRefreshToken((t) => t + 1); }} />
        <QuickCommandDialog open={quickOpen} onClose={() => setQuickOpen(false)} onNavigate={(to) => navigate(to)} onOpenAddJob={() => setAddOpen(true)} />
      </Suspense>
    </>
  );
}

export default function App() {
  const systemPrefersDark = useMediaQuery("(prefers-color-scheme: dark)", { defaultMatches: true, noSsr: true });
  const [themeMode, setThemeMode] = useState<ThemeModePref>(() => getThemeModePref());
  const [accentColor, setAccentColorState] = useState<string>(() => getAccentColor());
  const effectiveMode: "light" | "dark" = themeMode === "light" ? "light" : themeMode === "dark" ? "dark" : systemPrefersDark ? "dark" : "light";
  const theme = useMemo(() => getTheme(effectiveMode, accentColor), [effectiveMode, accentColor]);

  useEffect(() => {
    const sync = () => { setThemeMode(getThemeModePref()); setAccentColorState(getAccentColor()); };
    window.addEventListener("auth-changed", sync);
    return () => window.removeEventListener("auth-changed", sync);
  }, []);

  const onThemeModeChange = (v: ThemeModePref) => { setThemeModePref(v); setThemeMode(v); };
  const onAccentColorChange = (v: string) => { setAccentColor(v); setAccentColorState(getAccentColor()); };
  const onResetAccentColor = () => { clearAccentColor(); setAccentColorState(getAccentColor()); };

  const [jobPageSize, setJobPageSize] = useState<15 | 20 | 25>(() => {
    const raw = window.localStorage.getItem("jobPageSize");
    const n = raw ? Number(raw) : 15;
    return (n === 20 || n === 25 ? n : 15) as 15 | 20 | 25;
  });
  const [jobColumns, setJobColumns] = useState<JobTableColumns>(() => {
    const raw = window.localStorage.getItem("jobColumns");
    if (!raw) return { status: true, dateApplied: true, daysSince: true, jobUrl: false };
    try {
      const p = JSON.parse(raw) as Partial<JobTableColumns>;
      return { status: p.status ?? true, dateApplied: p.dateApplied ?? true, daysSince: p.daysSince ?? true, jobUrl: p.jobUrl ?? false };
    } catch {
      return { status: true, dateApplied: true, daysSince: true, jobUrl: false };
    }
  });

  const router = useMemo(() => createBrowserRouter([
    { path: "/login", element: <LoginPage />, errorElement: <RouteErrorPage /> },
    { path: "/forgot-password", element: <ForgotPasswordPage />, errorElement: <RouteErrorPage /> },
    { path: "/reset-password", element: <ResetPasswordPage />, errorElement: <RouteErrorPage /> },
    { path: "/*", element: <Shell jobPageSize={jobPageSize} setJobPageSize={setJobPageSize} jobColumns={jobColumns} setJobColumns={setJobColumns} themeMode={themeMode} onThemeModeChange={onThemeModeChange} accentColor={accentColor} onAccentColorChange={onAccentColorChange} onResetAccentColor={onResetAccentColor} />, errorElement: <RouteErrorPage /> },
  ], { future: { v7_relativeSplatPath: true } }), [jobColumns, jobPageSize, themeMode, accentColor]);

  return (
    <ToastProvider>
      <ConfirmProvider>
        <PromptProvider>
          <CssVarsProvider key={`${effectiveMode}:${accentColor}`} theme={theme as any} defaultMode={effectiveMode} disableTransitionOnChange>
            <CssBaseline enableColorScheme />
            <I18nProvider>
              <RouterProvider router={router} future={{ v7_startTransition: true }} />
            </I18nProvider>
          </CssVarsProvider>
        </PromptProvider>
      </ConfirmProvider>
    </ToastProvider>
  );
}
