import { LogOut, Menu, PanelLeftClose, PanelLeftOpen } from 'lucide-react';

import type { PropsWithChildren, ReactNode } from 'react';

import { Link, usePage } from '@inertiajs/react';

import { ImpersonationBanner } from '@/Components/admin/ImpersonationBanner';
import { Logo, TextLogo } from '@/Components/branding/Logo';
import { CommandPalette, useCommandPalette } from '@/Components/command-palette';
import { NotificationDropdown } from '@/Components/notifications/NotificationDropdown';
import { ThemeToggle } from '@/Components/theme';
import { Avatar, AvatarFallback } from '@/Components/ui/avatar';
import { Button } from '@/Components/ui/button';
import { ScrollArea } from '@/Components/ui/scroll-area';
import { Separator } from '@/Components/ui/separator';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from '@/Components/ui/sheet';
import { TooltipProvider } from '@/Components/ui/tooltip';
import type { AdminNavGroup } from '@/config/admin-navigation';
import { getVisibleGroups } from '@/config/navigation';
import type { NavGroup } from '@/config/navigation';
import type { PageProps } from '@/types';

import { SidebarProvider, useSidebar } from './sidebar-context';
import { MobileSidebarNav, SidebarNavGroup } from './sidebar-nav';

interface SidebarLayoutProps extends PropsWithChildren {
  navigationGroups?: NavGroup[] | AdminNavGroup[];
  logoHref?: string;
  headerExtra?: ReactNode;
  footerExtra?: ReactNode;
  banner?: ReactNode;
  siteSection?: ReactNode;
  mobileSiteSection?: ReactNode;
  navTopContent?: ReactNode;
  groupCollapsedState?: Record<string, boolean>;
  onGroupToggle?: (label: string) => void;
}

