/**
 * SidebarNav — WealthX Design System
 *
 * Presentational sidebar navigation organism.
 * Used by both Backoffice (Wealth Pro) and Frontend (WealthX app).
 *
 * Background: bg-brand-secondary (tenant dark navy — set via ThemeProvider).
 * Text:       text-brand-secondary-foreground (white on dark navy).
 *
 * - All icons must be Lucide icons (LucideIcon type).
 * - Supports collapsible sub-items (accordion).
 * - Hover mode (default): sidebar is icon-only; hovering expands it temporarily.
 * - Lock mode: clicking the Pin button keeps the sidebar expanded after mouse leaves.
 * - metricsGroups: optional financial summary rows (Frontend sidebar only).
 * - No internal navigation — consumers wire onNavigate / onLogout.
 */
import * as React from "react";
import {
  ChevronDown,
  ChevronRight,
  Info,
  LogOut,
  Pin,
  PinOff,
} from "lucide-react";
import type { LucideIcon } from "lucide-react";
import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
import { cn, getInitials } from "@/lib/utils";
import { formatCurrency } from "@/lib/format-currency";
import { Accordion, AccordionContent, AccordionItem } from "./accordion";
import { Button } from "./button";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";

// ─── Types ─────────────────────────────────────────────────────────────────────

export interface SidebarNavSubItem {
  title: string;
  href: string;
  isActive?: boolean;
}

export interface SidebarNavItem {
  /** Lucide icon component */
  icon: LucideIcon;
  title: string;
  href: string;
  isActive?: boolean;
  /** When true, renders an expandable group with subItems */
  isCollapsible?: boolean;
  subItems?: SidebarNavSubItem[];
}

export interface SidebarNavMetricItem {
  name: string;
  /** Numeric value in dollars — formatted as currency automatically */
  value: number;
  /** Net items show +/- prefix and a primary-color underline */
  isNetItem?: boolean;
  /** Optional tooltip text shown via Info icon */
  info?: string;
}

export interface SidebarNavMetricsGroup {
  items: SidebarNavMetricItem[];
}

export interface SidebarNavProps {
  items: SidebarNavItem[];
  /** Display name for the current user */
  userName?: string;
  /**
   * Optional logo URL rendered at the top of the sidebar.
   * Hidden when collapsed (unless logoCollapsed is provided).
   * Use a horizontal/landscape logo (max-height 32px).
   * The image is rendered white via CSS filter — use a logo with non-transparent paths.
   */
  logo?: string;
  /**
   * Optional icon-only logo URL shown when the sidebar is collapsed.
   * Use a square icon variant of the logo (rendered at 32×32px, white filter applied).
   */
  logoCollapsed?: string;
  /**
   * Optional financial metric groups rendered between the user section and
   * nav items. Hidden when sidebar is collapsed. Used by the Frontend (WealthX app) sidebar.
   */
  metricsGroups?: SidebarNavMetricsGroup[];
  onNavigate?: (href: string) => void;
  onLogout?: () => void;
  /**
   * Initial locked (pinned) state. When true, sidebar starts expanded and stays
   * open even without hover. Defaults to false (hover-to-expand mode).
   */
  defaultLocked?: boolean;
  /**
   * Called when the user toggles the Pin/Unpin button.
   * Use to persist the preference (e.g. localStorage).
   */
  onLockedChange?: (locked: boolean) => void;
  className?: string;
}

// ─── Helpers ───────────────────────────────────────────────────────────────────

function navIconCn(isActive: boolean): string {
  return cn(
    "shrink-0 transition-colors",
    isActive
      ? "text-primary"
      : "text-brand-secondary-foreground/50 group-hover:text-brand-secondary-foreground",
  );
}

// ─── NavTooltip ────────────────────────────────────────────────────────────────
// Wraps content in a right-side tooltip only when the sidebar is collapsed.

interface NavTooltipProps {
  label: string;
  collapsed: boolean;
  children: React.ReactElement;
}

function NavTooltip({ label, collapsed, children }: NavTooltipProps) {
  if (!collapsed) return children;
  return (
    <Tooltip>
      <TooltipTrigger render={children} />
      <TooltipContent side="right">{label}</TooltipContent>
    </Tooltip>
  );
}

// ─── MetricsGroup ──────────────────────────────────────────────────────────────

interface MetricsGroupProps {
  group: SidebarNavMetricsGroup;
}

