"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState, type ReactNode } from "react";
import {
  Activity, AlertTriangle, BarChart3, Bell, BookOpen, Building2, Calendar, DatabaseBackup, Eye, FileText,
  Globe, HardDrive, History, Image as ImageIcon, Inbox, Layers, Palette, LayoutDashboard, Library, Lock, Menu, Mic, Plug,
  BadgeCheck, ChevronRight, Handshake, Puzzle, Rocket, ScrollText, Search, Settings, Shield, Store, Tags, Ticket, User, Users, Wrench, X,
  type LucideIcon,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { publicHref, type DashKind } from "@/lib/dashboard-urls";
import type { IconName, NavItem } from "./nav-config";

const ICONS: Record<IconName, LucideIcon> = {
  "layout-dashboard": LayoutDashboard, building: Building2, globe: Globe, users: Users, shield: Shield,
  settings: Settings, puzzle: Puzzle, "hard-drive": HardDrive, "scroll-text": ScrollText, wrench: Wrench,
  plug: Plug, activity: Activity, "database-backup": DatabaseBackup, lock: Lock, "file-text": FileText,
  menu: Menu, library: Library, image: ImageIcon, calendar: Calendar, inbox: Inbox, search: Search,
  "bar-chart": BarChart3, history: History, ticket: Ticket, "alert-triangle": AlertTriangle, rocket: Rocket,
  "book-open": BookOpen, bell: Bell, user: User, mic: Mic, store: Store, eye: Eye, layers: Layers, palette: Palette, tags: Tags, "badge-check": BadgeCheck, handshake: Handshake,
};

function NavList({ items, kind, onNavigate }: { items: NavItem[]; kind: DashKind; onNavigate: () => void }) {
  const pathname = usePathname();
  const [closed, setClosed] = useState<Record<string, boolean>>({});
  const hrefOf = (i: NavItem) => i.href ?? publicHref(kind, i.path);
  // Only the most specific matching item is highlighted (e.g. /libraries/speakers beats /libraries, /reports/uptime beats /reports).
  const flat = items.flatMap((i) => [i, ...(i.children ?? [])]);
  const matches = flat.filter((i) => i.path !== "" && (pathname === hrefOf(i) || pathname.startsWith(`${hrefOf(i)}/`)));
  const best = matches.reduce<NavItem | null>((a, i) => (a && hrefOf(a).length > hrefOf(i).length ? a : i), null);
  const link = (item: NavItem, nested: boolean) => {
    const Icon = ICONS[item.icon];
    const href = hrefOf(item);
    const active = item.path === "" ? pathname === href : best === item;
    return (
      <Link
        href={href}
        onClick={onNavigate}
        aria-current={active ? "page" : undefined}
        className={cn(
          "flex min-w-0 flex-1 items-center gap-3 rounded-md px-2.5 py-2 text-sm font-semibold",
          nested && "py-1.5 pl-10 font-medium",
          active ? "bg-white/15 text-white" : "text-white/85 hover:bg-white/10 hover:text-white",
        )}
      >
        {nested ? null : <Icon className="size-4 shrink-0" aria-hidden />}
        <span className="truncate">{item.label}</span>
      </Link>
    );
  };
  return (
    <ul className="space-y-0.5">
      {items.map((item) => {
        const Icon = ICONS[item.icon];
        const content = (
          <>
            <Icon className="size-4 shrink-0" aria-hidden />
            <span className="truncate">{item.label}</span>
            {!item.ready ? <span className="ml-auto rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground">Soon</span> : null}
          </>
        );
        if (item.children?.length && item.ready) {
          const inside = pathname === hrefOf(item) || pathname.startsWith(`${hrefOf(item)}/`);
          const open = closed[item.label] === undefined ? inside : !closed[item.label];
          return (
            <li key={item.label}>
              <div className="flex items-center">
                {link(item, false)}
                <button type="button" aria-expanded={open} aria-label={`${open ? "Collapse" : "Expand"} ${item.label}`} onClick={() => setClosed((c) => ({ ...c, [item.label]: open }))} className="grid size-7 shrink-0 place-items-center rounded-md text-white/70 hover:bg-white/10">
                  <ChevronRight className={cn("size-4 transition-transform", open && "rotate-90")} aria-hidden />
                </button>
              </div>
              {open ? <ul className="mt-0.5 space-y-0.5 pb-1">{item.children.map((c) => <li key={c.label}>{link(c, true)}</li>)}</ul> : null}
            </li>
          );
        }
        return (
          <li key={item.label}>
            {item.ready ? link(item, false) : (
              <span aria-disabled className="flex cursor-not-allowed items-center gap-2.5 rounded-md px-2.5 py-1.5 text-sm text-white/50">
                {content}
              </span>
            )}
          </li>
        );
      })}
    </ul>
  );
}

export interface NavGroup { heading?: string; kind: DashKind; items: NavItem[] }

export function ShellFrame({
  groups,
  roleLabel,
  topbar,
  children,
}: {
  groups: NavGroup[];
  roleLabel: string;
  topbar: ReactNode;
  children: ReactNode;
}) {
  const [open, setOpen] = useState(false);
  const close = () => setOpen(false);

  const sidebar = (
    <nav aria-label={`${roleLabel} navigation`} className="flex h-full flex-col gap-4 overflow-y-auto p-3">
      <div className="px-2.5 pt-1">
        <p className="text-base font-bold tracking-tight text-white">{roleLabel}</p>
      </div>
      {groups.map((g, i) => (
        <div key={g.kind}>
          {g.heading ? <p id={`nav-group-${i}`} className="mb-1 px-2.5 text-[11px] font-semibold uppercase tracking-wide text-white/60">{g.heading}</p> : null}
          <NavList items={g.items} kind={g.kind} onNavigate={close} />
        </div>
      ))}
    </nav>
  );

  return (
    <div className="min-h-screen lg:grid lg:grid-cols-[16rem_1fr]">
      <aside className="sticky top-0 hidden h-screen border-r border-white/10 bg-[#263545] lg:block">{sidebar}</aside>

      {open ? (
        <div className="fixed inset-0 z-40 lg:hidden" role="dialog" aria-modal="true" aria-label="Navigation">
          <button aria-label="Close navigation" className="absolute inset-0 bg-black/40" onClick={close} />
          <aside className="relative h-full w-64 border-r border-white/10 bg-[#263545]">
            <button aria-label="Close navigation" onClick={close} className="absolute right-2 top-2 rounded-md p-1.5 text-white hover:bg-white/10">
              <X className="size-4" />
            </button>
            {sidebar}
          </aside>
        </div>
      ) : null}

      <div className="min-w-0">
        <header className="sticky top-0 z-30 flex h-14 items-center gap-3 border-b border-border bg-card/90 px-4 backdrop-blur">
          <button aria-label="Open navigation" onClick={() => setOpen(true)} className="rounded-md p-1.5 hover:bg-muted lg:hidden">
            <Menu className="size-5" />
          </button>
          <div className="flex min-w-0 flex-1 items-center justify-end gap-3">{topbar}</div>
        </header>
        <main id="main" className="mx-auto w-full max-w-6xl p-4 sm:p-6">
          {children}
        </main>
      </div>
    </div>
  );
}
