import { useEffect, useState } from "react"

const SIDEBAR_KEY = "crema.shell.sidebar"
import { NavLink, useNavigate } from "react-router"
import {
  Bell,
  LayoutDashboard,
  Boxes,
  Activity,
  Sparkles,
  BookOpen,
  Settings,
  Search,
  PanelLeftClose,
  PanelLeftOpen,
  User as UserIcon,
  LogOut,
  HelpCircle,
  Menu,
  Play,
  // CREMA:NAV-ICONS
} from "lucide-react"

import {
  useBrand,
  useUser,
  type Brand,
  type User,
} from "~/lib/identity"

import {
  Appbar,
  AppbarActions,
  AppbarSpacer,
  AppbarTitle,
} from "~/components/layout/appbar"
import { ThemeToggle } from "~/components/layout/theme-toggle"
import { BackgroundPicker } from "~/components/layout/background-picker"
import { FontSizePicker } from "~/components/layout/font-size-picker"
import { SurfacePicker } from "~/components/layout/surface-picker"
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar"
import { profileInitials, useProfile } from "~/lib/profile"
import { Button } from "~/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu"
import { Input } from "~/components/ui/input"
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "~/components/ui/sheet"
import { ScriptsDialog, useScriptsHotkey } from "~/components/scripts-dialog"

type NavItem = {
  to: string
  icon: React.ComponentType<{ className?: string }>
  label: string
  end?: boolean
}

const navItems: NavItem[] = [
  { to: "/", icon: LayoutDashboard, label: "Overview", end: true },
  { to: "/resources", icon: Boxes, label: "Resources" },
  { to: "/activity", icon: Activity, label: "Activity" },
  { to: "/assistant", icon: Sparkles, label: "Assistant" },
  { to: "/library", icon: BookOpen, label: "Library" },
  { to: "/settings", icon: Settings, label: "Settings" },
  // CREMA:NAV-ITEMS
]

type AppShellProps = {
  title: string
  children: React.ReactNode
  brand?: Brand
  user?: User
  /**
   * Optional theme name. When set, the shell wraps itself in
   * `data-theme={theme}` so a route can opt into an alternate theme without
   * the caller having to add an extra wrapping div.
   */
  theme?: string
}

