"use client";

import type { ReactNode } from "react";
import { signOut } from "next-auth/react";
import Link from "next/link";
import type { Route } from "next";
import { usePathname } from "next/navigation";
import { clsx } from "clsx";
import { memo, Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { PreferencesModal } from "./PreferencesModal.js";
import { ThemeProvider } from "./ThemeProvider.js";
import { PageTransition } from "./PageTransition.js";
import { NotificationBell } from "../notifications/NotificationBell.js";
import { ChatPanel } from "../assistant/ChatPanel.js";
import { NavProgressBar } from "~/components/ui/NavProgressBar.js";
import {
  IconFrame,
  DashboardIcon,
  ResourcesIcon,
  ProjectsIcon,
  EstimatesIcon,
  AllocationsIcon,
  TimelineIcon,
  StaffingIcon,
  VacationIcon,
  RolesIcon,
  SkillsIcon,
  MarketplaceIcon,
  ChargeabilityIcon,
  BenchIcon,
  ReportBuilderIcon,
  GraphIcon,
  InsightsIcon,
  NotificationsIcon,
  BroadcastIcon,
  ActivityLogIcon,
  AdminIcon,
  BlueprintIcon,
  ClientsIcon,
  CountryIcon,
  OrgUnitIcon,
  CategoryIcon,
  LevelsIcon,
  ImportIcon,
  CalcRulesIcon,
  UsersIcon,
  SystemRolesIcon,
  SecurityIcon,
  SettingsIcon,
  WebhooksIcon,
  ScenariosIcon,
  CollapseIcon,
  HamburgerIcon,
  CloseIcon,
} from "./nav-icons.js";

const SIDEBAR_COLLAPSED_KEY = "nexus_sidebar_collapsed";

type NavItem = { href: string; label: string; icon: ReactNode; roles: string[] };
type NavSection = { label: string; collapsed?: boolean; items: NavItem[] };

const navSections: NavSection[] = [
  {
    label: "Planning",
    items: [
      {
        href: "/dashboard",
        label: "Dashboard",
        icon: <DashboardIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER", "USER", "VIEWER"],
      },
      {
        href: "/timeline",
        label: "Timeline",
        icon: <TimelineIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER", "USER", "VIEWER"],
      },
      {
        href: "/allocations",
        label: "Allocations",
        icon: <AllocationsIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      { href: "/staffing", label: "Staffing", icon: <StaffingIcon />, roles: ["ADMIN", "MANAGER"] },
      {
        href: "/scenarios",
        label: "Scenarios",
        icon: <ScenariosIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      {
        href: "/notifications",
        label: "Notifications",
        icon: <NotificationsIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER", "USER", "VIEWER"],
      },
    ],
  },
  {
    label: "Estimating",
    collapsed: true,
    items: [
      {
        href: "/estimates",
        label: "Estimates",
        icon: <EstimatesIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER", "USER", "VIEWER"],
      },
      {
        href: "/admin/rate-cards",
        label: "Rate Cards",
        icon: <EstimatesIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      {
        href: "/admin/effort-rules",
        label: "Effort Rules",
        icon: <EstimatesIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      {
        href: "/admin/experience-multipliers",
        label: "Exp. Multipliers",
        icon: <EstimatesIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
    ],
  },
  {
    label: "Resources",
    items: [
      {
        href: "/resources",
        label: "Resources",
        icon: <ResourcesIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      {
        href: "/bench",
        label: "Bench",
        icon: <BenchIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      {
        href: "/projects",
        label: "Projects",
        icon: <ProjectsIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER", "VIEWER"],
      },
      {
        href: "/roles",
        label: "Roles",
        icon: <RolesIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
    ],
  },
  {
    label: "Analytics",
    items: [
      {
        href: "/analytics/skills",
        label: "Skills Hub",
        icon: <SkillsIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER", "VIEWER"],
      },
      {
        href: "/reports/chargeability",
        label: "Chargeability",
        icon: <ChargeabilityIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      {
        href: "/reports/builder",
        label: "Report Builder",
        icon: <ReportBuilderIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      {
        href: "/analytics/computation-graph",
        label: "Computation Graph",
        icon: <GraphIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
      {
        href: "/analytics/insights",
        label: "AI Insights",
        icon: <InsightsIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER"],
      },
    ],
  },
  {
    label: "Time Off",
    items: [
      {
        href: "/vacations/my",
        label: "My Vacations",
        icon: <VacationIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER", "USER", "VIEWER"],
      },
      {
        href: "/vacations",
        label: "Vacation Mgmt",
        icon: <VacationIcon />,
        roles: ["ADMIN", "MANAGER"],
      },
    ],
  },
  {
    label: "Account",
    items: [
      {
        href: "/account/security",
        label: "Security",
        icon: <SecurityIcon />,
        roles: ["ADMIN", "MANAGER", "CONTROLLER", "USER", "VIEWER"],
      },
    ],
  },
];

type AdminNavItem = { href: string; label: string; icon: ReactNode };
type AdminSubGroup = { label: string; collapsed: boolean; items: AdminNavItem[] };
type AdminEntry = AdminNavItem | AdminSubGroup;

function isSubGroup(entry: AdminEntry): entry is AdminSubGroup {
  return "items" in entry;
}

const adminNavEntries: AdminEntry[] = [
  { href: "/admin/blueprints", label: "Blueprints", icon: <BlueprintIcon /> },
  { href: "/admin/clients", label: "Clients", icon: <ClientsIcon /> },
  {
    label: "ACN-Orga",
    collapsed: true,
    items: [
      { href: "/admin/countries", label: "Countries", icon: <CountryIcon /> },
      { href: "/admin/org-units", label: "Org Units", icon: <OrgUnitIcon /> },
      { href: "/admin/utilization-categories", label: "Util. Categories", icon: <CategoryIcon /> },
      { href: "/admin/management-levels", label: "Mgmt Levels", icon: <LevelsIcon /> },
      { href: "/admin/imports", label: "Data Import", icon: <ImportIcon /> },
    ],
  },
  { href: "/admin/calculation-rules", label: "Calc. Rules", icon: <CalcRulesIcon /> },
  { href: "/admin/vacations", label: "Vacations & Holidays", icon: <VacationIcon /> },
  { href: "/admin/users", label: "Users", icon: <UsersIcon /> },
  { href: "/admin/system-roles", label: "System Roles", icon: <SystemRolesIcon /> },
  { href: "/admin/settings", label: "Settings", icon: <SettingsIcon /> },
  { href: "/admin/notifications", label: "Broadcasts", icon: <BroadcastIcon /> },
  { href: "/admin/webhooks", label: "Webhooks", icon: <WebhooksIcon /> },
  { href: "/admin/activity-log", label: "Activity Log", icon: <ActivityLogIcon /> },
];

/**
 * Collect every href registered in the sidebar so that the active-check
 * can determine whether a more-specific sibling matches the current path.
 */
const ALL_NAV_HREFS: string[] = (() => {
  const hrefs: string[] = [];
  for (const section of navSections) {
    for (const item of section.items) hrefs.push(item.href);
  }
  for (const entry of adminNavEntries) {
    if (isSubGroup(entry)) {
      for (const item of entry.items) hrefs.push(item.href);
    } else {
      hrefs.push(entry.href);
    }
  }
  return hrefs;
})();

function isNavItemActive(pathname: string, href: string): boolean {
  if (pathname === href) return true;
  if (!pathname.startsWith(href + "/")) return false;
  const hasMoreSpecificSibling = ALL_NAV_HREFS.some(
    (other) => other !== href && other.length > href.length && pathname.startsWith(other),
  );
  return !hasMoreSpecificSibling;
}

/* ------------------------------------------------------------------ */
/*  Tooltip wrapper — shows label on hover when sidebar is collapsed  */
/* ------------------------------------------------------------------ */

function NavTooltip({
  label,
  show,
  children,
}: {
  label: string;
  show: boolean;
  children: ReactNode;
}) {
  if (!show) return <>{children}</>;
  return (
    <div className="group/tip relative">
      {children}
      <div className="pointer-events-none absolute left-full top-1/2 z-50 ml-2 -translate-y-1/2 whitespace-nowrap rounded-lg bg-gray-900 px-2.5 py-1.5 text-xs font-medium text-white opacity-0 shadow-lg transition-opacity group-hover/tip:opacity-100 dark:bg-slate-700">
        {label}
        <div className="absolute right-full top-1/2 -translate-y-1/2 border-4 border-transparent border-r-gray-900 dark:border-r-slate-700" />
      </div>
    </div>
  );
}

/* ------------------------------------------------------------------ */
/*  Memoized nav item — prevents re-render of inactive items           */
/* ------------------------------------------------------------------ */

/** Routes that benefit from eager prefetching (loaded while user reads current page). */
const PREFETCH_ROUTES = new Set([
  "/dashboard",
  "/timeline",
  "/projects",
  "/resources",
  "/allocations",
]);

const NavItemLink = memo(function NavItemLink({
  href,
  label,
  icon,
  isActive,
  collapsed,
  onClick,
}: {
  href: string;
  label: string;
  icon: ReactNode;
  isActive: boolean;
  collapsed: boolean;
  onClick?: (() => void) | undefined;
}) {
  const linkProps = {
    ...(onClick ? { onClick } : {}),
    ...(PREFETCH_ROUTES.has(href) ? { prefetch: true as const } : {}),
  };

  return (
    <NavTooltip label={label} show={collapsed}>
      <Link
        href={href as Route}
        {...linkProps}
        className={clsx(
          "group relative flex items-center rounded-2xl text-sm transition-colors",
          collapsed ? "justify-center px-2 py-2" : "gap-3 px-3 py-2",
          isActive
            ? "font-medium text-brand-700 dark:border-l-2 dark:border-brand-400/70 dark:text-brand-300"
            : "font-medium text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-white/[0.05] dark:hover:text-white",
        )}
      >
        {isActive && (
          <motion.div
            layoutId="nav-indicator"
            className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-50 to-brand-100/60 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-500/15 dark:to-brand-400/[0.08] dark:ring-brand-900/40"
            transition={{ type: "spring", stiffness: 350, damping: 30 }}
          />
        )}
        <IconFrame isActive={isActive}>{icon}</IconFrame>
        {!collapsed && <span className="relative flex-1">{label}</span>}
      </Link>
    </NavTooltip>
  );
});

/* ------------------------------------------------------------------ */
/*  Sidebar component                                                  */
/* ------------------------------------------------------------------ */

function SidebarContent({
  userRole,
  onChatOpen,
  sidebarCollapsed,
  onToggleCollapse,
  onNavClick,
  onPrefsOpen,
}: {
  userRole: string;
  onChatOpen: () => void;
  sidebarCollapsed: boolean;
  onToggleCollapse: () => void;
  onNavClick?: () => void;
  onPrefsOpen: () => void;
}) {
  const pathname = usePathname();

  const activeHrefSet = useMemo(() => {
    const set = new Set<string>();
    for (const href of ALL_NAV_HREFS) {
      if (isNavItemActive(pathname, href)) set.add(href);
    }
    return set;
  }, [pathname]);

  const visibleSections = navSections
    .map((section) => ({
      ...section,
      items: section.items.filter((item) => item.roles.includes(userRole)),
    }))
    .filter((section) => section.items.length > 0);
  const showAdmin = userRole === "ADMIN";
  const showManagerSection = userRole === "ADMIN" || userRole === "MANAGER";

  const [collapsedSections, setCollapsedSections] = useState<Record<string, boolean>>(() => {
    const initial: Record<string, boolean> = {};
    for (const section of visibleSections) {
      if (section.collapsed) {
        const hasActiveRoute = section.items.some((item) => activeHrefSet.has(item.href));
        initial[section.label] = !hasActiveRoute;
      }
    }
    for (const entry of adminNavEntries) {
      if (isSubGroup(entry) && entry.collapsed) {
        const hasActiveRoute = entry.items.some((item) => activeHrefSet.has(item.href));
        initial[entry.label] = !hasActiveRoute;
      }
    }
    return initial;
  });

  const toggleSection = (label: string) => {
    setCollapsedSections((prev) => ({ ...prev, [label]: !prev[label] }));
  };

  const handleLinkClick = () => {
    onNavClick?.();
  };

  return (
    <>
      {/* Logo */}
      <div
        className={clsx(
          "border-b border-gray-200/80 dark:border-slate-800",
          sidebarCollapsed ? "px-3 py-4" : "px-6 py-6",
        )}
      >
        <div
          className={clsx(
            "inline-flex items-center rounded-2xl border border-brand-200/70 bg-gradient-to-br from-white to-brand-50 shadow-sm dark:border-white/[0.08] dark:from-[rgb(var(--surface-elevated))] dark:to-[rgb(var(--surface-elevated))]",
            sidebarCollapsed ? "p-2" : "gap-3 px-4 py-3",
          )}
        >
          <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-2xl bg-brand-600 text-white shadow-lg shadow-brand-600/25">
            <DashboardIcon />
          </div>
          {!sidebarCollapsed && (
            <div className="overflow-hidden">
              <h1 className="font-display text-xl font-semibold text-gray-900 dark:text-gray-50">
                Capa<span className="text-brand-600">Kraken</span>
              </h1>
              <p className="text-xs uppercase tracking-[0.18em] text-gray-500 dark:text-gray-400">
                Resource & Capacity Planning
              </p>
            </div>
          )}
        </div>
      </div>

      {/* Nav links */}
      <div className={clsx("flex-1 overflow-y-auto py-5", sidebarCollapsed ? "px-2" : "px-4")}>
        {visibleSections.map((section, idx) => {
          const isCollapsed = collapsedSections[section.label] ?? false;
          const isCollapsible = section.collapsed === true;

          return (
            <div key={section.label} className={idx > 0 ? "mt-2" : ""}>
              {/* Section header — hidden when sidebar collapsed */}
              {!sidebarCollapsed && (
                <button
                  type="button"
                  onClick={isCollapsible ? () => toggleSection(section.label) : undefined}
                  className={clsx(
                    "flex w-full items-center px-3 pb-1.5 pt-3",
                    isCollapsible && "cursor-pointer hover:text-gray-600 dark:hover:text-gray-300",
                  )}
                >
                  <span className="flex-1 text-left text-[11px] font-semibold uppercase tracking-[0.18em] text-gray-400 dark:text-gray-500">
                    {section.label}
                  </span>
                  {isCollapsible && (
                    <svg
                      className={clsx(
                        "h-3 w-3 text-gray-400 transition-transform dark:text-gray-500",
                        isCollapsed ? "-rotate-90" : "rotate-0",
                      )}
                      fill="none"
                      stroke="currentColor"
                      viewBox="0 0 24 24"
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth={2}
                        d="M19 9l-7 7-7-7"
                      />
                    </svg>
                  )}
                </button>
              )}

              {/* Collapsed sidebar: show a thin divider between sections instead of header */}
              {sidebarCollapsed && idx > 0 && (
                <div className="mx-3 my-2 border-t border-gray-200/60 dark:border-slate-800" />
              )}

              <AnimatePresence initial={false}>
                {(!isCollapsed || sidebarCollapsed) && (
                  <motion.div
                    initial={sidebarCollapsed ? false : { height: 0, opacity: 0 }}
                    animate={{ height: "auto", opacity: 1 }}
                    exit={{ height: 0, opacity: 0 }}
                    transition={{ duration: 0.2, ease: "easeInOut" }}
                    className="overflow-hidden"
                  >
                    <div className="space-y-0.5">
                      {section.items.map((item) => (
                        <NavItemLink
                          key={item.href}
                          href={item.href}
                          label={item.label}
                          icon={item.icon}
                          isActive={activeHrefSet.has(item.href)}
                          collapsed={sidebarCollapsed}
                          onClick={handleLinkClick}
                        />
                      ))}
                    </div>
                  </motion.div>
                )}
              </AnimatePresence>
            </div>
          );
        })}

        {showManagerSection && showAdmin && (
          <div className="mt-2">
            {!sidebarCollapsed && (
              <div className="px-3 pb-1.5 pt-3">
                <span className="text-[11px] font-semibold uppercase tracking-[0.18em] text-gray-400 dark:text-gray-500">
                  Admin
                </span>
              </div>
            )}
            {sidebarCollapsed && (
              <div className="mx-3 my-2 border-t border-gray-200/60 dark:border-slate-800" />
            )}
            <div className="space-y-0.5">
              {adminNavEntries.map((entry) => {
                if (isSubGroup(entry)) {
                  const subCollapsed = collapsedSections[entry.label] ?? false;

                  if (sidebarCollapsed) {
                    // In collapsed mode, show sub-group items directly as icon-only
                    return entry.items.map((item) => (
                      <NavItemLink
                        key={item.href}
                        href={item.href}
                        label={item.label}
                        icon={item.icon}
                        isActive={activeHrefSet.has(item.href)}
                        collapsed
                        onClick={handleLinkClick}
                      />
                    ));
                  }

                  return (
                    <div key={entry.label}>
                      <button
                        type="button"
                        onClick={() => toggleSection(entry.label)}
                        className="flex w-full items-center gap-3 rounded-2xl px-3 py-2 text-sm font-medium text-gray-500 transition-all hover:bg-gray-100/90 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/[0.05] dark:hover:text-gray-200"
                      >
                        <IconFrame>
                          <AdminIcon />
                        </IconFrame>
                        <span className="flex-1 text-left">{entry.label}</span>
                        <svg
                          className={clsx(
                            "h-3 w-3 transition-transform",
                            subCollapsed ? "-rotate-90" : "rotate-0",
                          )}
                          fill="none"
                          stroke="currentColor"
                          viewBox="0 0 24 24"
                        >
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            strokeWidth={2}
                            d="M19 9l-7 7-7-7"
                          />
                        </svg>
                      </button>
                      <AnimatePresence initial={false}>
                        {!subCollapsed && (
                          <motion.div
                            initial={{ height: 0, opacity: 0 }}
                            animate={{ height: "auto", opacity: 1 }}
                            exit={{ height: 0, opacity: 0 }}
                            transition={{ duration: 0.2, ease: "easeInOut" }}
                            className="overflow-hidden"
                          >
                            <div className="ml-4 space-y-0.5 border-l border-gray-200 pl-2 dark:border-slate-800">
                              {entry.items.map((item) => {
                                const isActive = activeHrefSet.has(item.href);
                                return (
                                  <Link
                                    key={item.href}
                                    href={item.href as Route}
                                    onClick={handleLinkClick}
                                    className={clsx(
                                      "group relative flex items-center gap-3 rounded-2xl px-3 py-1.5 text-sm font-medium transition-colors",
                                      isActive
                                        ? "text-brand-700 dark:border-l-2 dark:border-brand-400/70 dark:text-brand-300"
                                        : "text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-white/[0.05] dark:hover:text-white",
                                    )}
                                  >
                                    {isActive && (
                                      <motion.div
                                        layoutId="nav-indicator"
                                        className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-50 to-brand-100/60 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-500/15 dark:to-brand-400/[0.08] dark:ring-brand-900/40"
                                        transition={{ type: "spring", stiffness: 350, damping: 30 }}
                                      />
                                    )}
                                    <span className="relative flex-1">{item.label}</span>
                                  </Link>
                                );
                              })}
                            </div>
                          </motion.div>
                        )}
                      </AnimatePresence>
                    </div>
                  );
                }

                return (
                  <NavItemLink
                    key={entry.href}
                    href={entry.href}
                    label={entry.label}
                    icon={entry.icon}
                    isActive={activeHrefSet.has(entry.href)}
                    collapsed={sidebarCollapsed}
                    onClick={handleLinkClick}
                  />
                );
              })}
            </div>
          </div>
        )}
      </div>

      {/* Bottom actions */}
      <div
        className={clsx(
          "space-y-1 border-t border-gray-200/80 dark:border-slate-800",
          sidebarCollapsed ? "p-2" : "p-4",
        )}
      >
        <NavTooltip label="Notifications" show={sidebarCollapsed}>
          <div
            className={clsx(
              "flex items-center",
              sidebarCollapsed ? "justify-center px-2 py-2" : "gap-2 px-3 py-2",
            )}
          >
            <NotificationBell />
            {!sidebarCollapsed && (
              <span className="text-xs uppercase tracking-[0.16em] text-gray-400 dark:text-gray-500">
                Notifications
              </span>
            )}
          </div>
        </NavTooltip>

        <NavTooltip label="HartBOT" show={sidebarCollapsed}>
          <button
            type="button"
            onClick={onChatOpen}
            className={clsx(
              "flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-white/[0.05]",
              sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
            )}
          >
            <IconFrame>
              <svg
                className="h-4 w-4 shrink-0"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"
                />
              </svg>
            </IconFrame>
            {!sidebarCollapsed && <span>HartBOT</span>}
          </button>
        </NavTooltip>

        <NavTooltip label="Preferences" show={sidebarCollapsed}>
          <button
            type="button"
            onClick={onPrefsOpen}
            className={clsx(
              "flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-white/[0.05]",
              sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
            )}
          >
            <IconFrame>
              <svg
                className="h-4 w-4 shrink-0"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
                />
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
                />
              </svg>
            </IconFrame>
            {!sidebarCollapsed && <span>Preferences</span>}
          </button>
        </NavTooltip>

        <NavTooltip label="Sign out" show={sidebarCollapsed}>
          <button
            type="button"
            onClick={() => void signOut({ callbackUrl: "/auth/signin" })}
            className={clsx(
              "flex w-full items-center rounded-2xl text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-white/[0.05]",
              sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
            )}
          >
            <IconFrame>
              <svg
                className="h-4 w-4 shrink-0"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
                />
              </svg>
            </IconFrame>
            {!sidebarCollapsed && <span>Sign out</span>}
          </button>
        </NavTooltip>

        {/* Collapse toggle */}
        <NavTooltip
          label={sidebarCollapsed ? "Expand sidebar" : "Collapse sidebar"}
          show={sidebarCollapsed}
        >
          <button
            type="button"
            onClick={onToggleCollapse}
            className={clsx(
              "flex w-full items-center rounded-2xl text-sm text-gray-400 transition-colors hover:bg-gray-100/90 hover:text-gray-600 dark:text-gray-500 dark:hover:bg-white/[0.05] dark:hover:text-gray-300",
              sidebarCollapsed ? "justify-center px-2 py-2.5" : "gap-3 px-3 py-2.5",
            )}
          >
            <span className="flex h-8 w-8 shrink-0 items-center justify-center">
              <CollapseIcon collapsed={sidebarCollapsed} />
            </span>
            {!sidebarCollapsed && <span>Collapse</span>}
          </button>
        </NavTooltip>
      </div>
    </>
  );
}

/* ------------------------------------------------------------------ */
/*  Desktop sidebar wrapper                                            */
/* ------------------------------------------------------------------ */

function DesktopSidebar({
  userRole,
  onChatOpen,
  sidebarCollapsed,
  onToggleCollapse,
  onPrefsOpen,
}: {
  userRole: string;
  onChatOpen: () => void;
  sidebarCollapsed: boolean;
  onToggleCollapse: () => void;
  onPrefsOpen: () => void;
}) {
  return (
    <nav
      className={clsx(
        "sidebar-panel hidden shrink-0 border-r border-gray-200/60 bg-white/95 shadow-[1px_0_12px_rgba(0,0,0,0.03)] backdrop-blur-xl backdrop-saturate-150 dark:shadow-none lg:flex lg:flex-col",
        "transition-[width] duration-200 ease-out overflow-hidden",
        sidebarCollapsed ? "w-[72px]" : "w-72",
      )}
    >
      <SidebarContent
        userRole={userRole}
        onChatOpen={onChatOpen}
        sidebarCollapsed={sidebarCollapsed}
        onToggleCollapse={onToggleCollapse}
        onPrefsOpen={onPrefsOpen}
      />
    </nav>
  );
}

/* ------------------------------------------------------------------ */
/*  Mobile sidebar overlay                                             */
/* ------------------------------------------------------------------ */

function MobileSidebar({
  open,
  onClose,
  userRole,
  onChatOpen,
  onPrefsOpen,
}: {
  open: boolean;
  onClose: () => void;
  userRole: string;
  onChatOpen: () => void;
  onPrefsOpen: () => void;
}) {
  return (
    <AnimatePresence>
      {open && (
        <>
          {/* Backdrop */}
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
            className="fixed inset-0 z-40 bg-black/40 backdrop-blur-sm lg:hidden"
            onClick={onClose}
          />
          {/* Slide-in sidebar */}
          <motion.nav
            initial={{ x: -288 }}
            animate={{ x: 0 }}
            exit={{ x: -288 }}
            transition={{ type: "spring", stiffness: 400, damping: 35 }}
            className="sidebar-panel fixed inset-y-0 left-0 z-50 flex w-72 flex-col border-r border-gray-200/60 bg-white/95 shadow-2xl backdrop-blur-2xl backdrop-saturate-150 lg:hidden"
          >
            {/* Close button */}
            <button
              type="button"
              onClick={onClose}
              className="absolute right-3 top-5 z-10 flex h-8 w-8 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 dark:text-gray-500 dark:hover:bg-slate-800 dark:hover:text-gray-300"
            >
              <CloseIcon />
            </button>

            <SidebarContent
              userRole={userRole}
              onChatOpen={() => {
                onChatOpen();
                onClose();
              }}
              sidebarCollapsed={false}
              onToggleCollapse={() => {}}
              onNavClick={onClose}
              onPrefsOpen={() => {
                onPrefsOpen();
                onClose();
              }}
            />
          </motion.nav>
        </>
      )}
    </AnimatePresence>
  );
}

/* ------------------------------------------------------------------ */
/*  AppShell (main export)                                             */
/* ------------------------------------------------------------------ */

export function AppShell({
  children,
  userRole = "USER",
}: {
  children: React.ReactNode;
  userRole?: string;
}) {
  const [chatOpen, setChatOpen] = useState(false);
  const [mobileOpen, setMobileOpen] = useState(false);
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
  const [prefsOpen, setPrefsOpen] = useState(false);
  const pathname = usePathname();
  const contentRef = useRef<HTMLElement>(null);

  // Read collapsed state from localStorage on mount (avoid SSR hydration mismatch)
  useEffect(() => {
    try {
      const stored = localStorage.getItem(SIDEBAR_COLLAPSED_KEY);
      if (stored === "true") setSidebarCollapsed(true);
    } catch {
      // localStorage unavailable — ignore
    }
  }, []);

  // Persist collapsed state
  const handleToggleCollapse = useCallback(() => {
    setSidebarCollapsed((prev) => {
      const next = !prev;
      try {
        localStorage.setItem(SIDEBAR_COLLAPSED_KEY, String(next));
      } catch {
        // ignore
      }
      return next;
    });
  }, []);

  // Scroll to top on route change
  useEffect(() => {
    contentRef.current?.scrollTo({ top: 0, behavior: "smooth" });
  }, [pathname]);

  // Close mobile sidebar on route change
  useEffect(() => {
    setMobileOpen(false);
  }, [pathname]);

  return (
    <ThemeProvider>
      <Suspense>
        <NavProgressBar />
      </Suspense>
      <div className="flex h-screen bg-transparent">
        {/* Desktop sidebar */}
        <DesktopSidebar
          userRole={userRole}
          onChatOpen={() => setChatOpen(true)}
          sidebarCollapsed={sidebarCollapsed}
          onToggleCollapse={handleToggleCollapse}
          onPrefsOpen={() => setPrefsOpen(true)}
        />

        {/* Mobile sidebar overlay */}
        <MobileSidebar
          open={mobileOpen}
          onClose={() => setMobileOpen(false)}
          userRole={userRole}
          onChatOpen={() => setChatOpen(true)}
          onPrefsOpen={() => setPrefsOpen(true)}
        />

        {/* Main content area */}
        <main ref={contentRef} className="flex-1 overflow-auto bg-transparent">
          {/* Mobile hamburger */}
          <div className="sidebar-panel sticky top-0 z-20 flex items-center border-b border-gray-200/60 bg-white/85 px-4 py-2 backdrop-blur-xl lg:hidden">
            <button
              type="button"
              onClick={() => setMobileOpen(true)}
              className="flex h-9 w-9 items-center justify-center rounded-lg text-gray-600 transition-colors hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-slate-800"
            >
              <HamburgerIcon />
            </button>
            <span className="ml-3 font-display text-sm font-semibold text-gray-900 dark:text-gray-50">
              Capa<span className="text-brand-600">Kraken</span>
            </span>
          </div>
          <PageTransition>{children}</PageTransition>
        </main>
        {chatOpen && <ChatPanel onClose={() => setChatOpen(false)} />}
      </div>
      {/* Floating chat FAB */}
      {!chatOpen && (
        <button
          type="button"
          onClick={() => setChatOpen(true)}
          data-testid="assistant-open-button"
          className="fixed bottom-6 right-6 z-30 flex h-14 w-14 items-center justify-center rounded-full bg-brand-600 text-white shadow-lg shadow-brand-600/30 transition-all hover:bg-brand-700 hover:shadow-xl hover:shadow-brand-600/40 active:scale-95"
          title="HartBOT"
        >
          <svg className="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"
            />
          </svg>
        </button>
      )}
      {prefsOpen && <PreferencesModal onClose={() => setPrefsOpen(false)} />}
    </ThemeProvider>
  );
}
