"use client";

import { useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import Link from "next/link";
import { INVENTORY_ENABLED, SUBMITTER_VIEW_ALL_ENABLED, CREWING_ENABLED } from "@/lib/feature-flags";
import { cn } from "@/lib/utils";
import {
  LayoutDashboard,
  FileText,
  Plus,
  CheckSquare,
  CreditCard,
  History,
  Receipt,
  Users,
  Ship,
  Building2,
  Briefcase,
  Store,
  Anchor,
  Package,
  Upload,
  MapPin,
  ShoppingCart,
  UserCircle,
  ShieldCheck,
  Network,
  ClipboardList,
  UserSearch,
  Contact,
  CalendarDays,
  CalendarCheck,
  UserCog,
  Gauge,
  BadgeCheck,
  Truck,
  ScrollText,
  ChevronRight,
} from "lucide-react";
import type { Role } from "@prisma/client";

interface NavItem {
  href: string;
  label: string;
  icon: React.ElementType;
  roles?: Role[];
}

// History is open to all-PO viewers; when the submitter-view-all flag is on, submitters
// (TECHNICAL / MANNING) get read+export access to it too.
const HISTORY_ROLES: Role[] = [
  "MANAGER", "SUPERUSER", "AUDITOR", "ADMIN",
  ...(SUBMITTER_VIEW_ALL_ENABLED ? (["TECHNICAL", "MANNING"] as Role[]) : []),
];

const NAV_ITEMS: NavItem[] = [
  { href: "/dashboard",        label: "Dashboard",              icon: LayoutDashboard },
  { href: "/approvals",        label: "Approvals",              icon: CheckSquare, roles: ["MANAGER", "SUPERUSER"] },
  { href: "/payments",         label: "Payments",               icon: CreditCard,  roles: ["ACCOUNTS"] },
  { href: "/payments/history", label: "Payment History",        icon: Receipt,     roles: ["ACCOUNTS", "SUPERUSER"] },
  { href: "/profile",          label: "My Profile",             icon: UserCircle },
];

// ── Purchasing section ────────────────────────────────────────────────────────
// Purchase Order actions (create / browse / import / history)
const PURCHASING_PO: NavItem[] = [
  { href: "/po/new",     label: "New Purchase Order",     icon: Plus,     roles: ["TECHNICAL", "MANNING", "MANAGER", "SUPERUSER"] },
  { href: "/my-orders",  label: "Closed Purchase Orders", icon: FileText, roles: ["TECHNICAL", "MANNING", "MANAGER", "SUPERUSER"] },
  { href: "/po/import",  label: "Import Purchase Order",  icon: Upload,   roles: ["MANAGER", "SUPERUSER"] },
  { href: "/history",    label: "Purchase Order History", icon: History,  roles: HISTORY_ROLES },
];

// Staff browsing items (product catalogue + cart for PO creation)
const PURCHASING_STAFF: NavItem[] = [
  { href: "/catalogue/items",   label: "Items",         icon: Package,      roles: ["TECHNICAL", "MANNING", "SUPERUSER"] },
  { href: "/catalogue/vendors", label: "Vendors",       icon: Store,        roles: ["TECHNICAL", "MANNING", "SUPERUSER"] },
  { href: "/inventory/cart",    label: "Cart",          icon: ShoppingCart, roles: ["TECHNICAL", "MANNING", "SUPERUSER", "MANAGER"] },
];

// Manager catalogue management — Sites conditionally shown
// Admin does not use Purchasing; their links live under Administration
const PURCHASING_MGMT: NavItem[] = [
  { href: "/catalogue/vendors", label: "Vendors",      icon: Store,   roles: ["MANAGER"] },
  { href: "/catalogue/items",   label: "Items",        icon: Package, roles: ["MANAGER"] },
  { href: "/admin/vessels",     label: "Cost Centres", icon: Ship,    roles: ["MANAGER"] },
  ...(INVENTORY_ENABLED
    ? [{ href: "/admin/sites", label: "Sites", icon: MapPin, roles: ["MANAGER"] as Role[] }]
    : []),
];

const PURCHASING_ITEMS: NavItem[] = [...PURCHASING_PO, ...PURCHASING_STAFF, ...PURCHASING_MGMT];

// ── Reports section ───────────────────────────────────────────────────────────
// Spend analytics, gated by `view_analytics` (Manager / SuperUser / Auditor /
// Admin). Links are grouped under a "Purchasing" subheading so other domains
// (e.g. Crewing) can hang their own report groups here later.
const REPORTS_ROLES: Role[] = ["MANAGER", "SUPERUSER", "AUDITOR", "ADMIN"];
const REPORTS_PURCHASING: NavItem[] = [
  { href: "/reports/cost-centres",    label: "Cost Centres",     icon: Ship,      roles: REPORTS_ROLES },
  { href: "/reports/accounting-codes", label: "Accounting Codes", icon: Building2, roles: REPORTS_ROLES },
];

// ── Crewing section (feature-flagged) ─────────────────────────────────────────
// Gated by CREWING_ENABLED. Phase 2 adds Requisitions (Manager + MPO, per
// Crewing-Implementation-Spec §7); later phases append Candidates / Crew / Leave
// / Attendance / Verification with their per-role visibility. "Ranks & documents"
// lives under Administration.
const CREWING_ITEMS: NavItem[] = CREWING_ENABLED
  ? [
      { href: "/crewing/requisitions", label: "Requisitions", icon: ClipboardList, roles: ["MANNING", "MANAGER", "SUPERUSER"] },
      { href: "/crewing/candidates",   label: "Candidates",   icon: UserSearch,    roles: ["MANNING", "MANAGER", "SUPERUSER"] },
      { href: "/crewing/crew",         label: "Crew",         icon: Contact,       roles: ["MANNING", "MANAGER", "SUPERUSER", "SITE_STAFF", "ACCOUNTS"] },
      { href: "/crewing/leave",        label: "Leave",        icon: CalendarDays,  roles: ["MANAGER", "SUPERUSER", "SITE_STAFF"] },
      { href: "/crewing/attendance",   label: "Attendance",   icon: CalendarCheck, roles: ["MANAGER", "SUPERUSER", "SITE_STAFF"] },
      { href: "/crewing/verification", label: "Verification", icon: BadgeCheck,    roles: ["MANNING", "SUPERUSER", "ACCOUNTS"] },
    ]
  : [];

// ── Administration section ────────────────────────────────────────────────────
// Vendors shown to MANAGER / ACCOUNTS under their own Administration header
const MANAGER_ADMIN_ITEMS: NavItem[] = [
  { href: "/admin/vendors",            label: "Vendors",            icon: Store,   roles: ["MANAGER", "ACCOUNTS", "ADMIN"] },
  { href: "/admin/products",           label: "Items",              icon: Package, roles: ["MANAGER", "ADMIN"] },
  { href: "/admin/delivery-locations", label: "Delivery Locations", icon: Truck,      roles: ["MANAGER", "SUPERUSER", "ADMIN"] },
  { href: "/admin/terms",              label: "Terms & Conditions", icon: ScrollText, roles: ["MANAGER", "SUPERUSER", "ADMIN"] },
  // Crewing reference data — gated by the crewing flag; held by manage_ranks (MGR/ADMIN).
  ...(CREWING_ENABLED
    ? [
        { href: "/admin/ranks",        label: "Ranks & documents", icon: Network, roles: ["MANAGER", "ADMIN"] as Role[] },
        { href: "/admin/crew",         label: "Crew management",   icon: UserCog, roles: ["MANAGER", "SUPERUSER", "ADMIN"] as Role[] },
        { href: "/admin/crew-strength", label: "Crew strength",    icon: Gauge,   roles: ["MANAGER", "SUPERUSER", "ADMIN"] as Role[] },
      ]
    : []),
];

// Full Administration section (ADMIN only)
const ADMIN_ITEMS: NavItem[] = [
  { href: "/admin/vessels",            label: "Cost Centres",      icon: Ship       },
  { href: "/admin/sites",              label: "Sites",             icon: MapPin     },
  { href: "/admin/users",              label: "Users",             icon: Users      },
  { href: "/admin/superuser-requests", label: "SuperUser Requests",icon: ShieldCheck },
  { href: "/admin/accounts",           label: "Accounting Codes",  icon: Building2  },
  { href: "/admin/companies",          label: "Companies",         icon: Briefcase  },
];

interface NavGroup {
  label?: string; // optional subheading shown above the group's links
  items: NavItem[];
}
interface Section {
  id: string;
  label: string;
  groups: NavGroup[];
}

function isItemActive(href: string, pathname: string) {
  return pathname === href || pathname.startsWith(href + "/");
}

export function Sidebar({ userRole }: { userRole: Role }) {
  const pathname = usePathname();
  const isAdmin  = userRole === "ADMIN";

  const visible = (i: NavItem) => !i.roles || i.roles.includes(userRole);
  const visibleMain       = NAV_ITEMS.filter(visible);
  const visiblePurchasing = PURCHASING_ITEMS.filter(visible);
  const visibleReports    = REPORTS_PURCHASING.filter(visible);
  const visibleCrewing    = CREWING_ITEMS.filter(visible);
  const visibleMgrAdmin   = MANAGER_ADMIN_ITEMS.filter(visible);
  const adminItems        = isAdmin ? [...MANAGER_ADMIN_ITEMS, ...ADMIN_ITEMS] : visibleMgrAdmin;

  // Headed, collapsible sections (the main links above sit outside any section).
  // A section holds one or more groups; a group can carry an optional subheading.
  const sections: Section[] = [
    { id: "purchasing",     label: "Purchasing",     groups: [{ items: visiblePurchasing }] },
    { id: "reports",        label: "Reports",        groups: [{ label: "Purchasing", items: visibleReports }] },
    { id: "crewing",        label: "Crewing",        groups: [{ items: visibleCrewing }] },
    { id: "administration", label: "Administration", groups: [{ items: adminItems }] },
  ]
    .map((s) => ({ ...s, groups: s.groups.filter((g) => g.items.length > 0) }))
    .filter((s) => s.groups.length > 0);

  const sectionItems = (s: Section) => s.groups.flatMap((g) => g.items);
  // The section (if any) that holds the currently active route.
  const activeSectionId =
    sections.find((s) => sectionItems(s).some((i) => isItemActive(i.href, pathname)))?.id ?? null;

  // Single-open accordion, collapsed by default. Auto-expand the section that
  // contains the active route so the user is never stranded on a hidden link.
  const [openSection, setOpenSection] = useState<string | null>(activeSectionId);

  // On navigation, open the section holding the new active route (which, being a
  // single-open accordion, collapses any other open heading).
  useEffect(() => {
    if (activeSectionId) setOpenSection(activeSectionId);
  }, [activeSectionId]);

  const toggleSection = (id: string) =>
    setOpenSection((current) => (current === id ? null : id));

  return (
    <aside className="flex h-screen w-60 shrink-0 flex-col border-r border-neutral-200 bg-white">
      <div className="flex h-16 items-center gap-2.5 border-b border-neutral-200 px-4">
        <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary-600">
          <Anchor className="h-4 w-4 text-white" />
        </div>
        <span className="text-sm font-semibold text-neutral-900">PPMS</span>
      </div>

      <nav className="flex-1 overflow-y-auto px-3 py-4 space-y-0.5">
        {visibleMain.map((item) => (
          <NavLink key={item.href} item={item} pathname={pathname} />
        ))}

        {sections.map((section) => {
          const isOpen = openSection === section.id;
          const regionId = `nav-section-${section.id}`;
          return (
            <div key={section.id}>
              <SectionHeader
                label={section.label}
                isOpen={isOpen}
                regionId={regionId}
                onToggle={() => toggleSection(section.id)}
              />
              {isOpen && (
                <div id={regionId} className="space-y-0.5">
                  {section.groups.map((group, gi) => (
                    <div key={group.label ?? gi} className="space-y-0.5">
                      {group.label && (
                        <p className="px-3 pt-2 pb-1 text-[11px] font-semibold uppercase tracking-wider text-neutral-300">
                          {group.label}
                        </p>
                      )}
                      {group.items.map((item) => (
                        <NavLink key={item.href} item={item} pathname={pathname} />
                      ))}
                    </div>
                  ))}
                </div>
              )}
            </div>
          );
        })}
      </nav>
    </aside>
  );
}

function SectionHeader({
  label,
  isOpen,
  regionId,
  onToggle,
}: {
  label: string;
  isOpen: boolean;
  regionId: string;
  onToggle: () => void;
}) {
  return (
    <button
      type="button"
      onClick={onToggle}
      aria-expanded={isOpen}
      aria-controls={regionId}
      className="flex w-full items-center justify-between pt-4 pb-1 px-3 text-xs font-semibold text-neutral-400 uppercase tracking-wider hover:text-neutral-600"
    >
      <span>{label}</span>
      <ChevronRight
        className={cn("h-3.5 w-3.5 shrink-0 transition-transform", isOpen && "rotate-90")}
      />
    </button>
  );
}

function NavLink({ item, pathname }: { item: NavItem; pathname: string }) {
  const isActive = isItemActive(item.href, pathname);
  const Icon = item.icon;
  return (
    <Link
      href={item.href}
      className={cn(
        "flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
        isActive
          ? "bg-primary-50 text-primary-700"
          : "text-neutral-600 hover:bg-neutral-100 hover:text-neutral-900"
      )}
    >
      <Icon className="h-4 w-4 shrink-0" />
      {item.label}
    </Link>
  );
}
