import { Link, useRouterState } from "@tanstack/react-router";
import {
  Bell,
  BookOpen,
  Calendar,
  Compass,
  Database,
  FileText,
  Flag,
  Gift,
  Globe,
  GraduationCap,
  Inbox,
  LayoutDashboard,
  Menu,
  Radar,
  ScrollText,
  Send,
  Settings2,
  Shield,
  Trophy,
  Users,
  Waypoints,
  X,
} from "lucide-react";
import { useState, type ReactNode } from "react";
import { CflMark, CflWordmark } from "@/components/cfl-mark";
import { AvatarChip } from "@/components/avatar-chip";
import { RolePreviewBar } from "@/components/role-bar";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import type { AppRole } from "@/lib/identity";
import { ROLE_KICKER } from "@/lib/identity";
import { useRoleStore } from "@/lib/role-store";
import { cn } from "@/lib/utils";

type NavItem = { to: string; label: string; icon: typeof LayoutDashboard; search?: Record<string, string> };

const STAFF_NAV: { label: string; items: NavItem[] }[] = [
  {
    label: "Grant Scout",
    items: [
      { to: "/grant-scout", label: "Live Grant Scout", icon: Radar },
      { to: "/forge-control", label: "Forge Control", icon: Compass },
      { to: "/gamma", label: "Gamma board", icon: Flag },
      { to: "/opportunities", label: "Opportunities", icon: Compass },
      { to: "/foundations", label: "Foundations", icon: Shield },
      { to: "/pipeline", label: "Pipeline", icon: Waypoints },
      { to: "/outreach", label: "What we sent", icon: Send },
      { to: "/review", label: "Review queue", icon: FileText },
      { to: "/donations/inbox", label: "Mailbox", icon: Inbox },
    ],
  },
  {
    label: "Overview",
    items: [
      { to: "/", label: "Dashboard", icon: LayoutDashboard },
      { to: "/admin-hub", label: "Live Admin Hub", icon: Shield },
      { to: "/public", label: "Public site", icon: Globe },
      { to: "/public/stadium", label: "Stadium", icon: Trophy },
    ],
  },
  {
    label: "People",
    items: [{ to: "/admin/users", label: "People", icon: Users }],
  },
  {
    label: "Applications",
    items: [{ to: "/applications", label: "Applications", icon: Inbox }],
  },
  {
    label: "Content",
    items: [
      { to: "/content/projects", label: "Tombstone ads", icon: Flag },
      { to: "/content/scheduler", label: "Social scheduler", icon: Calendar },
    ],
  },
  {
    label: "Apps",
    items: [
      { to: "/capstone", label: "Capstone", icon: GraduationCap },
      { to: "/deal-rooms", label: "Deal rooms", icon: Flag },
      { to: "/admin/stadium", label: "Stadium desk", icon: Trophy },
      { to: "/admin/auction", label: "Auction ledger", icon: Gift },
    ],
  },
  {
    label: "Donations",
    items: [
      { to: "/donations", label: "Activity", icon: Gift },
      { to: "/agreements", label: "Agreements", icon: ScrollText },
    ],
  },
  {
    label: "System",
    items: [
      { to: "/discovery", label: "Catalog search", icon: Radar },
      { to: "/admin/schema", label: "Database", icon: Database },
      { to: "/settings", label: "Org profile", icon: Settings2 },
    ],
  },
];

const STUDENT_NAV: { label: string; items: NavItem[] }[] = [
  {
    label: "My desk",
    items: [
      { to: "/", label: "Dashboard", icon: LayoutDashboard },
      { to: "/learn/courses", label: "Courses", icon: BookOpen },
      { to: "/learn/team", label: "My team", icon: Users },
      { to: "/deal-rooms", label: "Deal rooms", icon: Flag },
      { to: "/public/stadium", label: "Stadium", icon: Trophy },
      { to: "/public/auction", label: "Auction", icon: Gift },
      { to: "/learn/calendar", label: "Game days", icon: Calendar },
      { to: "/public", label: "Public site", icon: Globe },
    ],
  },
];

const INSTRUCTOR_NAV: { label: string; items: NavItem[] }[] = [
  {
    label: "Coach desk",
    items: [
      { to: "/", label: "Dashboard", icon: LayoutDashboard },
      { to: "/coach/roster", label: "Roster", icon: Users },
      { to: "/coach/courses", label: "Courses", icon: BookOpen },
      { to: "/public/stadium", label: "Stadium", icon: Trophy },
      { to: "/coach/review", label: "To review", icon: Flag },
      { to: "/deal-rooms", label: "Deal rooms", icon: Flag },
      { to: "/public", label: "Public site", icon: Globe },
    ],
  },
];

