import { AppShell, Box } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { type ReactNode, useEffect, useState } from "react";

import FreightDashboardHeader from "./FreightDashboardHeader";
import FreightSidebar from "./FreightSidebar";
import { getPageMeta } from "./route-meta";
import type { SidebarSection } from "./types";

type Theme = "light" | "dark";
const THEME_STORAGE_KEY = "edr-theme";
const HEADER_HEIGHT = 64;
const NAVBAR_WIDTH = 280;

function getInitialTheme(): Theme {
  if (typeof window === "undefined") return "light";
  const stored = window.localStorage.getItem(THEME_STORAGE_KEY);
  if (stored === "dark" || stored === "light") return stored;
  return window.matchMedia?.("(prefers-color-scheme: dark)").matches
    ? "dark"
    : "light";
}

export interface FreightDashboardLayoutProps {
  sidebarSections: SidebarSection[];
  /** Render the shell with no navbar at all (used by GL clearance-only users). */
  hideSidebar?: boolean;
  activeHref?: string;
  onNavigate?: (href: string) => void;
  headerRight?: ReactNode;
  enableThemeToggle?: boolean;
  userName?: string;
  userEmail?: string;
  userInitials?: string;
  onLogout?: () => void;
  children: ReactNode;
}

const FreightDashboardLayout = ({
  sidebarSections,
  hideSidebar = false,
  activeHref = "",
  onNavigate,
  headerRight,
  enableThemeToggle = false,
  userName,
  userEmail,
  userInitials,
  onLogout,
  children,
}: FreightDashboardLayoutProps) => {
  const pageMeta = getPageMeta(activeHref);
  const [mobileOpened, { toggle: toggleMobile, close: closeMobile }] =
    useDisclosure(false);

  const [theme, setTheme] = useState<Theme>(() =>
    enableThemeToggle ? getInitialTheme() : "light",
  );

  useEffect(() => {
    if (!enableThemeToggle) return;
    const root = document.documentElement;
    root.classList.toggle("dark", theme === "dark");
    window.localStorage.setItem(THEME_STORAGE_KEY, theme);
  }, [theme, enableThemeToggle]);

  const toggleTheme = () =>
    setTheme((current) => (current === "dark" ? "light" : "dark"));

  const navigate = (href: string) => {
    closeMobile();
    onNavigate?.(href);
  };

  return (
    <AppShell
      layout="alt"
      padding={0}
      className="bg-edr-bg"
      header={{ height: HEADER_HEIGHT }}
      // When the sidebar is hidden the navbar slot is dropped entirely so Main
      // spans the full viewport width (GL clearance-only users).
      navbar={
        hideSidebar
          ? undefined
          : {
              width: NAVBAR_WIDTH,
              breakpoint: "sm",
              collapsed: { mobile: !mobileOpened },
            }
      }
    >
      <FreightDashboardHeader
        pageMeta={pageMeta}
        headerRight={headerRight}
        enableThemeToggle={enableThemeToggle}
        userName={userName}
        userEmail={userEmail}
        userInitials={userInitials}
        onLogout={onLogout}
        theme={theme}
        onToggleTheme={toggleTheme}
        mobileOpened={mobileOpened}
        onToggleMobile={toggleMobile}
        hideSidebarBurger={hideSidebar}
      />

      {!hideSidebar && (
        <FreightSidebar
          sections={sidebarSections}
          activeHref={activeHref}
          onNavigate={navigate}
          onClose={closeMobile}
        />
      )}

      <AppShell.Main>
        {/* Internal scroll keeps the fixed-viewport model the dashboard pages
            assume (sidebar + header stay put, content scrolls beneath). */}
        <Box
          className="overflow-y-auto bg-edr-bg"
          style={{ height: `calc(100dvh - ${HEADER_HEIGHT}px)` }}
        >
          {children}
        </Box>
      </AppShell.Main>
    </AppShell>
  );
};

export default FreightDashboardLayout;