function MetricsGroup({ group }: MetricsGroupProps) {
  return (
    <div className="border-b border-white/15 py-4 px-5 flex flex-col gap-1.5">
      {group.items.map((item) => (
        <div
          key={item.name}
          className="flex items-center justify-between gap-2"
        >
          <div className="flex items-center gap-1 min-w-0">
            <span
              className={cn(
                "text-sm truncate text-brand-secondary-foreground/80",
                item.isNetItem &&
                  "font-semibold text-brand-secondary-foreground border-b-2 border-primary pb-px",
              )}
            >
              {item.name}
            </span>
            {item.info && (
              <Info
                size={11}
                strokeWidth={2}
                className="shrink-0 text-brand-secondary-foreground/50"
              />
            )}
          </div>
          <span
            className={cn(
              "text-sm font-semibold tabular-nums shrink-0 text-brand-secondary-foreground",
              item.isNetItem && item.value < 0 && "text-destructive",
            )}
          >
            {formatCurrency(item.value, { showSign: item.isNetItem })}
          </span>
        </div>
      ))}
    </div>
  );
}

// ─── SidebarNavItemView (single link) ──────────────────────────────────────────

interface SidebarNavItemViewProps {
  item: SidebarNavItem;
  collapsed: boolean;
  onNavigate?: (href: string) => void;
}

function SidebarNavItemView({
  item,
  collapsed,
  onNavigate,
}: SidebarNavItemViewProps) {
  const Icon = item.icon;

  return (
    <NavTooltip label={item.title} collapsed={collapsed}>
      <Button
        type="button"
        variant="ghost"
        onClick={() => onNavigate?.(item.href)}
        className={cn(
          "group h-auto w-full items-center gap-3 py-2.5 text-base font-medium transition-colors",
          "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
          collapsed
            ? "justify-center px-2"
            : cn(
                "justify-start px-3 border-l-4",
                item.isActive
                  ? "bg-white/15 text-brand-secondary-foreground border-primary"
                  : "border-transparent",
              ),
        )}
      >
        <Icon
          className={navIconCn(item.isActive ?? false)}
          size={24}
          strokeWidth={1.75}
        />
        {!collapsed && <span className="truncate">{item.title}</span>}
      </Button>
    </NavTooltip>
  );
}

// ─── CollapsibleNavItem (accordion group) ──────────────────────────────────────

interface CollapsibleNavItemProps {
  item: SidebarNavItem;
  collapsed: boolean;
  onNavigate?: (href: string) => void;
}

function CollapsibleNavItem({
  item,
  collapsed,
  onNavigate,
}: CollapsibleNavItemProps) {
  const Icon = item.icon;
  const hasActiveChild = item.subItems?.some((sub) => sub.isActive) ?? false;
  // The group is highlighted when its own landing page OR one of its sub-items
  // is active — not only when a child is selected.
  const isGroupActive = hasActiveChild || (item.isActive ?? false);
  const [open, setOpen] = React.useState(isGroupActive);

  React.useEffect(() => {
    if (isGroupActive) setOpen(true);
  }, [isGroupActive]);

  if (collapsed) {
    return (
      <NavTooltip label={item.title} collapsed={collapsed}>
        <Button
          type="button"
          variant="ghost"
          onClick={() => onNavigate?.(item.href)}
          className={cn(
            "group h-auto w-full justify-center px-2 py-2.5 transition-colors",
            "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
            isGroupActive && "bg-white/15 text-brand-secondary-foreground",
          )}
        >
          <Icon
            className={navIconCn(isGroupActive)}
            size={24}
            strokeWidth={1.75}
          />
        </Button>
      </NavTooltip>
    );
  }

  return (
    <Accordion
      value={open ? [item.href] : []}
      onValueChange={(values) => setOpen(values.length > 0)}
    >
      <AccordionItem className="border-none" value={item.href}>
        <AccordionPrimitive.Header className="flex">
          <AccordionPrimitive.Trigger
            onClick={() => onNavigate?.(item.href)}
            className={cn(
              "group flex h-auto w-full items-center justify-start gap-3 px-3 py-2.5 text-base font-medium transition-colors",
              "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground",
              "border-l-4 border-transparent",
              isGroupActive &&
                "bg-white/15 text-brand-secondary-foreground border-primary",
            )}
          >
            <Icon
              className={navIconCn(isGroupActive)}
              size={24}
              strokeWidth={1.75}
            />
            <span className="flex-1 truncate text-left">{item.title}</span>
            <ChevronDown
              className={cn(
                "ml-auto shrink-0 text-brand-secondary-foreground/40 transition-transform duration-200",
                "group-data-[panel-open]:rotate-180",
              )}
              size={14}
              strokeWidth={2}
            />
          </AccordionPrimitive.Trigger>
        </AccordionPrimitive.Header>

        {item.subItems && (
          <AccordionContent className="p-0 text-inherit">
            <div className="ml-9 border-l border-white/15 pl-3">
              {item.subItems.map((sub) => (
                <Button
                  key={sub.href}
                  type="button"
                  variant="ghost"
                  onClick={() => onNavigate?.(sub.href)}
                  className={cn(
                    "group h-auto w-full justify-start gap-2 py-1.5 pl-1 text-sm transition-colors",
                    // Hover bg is the light `accent`, so hover text/icon use the
                    // dark `accent-foreground` to stay readable.
                    "text-brand-secondary-foreground/50 hover:text-accent-foreground",
                    sub.isActive && "text-primary font-medium",
                  )}
                >
                  <ChevronRight
                    size={11}
                    strokeWidth={2}
                    className={cn(
                      "shrink-0",
                      sub.isActive
                        ? "text-primary"
                        : "text-brand-secondary-foreground/30 group-hover:text-accent-foreground",
                    )}
                  />
                  <span className="truncate">{sub.title}</span>
                </Button>
              ))}
            </div>
          </AccordionContent>
        )}
      </AccordionItem>
    </Accordion>
  );
}