const DONOR_NAV: { label: string; items: NavItem[] }[] = [
  {
    label: "Donor desk",
    items: [
      { to: "/", label: "Dashboard", icon: LayoutDashboard },
      { to: "/donor/projects", label: "Projects", icon: Flag },
      { to: "/deal-rooms", label: "Deal rooms", icon: GraduationCap },
      { to: "/public/stadium", label: "Stadium", icon: Trophy },
      { to: "/public/auction", label: "Auction", icon: Gift },
      { to: "/donor/invites", label: "Game days", icon: Calendar },
      { to: "/public", label: "Public site", icon: Globe },
    ],
  },
];

const PUBLIC_NAV: { label: string; items: NavItem[] }[] = [
  {
    label: "Public site",
    items: [
      { to: "/public", label: "Home", icon: Globe },
      { to: "/public/teams", label: "Teams", icon: Users },
      { to: "/public/stadium", label: "Stadium", icon: Trophy },
      { to: "/public/auction", label: "Auction", icon: Gift },
      { to: "/public/game-days", label: "Game days", icon: Calendar },
      { to: "/market", label: "Market", icon: Flag },
      { to: "/login", label: "Donor login", icon: Gift },
    ],
  },
];

function navFor(role: AppRole) {
  if (role === "student") return STUDENT_NAV;
  if (role === "instructor") return INSTRUCTOR_NAV;
  if (role === "donor") return DONOR_NAV;
  if (role === "public") return PUBLIC_NAV;
  return STAFF_NAV;
}

const CRUMB: Record<string, string> = {
  "/": "Dashboard",
  "/deal-rooms": "Deal rooms",
  "/forge-control": "Forge Control",
  "/admin-hub": "Admin Hub",
  "/gamma": "Gamma board",
  "/opportunities": "Opportunities",
  "/foundations": "Foundations",
  "/pipeline": "Pipeline",
  "/outreach": "What we sent",
  "/review": "Review queue",
  "/donations": "Activity",
  "/donations/inbox": "Inbox",
  "/agreements": "Agreements",
  "/discovery": "Catalog search",
  "/settings": "Org profile",
  "/login": "Sign in",
  "/admin/users": "People",
  "/admin/archived": "People",
  "/admin/members": "People",
  "/admin/privileges": "Org profile",
  "/admin/schema": "Database",
  "/admin/contract": "Database",
  "/applications": "Applications",
  "/content/projects": "Tombstone ads",
  "/content/scheduler": "Social scheduler",
  "/learn/courses": "All courses",
  "/learn/team": "My team",
  "/learn/calendar": "Game days",
  "/coach/courses": "Courses",
  "/coach/roster": "Roster",
  "/coach/review": "To review",
  "/admin/stadium": "Stadium desk",
  "/admin/auction": "Auction ledger",
  "/capstone": "Capstone",
  "/public/stadium": "Stadium",
  "/public/auction": "Auction",
  "/market": "Market",
  "/public": "Public site",
  "/public/teams": "Teams",
  "/public/game-days": "Game days",
  "/donor/projects": "Projects",
  "/donor/invites": "Game Day invites",
};

function crumbFor(pathname: string) {
  if (CRUMB[pathname]) return CRUMB[pathname];
  if (pathname.startsWith("/outreach/")) return "Solicitation";
  if (pathname.startsWith("/opportunities/")) return "Opportunity";
  if (pathname.startsWith("/foundations/")) return "Foundation";
  if (pathname.startsWith("/review/")) return "Draft";
  if (pathname.startsWith("/agreements/")) return "Agreement";
  if (pathname.startsWith("/donations")) return "Donations";
  if (pathname.startsWith("/admin")) return "Admin";
  if (pathname.startsWith("/learn")) return "Student";
  if (pathname.startsWith("/coach")) return "Instructor";
  if (pathname.startsWith("/public/stadium")) return "Stadium";
  if (pathname.startsWith("/public/bios")) return "Bio";
  if (pathname.startsWith("/public/teams")) return "Team";
  if (pathname.startsWith("/public")) return "Public site";
  if (pathname.startsWith("/donor")) return "Donor";
  if (pathname.startsWith("/capstone")) return "Capstone project";
  if (pathname.startsWith("/content")) return "Content";
  return "Capital Forge";
}

