"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 { Suspense, useMemo, 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";

function IconFrame({ children }: { children: ReactNode }) {
  return (
    <span className="flex h-8 w-8 items-center justify-center rounded-xl border border-white/60 bg-white/80 text-slate-600 shadow-sm transition-shadow duration-200 hover:shadow-[0_0_12px_rgba(var(--accent-500),0.15)] dark:border-slate-800 dark:bg-slate-900/70 dark:text-slate-300">
      {children}
    </span>
  );
}

function DashboardIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M4 13h6V5H4v8zm10 6h6V5h-6v14zM4 19h6v-2H4v2zm0-4h6v-2H4v2zm10 4h6v-6h-6v6z" /></svg>;
}
function ResourcesIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M16 21v-2a4 4 0 00-4-4H6a4 4 0 00-4 4v2m18 0v-2a4 4 0 00-3-3.87M14 3.13a4 4 0 010 7.75M12 7a4 4 0 11-8 0 4 4 0 018 0z" /></svg>;
}
function ProjectsIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M3 7h18M7 3v4m10-4v4M5 11h14v8H5z" /></svg>;
}
function EstimatesIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M8 7h8M8 11h4m-4 4h8M5 4h14a2 2 0 012 2v12a2 2 0 01-2 2H5a2 2 0 01-2-2V6a2 2 0 012-2z" /></svg>;
}
function AllocationsIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M8 7V3m8 4V3M4 11h16M5 5h14a1 1 0 011 1v13a1 1 0 01-1 1H5a1 1 0 01-1-1V6a1 1 0 011-1z" /></svg>;
}
function TimelineIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M4 6h16M4 12h10M4 18h7m9-8h-4m4 6h-7" /></svg>;
}
function StaffingIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M12 20l9-5-9-5-9 5 9 5zm0-10l9-5-9-5-9 5 9 5zm0 10v-10" /></svg>;
}
function VacationIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M4 19c3-4 6-6 8-6s5 2 8 6M7 12c.8-2.5 2.5-4 5-4s4.2 1.5 5 4M12 8V4" /></svg>;
}
function RolesIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M7 7h10v10H7zM4 4h4m8 0h4m-4 16h4M4 20h4" /></svg>;
}
function SkillsIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M12 3l2.8 5.7 6.2.9-4.5 4.4 1 6.2L12 17.2 6.5 20.2l1-6.2L3 9.6l6.2-.9L12 3z" /></svg>;
}
function ChargeabilityIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M5 17l4-4 3 3 7-8M19 19H5V5" /></svg>;
}
function GraphIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><circle cx="6" cy="6" r="2.5" strokeWidth={1.8} /><circle cx="18" cy="6" r="2.5" strokeWidth={1.8} /><circle cx="12" cy="18" r="2.5" strokeWidth={1.8} /><path strokeLinecap="round" strokeWidth={1.8} d="M8.5 7.5l2 7M15.5 7.5l-2 7M8.5 6h7" /></svg>;
}
function NotificationsIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6 6 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" /></svg>;
}
function BroadcastIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M11 5.882V19.24a1.76 1.76 0 01-3.417.592l-2.147-6.15M18 13a3 3 0 100-6M5.436 13.683A4.001 4.001 0 017 6h1.832c4.1 0 7.625-1.234 9.168-3v14c-1.543-1.766-5.067-3-9.168-3H7a3.988 3.988 0 01-1.564-.317z" /></svg>;
}
function AdminIcon() {
  return <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.8} d="M12 8a4 4 0 100 8 4 4 0 000-8zm8 4l-2.1.7a7.9 7.9 0 01-.6 1.5l1 2-2.1 2.1-2-1a7.9 7.9 0 01-1.5.6L12 20l-1.7-2.1a7.9 7.9 0 01-1.5-.6l-2 1-2.1-2.1 1-2a7.9 7.9 0 01-.6-1.5L4 12l2.1-1.7a7.9 7.9 0 01.6-1.5l-1-2 2.1-2.1 2 1a7.9 7.9 0 011.5-.6L12 4l1.7 2.1a7.9 7.9 0 011.5.6l2-1 2.1 2.1-1 2a7.9 7.9 0 01.6 1.5L20 12z" /></svg>;
}

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: "/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: "/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 Analytics", icon: <SkillsIcon />, roles: ["ADMIN", "MANAGER", "CONTROLLER", "VIEWER"] },
      { href: "/reports/chargeability", label: "Chargeability", icon: <ChargeabilityIcon />, roles: ["ADMIN", "MANAGER", "CONTROLLER"] },
      { href: "/analytics/computation-graph", label: "Computation Graph", icon: <GraphIcon />, 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"] },
    ],
  },
];

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: <AdminIcon /> },
  { href: "/admin/clients", label: "Clients", icon: <AdminIcon /> },
  {
    label: "ACN-Orga",
    collapsed: true,
    items: [
      { href: "/admin/countries", label: "Countries", icon: <AdminIcon /> },
      { href: "/admin/org-units", label: "Org Units", icon: <AdminIcon /> },
      { href: "/admin/utilization-categories", label: "Util. Categories", icon: <AdminIcon /> },
      { href: "/admin/management-levels", label: "Mgmt Levels", icon: <AdminIcon /> },
    ],
  },
  { href: "/admin/calculation-rules", label: "Calc. Rules", icon: <AdminIcon /> },
  { href: "/admin/users", label: "Users", icon: <AdminIcon /> },
  { href: "/admin/system-roles", label: "System Roles", icon: <AdminIcon /> },
  { href: "/admin/settings", label: "Settings", icon: <AdminIcon /> },
  { href: "/admin/skill-import", label: "Skill Import", icon: <AdminIcon /> },
  { href: "/admin/notifications", label: "Broadcasts", icon: <BroadcastIcon /> },
];

