'use client';

import {usePathname} from 'next/navigation';
import {
  SideNav,
  SideNavItem,
  SideNavSection,
} from '@astryxdesign/core/SideNav';
import {Divider} from '@astryxdesign/core/Divider';
import {VStack} from '@astryxdesign/core/Layout';
import {AccountMenu} from './AccountMenu';
import {SideNavBrand} from './SideNavBrand';
import {NAV_RAIL_ID, useSidebar} from './SidebarProvider';
import {FOOTER_NAV, PRIMARY_NAV, isNavActive} from './nav-config';

/**
 * 260px expanded, 84px collapsed, Settings pinned to the bottom.
 *
 * ── Why the collapsed rail is restyled ────────────────────────────────────
 * Astryx's collapsed rail is --spacing-12 (48px) holding 32px items around
 * 16px icons. At a glance that reads as a scrollbar with symbols in it, and a
 * 32px hit area is under every touch-target guideline there is. The rail is
 * widened to 84px with 44px items around 24px icons — the Linear/Cursor
 * proportion, where a collapsed rail still reads as navigation.
 *
 * None of that is expressible through `defineTheme({components})`: the theme
 * layer can only reach an element's own themeProps, and SideNav publishes no
 * collapsed variant (`themeProps('side-nav')` takes only `mode`), while the
 * icon size is hardcoded to `sm` inside SideNavItem. So the three geometry
 * facts are set here, as token-backed Tailwind utilities scoped to this rail:
 *
 *   w-21                     84px = --spacing-1 × 21, the rail itself
 *   .astryx-side-nav-item    44px square, centred with margin-inline auto
 *   .astryx-icon             24px
 *
 * They win over Astryx's StyleX classes because astryx.css declares
 * `@layer astryx-base` and Tailwind's utilities layer sorts after it —
 * cascade layers outrank specificity, so no !important is involved.
 *
 * ── Why the collapse button is gone from here ─────────────────────────────
 * `hasButton: false`. A control that lives inside the sidebar vanishes with
 * the sidebar on mobile and, collapsed, sits in the one corner a user is
 * least likely to look. NavMenuButton in the top bar owns all three states —
 * see SidebarProvider.
 */

/** Applied only while collapsed. See the geometry note above. */
const COLLAPSED_RAIL = [
  'w-21',
  '[&_.astryx-side-nav-item]:size-11',
  '[&_.astryx-side-nav-item]:mx-auto',
  '[&_.astryx-icon]:size-6',
].join(' ');

/**
 * 200ms ease-in-out on width. Astryx's own --duration-medium is 260ms and its
 * --ease-standard is an ease-out; a rail that only decelerates into place
 * reads as heavier than one eased at both ends, which is what the brief asks
 * for. The logo, labels and icons animate on their own properties at the same
 * duration so the whole rail arrives together.
 */
const RAIL_MOTION = 'transition-[width] duration-200 ease-in-out';

export function AppSideNav() {
  const pathname = usePathname();
  const {isCollapsed, toggle} = useSidebar();

  return (
    <SideNav
      id={NAV_RAIL_ID}
      className={`${RAIL_MOTION} ${isCollapsed ? COLLAPSED_RAIL : ''}`}
      collapsible={{
        isCollapsed,
        // SideNav still drives its own children (icon-only items, tooltips)
        // off this flag; it just no longer owns it.
        onCollapsedChange: toggle,
        hasButton: false,
      }}
      // Not resizable. Two reasons, one of them measurable: the drag handle
      // renders in overlay mode inside a wrapper that comes out 1px wider than
      // the panel it sits in, which gave the sidebar a permanent horizontal
      // scrollbar along its bottom edge (measured: scrollWidth 261 in a 260px
      // panel). And a rail whose width is a stored user preference cannot also
      // be the fixed 260/84 pair the collapse animation moves between —
      // resizing and collapsing were fighting for the same property.
      header={<SideNavBrand />}
      footer={
        <VStack gap={3} width="100%">
          <Divider />
          <AccountMenu />
        </VStack>
      }
    >
      <SideNavSection title="Workspace" isHeaderHidden>
        {PRIMARY_NAV.map((item) => (
          <SideNavItem
            key={item.href}
            label={item.label}
            icon={item.icon}
            href={item.href}
            isSelected={isNavActive(pathname, item.href)}
          />
        ))}
      </SideNavSection>
    </SideNav>
  );
}