function isNavActive(item: NavItem, pathname: string, search: Record<string, unknown>) {
  if (item.to === "/") return pathname === "/";
  if (item.to === "/applications") {
    return pathname === "/applications" || pathname.startsWith("/applications/");
  }
  if (item.to === "/admin/users") {
    return pathname === "/admin/users" || pathname === "/admin/archived" || pathname === "/admin/members";
  }
  if (item.to === "/admin/schema") {
    return pathname === "/admin/schema" || pathname === "/admin/contract";
  }
  if (item.to === "/settings") {
    return pathname === "/settings" || pathname === "/admin/privileges";
  }
  if (item.to === "/public") return pathname === "/public" || pathname === "/public/";
  return pathname === item.to || pathname.startsWith(`${item.to}/`);
}

function NavBody({
  pathname,
  search,
  onNavigate,
  hold,
  unread,
  inboxUnread,
  role,
  name,
  title,
  initials,
  email,
}: {
  pathname: string;
  search: Record<string, unknown>;
  onNavigate?: () => void;
  hold: boolean;
  unread: number;
  inboxUnread: number;
  role: AppRole;
  name: string;
  title: string;
  initials: string;
  email: string;
}) {
  const groups = navFor(role);
  return (
    <div className="flex h-full flex-col">
      <div className="border-b border-sidebar-border px-4 pt-5 pb-4">
        <CflWordmark kicker="League portal" />
        <div className="mt-3 flex items-center gap-2 rounded-lg bg-sidebar-accent px-2.5 py-2">
          <Shield className="size-3.5 text-primary" />
          <span className="text-xs font-medium text-primary">{ROLE_KICKER[role]}</span>
        </div>
      </div>
      <nav className="flex-1 overflow-y-auto px-3 py-4">
        {groups.map((group) => (
          <div key={group.label} className="mb-5">
            <p className="px-2 pb-2 text-[10px] font-medium tracking-[0.18em] text-sidebar-muted uppercase">
              {group.label}
            </p>
            <ul className="flex flex-col gap-0.5">
              {group.items.map((item) => {
                const active = isNavActive(item, pathname, search);
                const Icon = item.icon;
                return (
                  <li key={`${item.to}:${item.label}:${item.search?.kind ?? ""}`}>
                    <Link
                      to={item.to}
                      search={item.search}
                      onClick={onNavigate}
                      className={cn(
                        "flex min-h-11 items-center gap-2.5 rounded-lg px-3 text-sm transition-colors",
                        active
                          ? "bg-primary/15 text-primary"
                          : "text-sidebar-muted hover:bg-sidebar-accent hover:text-sidebar-foreground",
                      )}
                    >
                      <Icon className="size-4 shrink-0" />
                      <span className="flex-1">{item.label}</span>
                      {item.to === "/review" && unread > 0 ? (
                        <span className="rounded-full bg-primary/20 px-1.5 text-[10px] tabular text-primary">
                          {unread}
                        </span>
                      ) : null}
                      {item.to === "/donations/inbox" && inboxUnread > 0 ? (
                        <span className="rounded-full bg-primary/20 px-1.5 text-[10px] tabular text-primary">
                          {inboxUnread}
                        </span>
                      ) : null}
                    </Link>
                  </li>
                );
              })}
            </ul>
          </div>
        ))}
      </nav>
      <div className="border-t border-sidebar-border px-4 py-4">
        {role === "staff" ? (
          <div className="mb-4 flex items-center justify-between gap-2">
            <div>
              <p className="text-[11px] tracking-wide text-sidebar-muted uppercase">Solicitation hold</p>
              <p className="text-sm text-sidebar-foreground">{hold ? "On — letter pending" : "Off — sending live"}</p>
            </div>
            <span className={cn("size-2 rounded-full", hold ? "bg-warning" : "bg-live")} />
          </div>
        ) : null}
        <div className="flex items-center gap-2.5">
          <AvatarChip email={email} initials={initials} />
          <div className="min-w-0">
            <p className="truncate text-sm font-medium leading-none">{name}</p>
            <p className="mt-0.5 truncate text-[11px] text-sidebar-muted">{title}</p>
          </div>
        </div>
      </div>
    </div>
  );
}