/**
 * Collect every href registered in the sidebar so that the active-check
 * can determine whether a more-specific sibling matches the current path.
 * Example: when pathname is `/vacations/my`, the item `/vacations` must NOT
 * highlight because `/vacations/my` is a more-specific registered route.
 */
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;
  // pathname starts with `href/...` — but a more-specific registered route may match.
  // If another nav href is a longer prefix match, this shorter one should NOT be active.
  const hasMoreSpecificSibling = ALL_NAV_HREFS.some(
    (other) => other !== href && other.length > href.length && pathname.startsWith(other),
  );
  return !hasMoreSpecificSibling;
}

function Sidebar({ userRole, onChatOpen }: { userRole: string; onChatOpen: () => void }) {
  const pathname = usePathname();
  const [prefsOpen, setPrefsOpen] = useState(false);

  // Memoize active href set — avoids O(n²) on every render
  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";

  // Sections and sub-groups auto-expand when the current route matches an item inside them
  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] }));
  };

  return (
    <>
      <nav className="w-72 shrink-0 border-r border-gray-200/60 bg-white/60 shadow-[1px_0_12px_rgba(0,0,0,0.03)] backdrop-blur-2xl backdrop-saturate-150 dark:border-slate-800 dark:bg-slate-950/75 dark:shadow-none flex flex-col">
        {/* Logo */}
        <div className="border-b border-gray-200/80 px-6 py-6 dark:border-slate-800">
          <div className="inline-flex items-center gap-3 rounded-2xl border border-brand-200/70 bg-gradient-to-br from-white to-brand-50 px-4 py-3 shadow-sm dark:border-brand-900/50 dark:from-slate-950 dark:to-slate-900">
            <div className="flex h-10 w-10 items-center justify-center rounded-2xl bg-brand-600 text-white shadow-lg shadow-brand-600/25">
              <DashboardIcon />
            </div>
            <div>
              <h1 className="font-display text-xl font-semibold text-gray-900 dark:text-gray-50">
                Pl<span className="text-brand-600">anarchy</span>
              </h1>
              <p className="text-xs uppercase tracking-[0.18em] text-gray-500 dark:text-gray-400">Resource Planning</p>
            </div>
          </div>
        </div>

        {/* Nav links */}
        <div className="flex-1 overflow-y-auto px-4 py-5">
          {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" : ""}>
                <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>
                <AnimatePresence initial={false}>
                  {!isCollapsed && (
                    <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="space-y-0.5">
                        {section.items.map((item) => {
                          const isActive = activeHrefSet.has(item.href);
                          return (
                            <Link
                              key={item.href}
                              href={item.href as Route}
                              className={clsx(
                                "group relative flex items-center gap-3 rounded-2xl px-3 py-2 text-sm font-medium transition-colors",
                                isActive
                                  ? "text-brand-800 dark:text-brand-200"
                                  : "text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-slate-900 dark:hover:text-white",
                              )}
                            >
                              {isActive && (
                                <motion.div
                                  layoutId="nav-indicator"
                                  className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-100 to-brand-50/80 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-900/30 dark:to-brand-800/20 dark:ring-brand-900/40"
                                  transition={{ type: "spring", stiffness: 350, damping: 30 }}
                                />
                              )}
                              <IconFrame>{item.icon}</IconFrame>
                              <span className="relative flex-1">{item.label}</span>
                            </Link>
                          );
                        })}
                      </div>
                    </motion.div>
                  )}
                </AnimatePresence>
              </div>
            );
          })}

          {showManagerSection && showAdmin && (
            <div className="mt-2">
              <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>
              <div className="space-y-0.5">
                {adminNavEntries.map((entry) => {
                  if (isSubGroup(entry)) {
                    const subCollapsed = collapsedSections[entry.label] ?? false;
                    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-slate-900 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}
                                      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-800 dark:text-brand-200"
                                          : "text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-slate-900 dark:hover:text-white",
                                      )}
                                    >
                                      {isActive && (
                                        <motion.div
                                          layoutId="nav-indicator"
                                          className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-100 to-brand-50/80 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-900/30 dark:to-brand-800/20 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>
                    );
                  }
                  const isActive = activeHrefSet.has(entry.href);
                  return (
                    <Link
                      key={entry.href}
                      href={entry.href as Route}
                      className={clsx(
                        "group relative flex items-center gap-3 rounded-2xl px-3 py-2 text-sm font-medium transition-colors",
                        isActive
                          ? "text-brand-800 dark:text-brand-200"
                          : "text-gray-700 hover:bg-gray-100/90 hover:text-gray-900 dark:text-gray-300 dark:hover:bg-slate-900 dark:hover:text-white",
                      )}
                    >
                      {isActive && (
                        <motion.div
                          layoutId="nav-indicator"
                          className="absolute inset-0 rounded-2xl bg-gradient-to-r from-brand-100 to-brand-50/80 shadow-sm ring-1 ring-brand-200/80 dark:from-brand-900/30 dark:to-brand-800/20 dark:ring-brand-900/40"
                          transition={{ type: "spring", stiffness: 350, damping: 30 }}
                        />
                      )}
                      <IconFrame>{entry.icon}</IconFrame>
                      <span className="relative flex-1">{entry.label}</span>
                    </Link>
                  );
                })}
              </div>
            </div>
          )}
        </div>

        {/* Bottom actions */}
        <div className="space-y-1 border-t border-gray-200/80 p-4 dark:border-slate-800">
          <div className="flex items-center gap-2 px-3 py-2">
            <NotificationBell />
            <span className="text-xs uppercase tracking-[0.16em] text-gray-400 dark:text-gray-500">Notifications</span>
          </div>
          <button
            type="button"
            onClick={onChatOpen}
            className="flex w-full items-center gap-3 rounded-2xl px-3 py-2.5 text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-slate-900"
          >
            <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>
            <span>HartBOT</span>
          </button>
          <button
            type="button"
            onClick={() => setPrefsOpen(true)}
            className="flex w-full items-center gap-3 rounded-2xl px-3 py-2.5 text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-slate-900"
          >
            <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>
            <span>Preferences</span>
          </button>
          <button
            type="button"
            onClick={() => void signOut({ callbackUrl: "/auth/signin" })}
            className="flex w-full items-center gap-3 rounded-2xl px-3 py-2.5 text-sm text-gray-700 transition-colors hover:bg-gray-100/90 dark:text-gray-300 dark:hover:bg-slate-900"
          >
            <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>
            <span>Sign out</span>
          </button>
        </div>
      </nav>

      {prefsOpen && <PreferencesModal onClose={() => setPrefsOpen(false)} />}
    </>
  );
}

export function AppShell({ children, userRole = "USER" }: { children: React.ReactNode; userRole?: string }) {
  const [chatOpen, setChatOpen] = useState(false);

  return (
    <ThemeProvider>
      <Suspense>
        <NavProgressBar />
      </Suspense>
      <div className="flex h-screen bg-transparent">
        <Sidebar userRole={userRole} onChatOpen={() => setChatOpen(true)} />
        <main className="flex-1 overflow-auto bg-transparent">
          <PageTransition>{children}</PageTransition>
        </main>
        {chatOpen && <ChatPanel onClose={() => setChatOpen(false)} />}
      </div>
      {/* Floating chat FAB — always visible when panel is closed */}
      {!chatOpen && (
        <button
          type="button"
          onClick={() => setChatOpen(true)}
          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>
      )}
    </ThemeProvider>
  );
}