// ─── SidebarNav (root) ─────────────────────────────────────────────────────────

export function SidebarNav({
  items,
  userName = "Anonymous User",
  logo,
  logoCollapsed,
  metricsGroups,
  onNavigate,
  onLogout,
  defaultLocked = false,
  onLockedChange,
  className,
}: SidebarNavProps) {
  const [isLocked, setIsLocked] = React.useState(defaultLocked);
  const [isHovered, setIsHovered] = React.useState(false);

  // Sidebar is expanded when pinned OR when the user is hovering over it.
  const isExpanded = isLocked || isHovered;

  const [userMenuOpen, setUserMenuOpen] = React.useState(false);
  const navScrollRef = React.useRef<HTMLDivElement>(null);
  const expandedScrollRef = React.useRef(0);

  const handleLockToggle = () => {
    const next = !isLocked;
    setIsLocked(next);
    onLockedChange?.(next);
  };

  React.useEffect(() => {
    if (!isExpanded) setUserMenuOpen(false);
  }, [isExpanded]);

  // Preserve nav items scroll position across collapse/expand transitions.
  // Cleanup saves scrollTop before the DOM changes; setup restores it when expanding.
  React.useLayoutEffect(() => {
    const nav = navScrollRef.current;
    if (!nav) return;
    if (isExpanded) {
      nav.scrollTop = expandedScrollRef.current;
    }
    return () => {
      if (isExpanded && nav) {
        expandedScrollRef.current = nav.scrollTop;
      }
    };
  }, [isExpanded]);

  return (
    <TooltipProvider>
      <nav
        data-slot="sidebar-nav"
        data-expanded={isExpanded}
        data-locked={isLocked}
        onMouseEnter={() => setIsHovered(true)}
        onMouseLeave={() => setIsHovered(false)}
        className={cn(
          "flex h-full flex-col bg-brand-secondary text-brand-secondary-foreground",
          "transition-all duration-200 ease-in-out",
          isExpanded ? "w-[279px]" : "w-14",
          className,
        )}
      >
        {/* Logo — crossfade between full and icon variant */}
        {(logo || logoCollapsed) && (
          <div className="relative flex items-center border-b border-white/15 py-4 overflow-hidden">
            {logo && (
              <img
                src={logo}
                alt="Logo"
                className={cn(
                  "h-8 w-auto object-contain object-left px-5 transition-opacity duration-200",
                  !isExpanded ? "opacity-0" : "opacity-100",
                )}
              />
            )}
            {logoCollapsed && (
              <img
                src={logoCollapsed}
                alt="Logo"
                className={cn(
                  "absolute inset-y-0 left-0 right-0 m-auto h-8 w-8 object-contain transition-opacity duration-200",
                  !isExpanded ? "opacity-100" : "opacity-0",
                )}
              />
            )}
          </div>
        )}

        {/* User section — crossfade between expanded and collapsed */}
        <div className="relative border-b border-white/15">
          {/* Expanded — in flow (defines height), no transition (overlay handles it) */}
          <div
            className={cn(
              !isExpanded ? "opacity-0 pointer-events-none" : "opacity-100",
            )}
          >
            <Accordion
              value={userMenuOpen ? ["user-menu"] : []}
              onValueChange={(values) => setUserMenuOpen(values.length > 0)}
            >
              <AccordionItem className="border-none" value="user-menu">
                <AccordionPrimitive.Header className="flex">
                  <AccordionPrimitive.Trigger
                    className={cn(
                      "group flex h-auto w-full items-center justify-start gap-3 px-5 py-5 text-base transition-colors",
                      "text-brand-secondary-foreground hover:bg-white/10",
                    )}
                  >
                    <div className="flex h-8 w-8 shrink-0 items-center justify-center font-semibold text-xs bg-primary text-primary-foreground">
                      {getInitials(userName)}
                    </div>
                    <span className="flex-1 truncate text-left font-medium text-brand-secondary-foreground">
                      {userName}
                    </span>
                    <ChevronDown
                      className="ml-auto shrink-0 text-brand-secondary-foreground/50 transition-transform duration-200 group-data-[panel-open]:rotate-180"
                      size={16}
                      strokeWidth={2}
                    />
                  </AccordionPrimitive.Trigger>
                </AccordionPrimitive.Header>

                <AccordionContent className="p-0 text-inherit">
                  <div className="border-t border-white/15 bg-black/20">
                    <Button
                      type="button"
                      variant="ghost"
                      onClick={onLogout}
                      className={cn(
                        "h-auto w-full justify-start gap-3 px-5 py-3 text-base",
                        "text-brand-secondary-foreground/70 hover:bg-white/10 hover:text-brand-secondary-foreground transition-colors",
                      )}
                    >
                      <LogOut
                        size={16}
                        strokeWidth={1.75}
                        className="shrink-0 text-destructive"
                      />
                      <span>Logout</span>
                    </Button>
                  </div>
                </AccordionContent>
              </AccordionItem>
            </Accordion>
          </div>

          {/* Collapsed — absolute overlay, centered avatar */}
          <NavTooltip label={userName} collapsed={!isExpanded}>
            <div
              className={cn(
                "absolute inset-0 flex items-center justify-center transition-opacity duration-200",
                !isExpanded ? "opacity-100" : "opacity-0 pointer-events-none",
              )}
            >
              <div className="flex h-8 w-8 shrink-0 items-center justify-center font-semibold text-xs bg-primary text-primary-foreground">
                {getInitials(userName)}
              </div>
            </div>
          </NavTooltip>
        </div>

        {/* Financial metrics — animated in/out with sidebar expand to prevent nav items jumping */}
        {!!metricsGroups?.length && (
          <Accordion
            value={isExpanded ? ["metrics"] : []}
            onValueChange={() => {}}
          >
            <AccordionItem className="border-none" value="metrics">
              <AccordionContent className="p-0 text-inherit">
                {metricsGroups.map((group, i) => (
                  <MetricsGroup key={i} group={group} />
                ))}
              </AccordionContent>
            </AccordionItem>
          </Accordion>
        )}

        {/* Nav items */}
        <div ref={navScrollRef} className="flex flex-col overflow-y-auto py-3">
          {items.map((item) =>
            item.isCollapsible ? (
              <CollapsibleNavItem
                key={item.href}
                item={item}
                collapsed={!isExpanded}
                onNavigate={onNavigate}
              />
            ) : (
              <SidebarNavItemView
                key={item.href}
                item={item}
                collapsed={!isExpanded}
                onNavigate={onNavigate}
              />
            ),
          )}
        </div>

        {/* Pin / Unpin toggle — always visible */}
        <div className="mt-auto border-t border-white/15 bg-white/10">
          <NavTooltip
            label={isLocked ? "Unpin sidebar" : "Pin sidebar open"}
            collapsed={!isExpanded}
          >
            <Button
              type="button"
              variant="ghost"
              onClick={handleLockToggle}
              className={cn(
                "h-12 w-full items-center gap-3 py-3 transition-colors",
                "text-brand-secondary-foreground/80 hover:bg-white/10 hover:text-brand-secondary-foreground",
                isExpanded ? "justify-start px-3" : "justify-center px-2",
                isLocked && "text-primary",
              )}
            >
              {isLocked ? (
                <Pin size={24} strokeWidth={1.75} className="shrink-0" />
              ) : (
                <PinOff
                  size={24}
                  strokeWidth={1.75}
                  className="shrink-0 opacity-60"
                />
              )}
              {isExpanded && (
                <span className="text-sm">
                  {isLocked ? "Pinned" : "Pin sidebar"}
                </span>
              )}
            </Button>
          </NavTooltip>
        </div>
      </nav>
    </TooltipProvider>
  );
}