export function AppShell({
  children,
  hold = true,
  unread = 0,
  noticeCount = 0,
  inboxUnread = 0,
}: {
  children: ReactNode;
  hold?: boolean;
  unread?: number;
  noticeCount?: number;
  inboxUnread?: number;
}) {
  const pathname = useRouterState({ select: (s) => s.location.pathname });
  const search = useRouterState({ select: (s) => s.location.search as Record<string, unknown> });
  const [open, setOpen] = useState(false);
  const page = crumbFor(pathname);
  const account = useRoleStore((s) => s.account());
  const role = useRoleStore((s) => s.role);

  return (
    <div className="min-h-dvh bg-background">
      <RolePreviewBar />
      <aside data-on-navy className="fixed inset-y-0 left-0 top-11 z-30 hidden w-[248px] border-r border-sidebar-border bg-sidebar lg:block">
        <NavBody
          pathname={pathname}
          search={search}
          hold={hold}
          unread={unread}
          inboxUnread={inboxUnread}
          role={role}
          name={account.name}
          title={account.title}
          initials={account.initials}
          email={account.email}
        />
      </aside>

      {open ? (
        <div className="fixed inset-0 top-11 z-40 lg:hidden">
          <button
            className="absolute inset-0 bg-background/70"
            aria-label="Close menu"
            onClick={() => setOpen(false)}
          />
          <aside data-on-navy className="absolute inset-y-0 left-0 w-[min(20rem,86vw)] border-r border-sidebar-border bg-sidebar shadow-xl">
            <button
              className="absolute top-4 right-4 rounded-md p-2 text-sidebar-muted hover:text-sidebar-foreground"
              onClick={() => setOpen(false)}
              aria-label="Close"
            >
              <X className="size-5" />
            </button>
            <NavBody
              pathname={pathname}
              search={search}
              hold={hold}
              unread={unread}
              inboxUnread={inboxUnread}
              onNavigate={() => setOpen(false)}
              role={role}
              name={account.name}
              title={account.title}
              initials={account.initials}
              email={account.email}
            />
          </aside>
        </div>
      ) : null}

      <div className="pt-11 lg:pl-[248px]">
        <header className="sticky top-11 z-20 flex h-14 items-center gap-3 border-b border-border bg-background/90 px-4 backdrop-blur-sm sm:px-6">
          <Link to="/" className="shrink-0" aria-label="Capital Forge League home">
            <CflMark variant="header" />
          </Link>
          <Button
            variant="ghost"
            size="icon-sm"
            className="lg:hidden"
            onClick={() => setOpen(true)}
            aria-label="Open menu"
          >
            <Menu className="size-5" />
          </Button>
          <p className="min-w-0 truncate text-sm text-muted-foreground">
            <span className="text-muted-foreground/70">{ROLE_KICKER[role]}</span>
            <span className="mx-1.5 text-muted-foreground/40">/</span>
            <span className="text-foreground">{page}</span>
          </p>
          <div className="ml-auto flex items-center gap-3">
            <Badge variant="live" className="hidden sm:inline-flex">
              Live
            </Badge>
            {role === "staff" ? (
              <Link
                to="/discovery"
                className="relative flex size-10 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground"
                aria-label="Alerts"
              >
                <Bell className="size-4" />
                {noticeCount > 0 ? (
                  <span className="absolute top-1.5 right-1.5 size-1.5 rounded-full bg-destructive" />
                ) : null}
              </Link>
            ) : null}
            <AvatarChip email={account.email} initials={account.initials} name={account.name} size="sm" showName />
          </div>
        </header>
        <main className="overflow-x-hidden px-4 py-6 sm:px-6 lg:px-8">{children}</main>
      </div>
    </div>
  );
}

export function PageHeader({
  kicker,
  title,
  description,
  actions,
}: {
  kicker?: string;
  title: string;
  description?: string;
  actions?: ReactNode;
}) {
  return (
    <div className="mb-6 flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
      <div className="min-w-0">
        {kicker ? (
          <p className="mb-1 text-[11px] font-medium tracking-[0.18em] text-primary uppercase">{kicker}</p>
        ) : null}
        <h1 className="font-display text-3xl font-semibold sm:text-4xl">{title}</h1>
        {description ? (
          <p className="mt-2 max-w-2xl text-sm text-foreground/85 sm:text-base">{description}</p>
        ) : null}
      </div>
      {actions ? <div className="flex flex-wrap items-center gap-2">{actions}</div> : null}
    </div>
  );
}