function SidebarInner({
  children,
  navigationGroups,
  logoHref = '/dashboard',
  headerExtra,
  footerExtra,
  banner,
  siteSection,
  mobileSiteSection,
  navTopContent,
  groupCollapsedState,
  onGroupToggle,
}: SidebarLayoutProps) {
  const { auth, features } = usePage<PageProps>().props;
  const { collapsed, toggleCollapsed, mobileOpen, setMobileOpen } = useSidebar();
  const { open: commandPaletteOpen, setOpen: setCommandPaletteOpen } = useCommandPalette();

  const visibleGroups = navigationGroups ?? getVisibleGroups(features);

  return (
    <div className="flex min-h-screen">
      <a
        href="#main-content"
        className="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-50 focus:px-4 focus:py-2 focus:bg-background focus:rounded focus:ring-2 focus:ring-ring"
      >
        Skip to main content
      </a>
      {/* Desktop Sidebar */}
      <aside
        aria-label="Main navigation"
        className={`hidden md:flex flex-col border-r border-sidebar-border bg-sidebar transition-[width] duration-200 ${
          collapsed ? 'w-12' : 'w-60'
        }`}
      >
        {/* Sidebar Header */}
        <div className="flex h-16 items-center justify-between border-b border-sidebar-border px-3">
          <Link href={logoHref} className="flex items-center gap-2 overflow-hidden">
            <Logo className="h-6 w-6 shrink-0" />
            {!collapsed && <TextLogo className="text-sm" />}
            {!collapsed && headerExtra}
          </Link>
          <Button
            variant="ghost"
            size="icon"
            className="h-7 w-7 shrink-0 text-sidebar-foreground/60 hover:text-sidebar-foreground"
            onClick={toggleCollapsed}
            aria-expanded={!collapsed}
            aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
          >
            {collapsed ? (
              <PanelLeftOpen className="h-4 w-4" />
            ) : (
              <PanelLeftClose className="h-4 w-4" />
            )}
          </Button>
        </div>

        {/* Site Section */}
        {siteSection}

        {/* Nav Top Content (e.g. search input) */}
        {navTopContent && !collapsed && <div className="px-3 pt-2">{navTopContent}</div>}

        {/* Nav Groups */}
        <ScrollArea className="flex-1 py-2">
          <TooltipProvider delayDuration={0}>
            {visibleGroups.map((group) => (
              <SidebarNavGroup
                key={group.label}
                group={group}
                collapsed={collapsed}
                isGroupCollapsed={groupCollapsedState?.[group.label] ?? false}
                onGroupToggle={onGroupToggle ? () => onGroupToggle(group.label) : undefined}
              />
            ))}
          </TooltipProvider>
        </ScrollArea>

        <Separator className="bg-sidebar-border" />

        {/* Sidebar Footer */}
        <div className="flex flex-col gap-2 p-3">
          {features.notifications && <NotificationDropdown />}
          {!collapsed && (
            <button
              type="button"
              onClick={() => setCommandPaletteOpen(true)}
              className="flex w-full items-center justify-between rounded-md border border-sidebar-border bg-sidebar-accent/30 px-2 py-1.5 text-xs text-sidebar-foreground/60 hover:bg-sidebar-accent hover:text-sidebar-foreground transition-colors"
              aria-label="Open command palette"
            >
              <span>Search…</span>
              <kbd className="hidden lg:inline-flex h-5 items-center gap-1 rounded border bg-muted px-1.5 text-xs font-medium text-muted-foreground">
                <span className="text-xs">⌘</span>K
              </kbd>
            </button>
          )}
          <ThemeToggle />
          {footerExtra}
          <div
            className={`flex items-center gap-2 overflow-hidden ${collapsed ? 'justify-center' : ''}`}
          >
            <Avatar className="h-7 w-7 shrink-0">
              <AvatarFallback className="bg-sidebar-primary/10 text-sidebar-primary text-xs font-medium">
                {auth.user?.name.slice(0, 2).toUpperCase()}
              </AvatarFallback>
            </Avatar>
            {!collapsed && (
              <div className="flex-1 overflow-hidden">
                <p className="truncate text-xs font-medium text-sidebar-foreground">
                  {auth.user?.name}
                </p>
                <p className="truncate text-xs text-sidebar-foreground/60">{auth.user?.email}</p>
              </div>
            )}
          </div>
          <Button
            variant="ghost"
            size="sm"
            className="w-full justify-start text-sidebar-foreground/60 hover:text-destructive"
            asChild
          >
            <Link href={route('logout')} method="post" as="button" className="w-full">
              <LogOut className="mr-2 h-4 w-4" />
              {!collapsed && 'Log out'}
            </Link>
          </Button>
        </div>
      </aside>

      {/* Mobile Sidebar (Sheet) */}
      <Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
        <SheetContent side="left" className="w-72 bg-sidebar p-0">
          <SheetHeader className="border-b border-sidebar-border px-4 py-4">
            <SheetTitle className="flex items-center gap-2">
              <Logo className="h-6 w-6" />
              <TextLogo className="text-sm" />
              {headerExtra}
            </SheetTitle>
            <SheetDescription className="sr-only">Navigation menu</SheetDescription>
          </SheetHeader>
          <ScrollArea className="flex-1">
            {mobileSiteSection}
            <MobileSidebarNav groups={visibleGroups} onNavigate={() => setMobileOpen(false)} />
          </ScrollArea>
          <div className="flex flex-col gap-2 border-t border-sidebar-border p-3">
            <div className="flex items-center gap-2">
              <Avatar className="h-7 w-7 shrink-0">
                <AvatarFallback className="bg-sidebar-primary/10 text-sidebar-primary text-xs font-medium">
                  {auth.user?.name.slice(0, 2).toUpperCase()}
                </AvatarFallback>
              </Avatar>
              <div className="flex-1 overflow-hidden">
                <p className="truncate text-xs font-medium text-sidebar-foreground">
                  {auth.user?.name}
                </p>
              </div>
            </div>
            {footerExtra}
            <ThemeToggle />
            <Button
              variant="ghost"
              size="sm"
              className="w-full justify-start text-sidebar-foreground/60 hover:text-destructive"
              asChild
            >
              <Link href={route('logout')} method="post" as="button" className="w-full">
                <LogOut className="mr-2 h-4 w-4" />
                Log out
              </Link>
            </Button>
          </div>
        </SheetContent>
      </Sheet>

      {/* Main Content */}
      <div className="flex flex-1 flex-col">
        {/* Mobile Header */}
        <header className="flex h-14 items-center border-b bg-background px-4 md:hidden">
          <Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
            <SheetTrigger asChild>
              <Button
                variant="ghost"
                size="icon"
                className="mr-2"
                aria-label="Toggle navigation menu"
              >
                <Menu className="h-5 w-5" />
              </Button>
            </SheetTrigger>
          </Sheet>
          <Link href={logoHref} className="flex items-center gap-2">
            <Logo className="h-6 w-6" />
            <TextLogo className="text-sm" />
          </Link>
        </header>

        <ImpersonationBanner />
        {banner}

        <main id="main-content" className="flex-1">
          {children}
        </main>
      </div>

      <CommandPalette open={commandPaletteOpen} onOpenChange={setCommandPaletteOpen} />
    </div>
  );
}

export default function SidebarLayout({
  children,
  navigationGroups,
  logoHref,
  headerExtra,
  footerExtra,
  banner,
  siteSection,
  mobileSiteSection,
  navTopContent,
  groupCollapsedState,
  onGroupToggle,
}: SidebarLayoutProps) {
  return (
    <SidebarProvider>
      <SidebarInner
        navigationGroups={navigationGroups}
        logoHref={logoHref}
        headerExtra={headerExtra}
        footerExtra={footerExtra}
        banner={banner}
        siteSection={siteSection}
        mobileSiteSection={mobileSiteSection}
        navTopContent={navTopContent}
        groupCollapsedState={groupCollapsedState}
        onGroupToggle={onGroupToggle}
      >
        {children}
      </SidebarInner>
    </SidebarProvider>
  );
}