export function AppShell({
  title,
  children,
  brand: brandOverride,
  user: userOverride,
  theme,
}: AppShellProps) {
  const defaultBrand = useBrand()
  const defaultUser = useUser()
  const profile = useProfile()
  const brand = brandOverride ?? defaultBrand
  const user = userOverride ?? {
    name: profile.name || defaultUser.name,
    email: profile.email || defaultUser.email,
    initials: profileInitials(profile.name || defaultUser.name),
  }
  const [expanded, setExpanded] = useState<boolean>(() => {
    if (typeof window === "undefined") return false
    return localStorage.getItem(SIDEBAR_KEY) === "1"
  })
  useEffect(() => {
    localStorage.setItem(SIDEBAR_KEY, expanded ? "1" : "0")
  }, [expanded])
  const [mobileOpen, setMobileOpen] = useState(false)
  const [scriptsOpen, setScriptsOpen] = useState(false)
  const navigate = useNavigate()
  const BrandIcon = brand.icon

  useScriptsHotkey(() => setScriptsOpen(true))

  return (
    <div
      data-theme={theme}
      className="relative isolate flex min-h-svh"
    >
      <a
        href="#main-content"
        className="sr-only focus:not-sr-only focus:fixed focus:left-2 focus:top-2 focus:z-50 focus:rounded-md focus:bg-primary focus:px-3 focus:py-2 focus:text-primary-foreground focus:shadow-lg"
      >
        Skip to main content
      </a>
      <aside
        data-slot="sidebar"
        data-expanded={expanded ? "true" : "false"}
        className={[
          "sticky top-0 z-30 hidden h-svh shrink-0 flex-col border-r bg-sidebar transition-[width] duration-base ease-standard md:flex",
          expanded ? "w-60" : "w-16",
        ].join(" ")}
      >
        <div
          className={[
            "flex h-14 items-center gap-2 border-b px-3",
            expanded ? "justify-between" : "justify-center",
          ].join(" ")}
        >
          {expanded ? (
            <div className="flex items-center gap-2">
              <div className="flex size-8 items-center justify-center rounded-lg bg-primary text-primary-foreground">
                <BrandIcon className="size-4" />
              </div>
              <span className="font-heading font-semibold tracking-tight">
                {brand.name}
              </span>
            </div>
          ) : (
            <div className="flex size-8 items-center justify-center rounded-lg bg-primary text-primary-foreground">
              <BrandIcon className="size-4" />
            </div>
          )}
        </div>

        <nav className="flex min-h-0 flex-1 flex-col gap-1 overflow-y-auto p-2">
          {navItems.map((item) => {
            const Icon = item.icon
            return (
              <NavLink
                key={item.label}
                to={item.to}
                end={item.end}
                title={expanded ? undefined : item.label}
                data-action={`nav-${item.label.toLowerCase()}`}
                className={({ isActive }) =>
                  [
                    "flex items-center gap-3 rounded-lg px-3 py-2 font-medium transition-colors duration-fast ease-standard",
                    expanded ? "justify-start" : "justify-center",
                    isActive
                      ? "bg-primary/10 text-primary"
                      : "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
                  ].join(" ")
                }
              >
                <Icon className="size-5 shrink-0" />
                {expanded && <span className="truncate">{item.label}</span>}
              </NavLink>
            )
          })}
        </nav>

        <div className="shrink-0 border-t p-2">
          <Button
            data-action="sidebar-toggle"
            variant="ghost"
            size={expanded ? "sm" : "icon-sm"}
            onClick={() => setExpanded((v) => !v)}
            aria-label={expanded ? "Collapse sidebar" : "Expand sidebar"}
            className={expanded ? "w-full justify-start" : "w-full"}
          >
            {expanded ? (
              <>
                <PanelLeftClose className="size-4" />
                <span>Collapse</span>
              </>
            ) : (
              <PanelLeftOpen className="size-4" />
            )}
          </Button>
        </div>
      </aside>

      <main className="flex min-w-0 flex-1 flex-col">
        <Appbar className="sticky top-0 z-20 border-b">
          <Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
            <SheetTrigger
              data-action="mobile-nav-toggle"
              aria-label="Open navigation"
              className="mr-1 inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-accent-foreground md:hidden"
            >
              <Menu className="size-5" />
            </SheetTrigger>
            <SheetContent side="left" className="w-72 p-0">
              <SheetHeader className="border-b">
                <SheetTitle className="flex items-center gap-2">
                  <div className="flex size-7 items-center justify-center rounded-lg bg-primary text-primary-foreground">
                    <BrandIcon className="size-4" />
                  </div>
                  {brand.name}
                </SheetTitle>
              </SheetHeader>
              <nav className="flex flex-col gap-1 p-2">
                {navItems.map((item) => {
                  const Icon = item.icon
                  return (
                    <NavLink
                      key={item.label}
                      to={item.to}
                      end={item.end}
                      onClick={() => setMobileOpen(false)}
                      data-action={`nav-mobile-${item.label.toLowerCase()}`}
                      className={({ isActive }) =>
                        [
                          "flex items-center gap-3 rounded-lg px-3 py-2 font-medium transition-colors",
                          isActive
                            ? "bg-primary/10 text-primary"
                            : "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
                        ].join(" ")
                      }
                    >
                      <Icon className="size-5 shrink-0" />
                      <span>{item.label}</span>
                    </NavLink>
                  )
                })}
              </nav>
            </SheetContent>
          </Sheet>
          <AppbarTitle>{title}</AppbarTitle>
          <div className="relative ml-6 hidden md:block">
            <Search className="pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              data-action="appbar-search"
              placeholder="Search…"
              className="h-9 w-80 pl-8"
            />
          </div>
          <AppbarSpacer />
          <AppbarActions>
            <Button
              data-action="appbar-scripts"
              variant="ghost"
              size="icon-sm"
              aria-label="Run script (Cmd+Shift+P)"
              title="Run script (Cmd+Shift+P)"
              onClick={() => setScriptsOpen(true)}
            >
              <Play />
            </Button>
            <FontSizePicker />
            <SurfacePicker />
            <BackgroundPicker />
            <ThemeToggle />
            <Button
              data-action="appbar-notifications"
              variant="ghost"
              size="icon-sm"
              aria-label="Notifications"
            >
              <Bell />
            </Button>
            <DropdownMenu>
              <DropdownMenuTrigger
                data-action="appbar-avatar"
                aria-label="Account menu"
                className="rounded-full outline-none ring-offset-2 ring-offset-background transition-opacity hover:opacity-80 focus-visible:ring-2 focus-visible:ring-ring"
              >
                <Avatar className="size-8 cursor-pointer">
                  {profile.avatarUrl ? (
                    <AvatarImage src={profile.avatarUrl} alt={user.name} />
                  ) : null}
                  <AvatarFallback>{user.initials}</AvatarFallback>
                </Avatar>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end" sideOffset={8} className="w-56">
                <DropdownMenuGroup>
                  <DropdownMenuLabel className="flex flex-col gap-0.5">
                    <span className="font-medium">{user.name}</span>
                    <span className="text-xs font-normal text-muted-foreground">
                      {user.email}
                    </span>
                  </DropdownMenuLabel>
                </DropdownMenuGroup>
                <DropdownMenuSeparator />
                <DropdownMenuItem
                  data-action="avatar-profile"
                  onClick={() => navigate("/profile")}
                >
                  <UserIcon /> Profile
                </DropdownMenuItem>
                <DropdownMenuItem
                  data-action="avatar-settings"
                  onClick={() => navigate("/settings")}
                >
                  <Settings /> Settings
                </DropdownMenuItem>
                <DropdownMenuItem data-action="avatar-help">
                  <HelpCircle /> Help
                </DropdownMenuItem>
                <DropdownMenuSeparator />
                <DropdownMenuItem data-action="avatar-signout" variant="destructive">
                  <LogOut /> Sign out
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </AppbarActions>
        </Appbar>

        <div
          id="main-content"
          tabIndex={-1}
          className="flex flex-1 flex-col gap-6 p-6 focus:outline-none"
        >
          {children}
        </div>
      </main>

      <ScriptsDialog open={scriptsOpen} onOpenChange={setScriptsOpen} />
    </div>
  )
}
