// App Shell V2 (Phase 22) — collapsible sidebar + refined top bar + profile popover.
//
// Behavior contract:
//   • Default sidebar state: collapsed (72px wide, icon-only). Persisted in
//     localStorage as 'mygeni:sidebar' = 'collapsed' | 'expanded'.
//   • Two toggle affordances (upper — next to the workspace mark; lower —
//     the bottom user tile). Both flip the same state.
//   • Route change does NOT touch sidebar state.
//   • Hover on collapsed items shows a CSS tooltip (label + optional badge).
//   • Layout uses a CSS custom prop `--shell-nav-w` on the shell root so the
//     sidebar column and main column animate together; no layout jump.
//
// useHashRoute is UNCHANGED — the routing contract from Phase 21 must not
// move. Only the visual chrome around it is upgraded.

function _navPrimary() {
  const inboxNeeds = (window.MYGENI_DATA?.inboxItems || [])
    .filter(i => i.state === 'needs-action').length;
  const overdueWork = (window.MYGENI_DATA?.workItems || [])
    .filter(w => w.dueBucket === 'overdue' && w.status !== 'done').length;

  const items = [
    { key: 'home',      route: '#/home',      label: 'Home',      icon: 'home' },
    { key: 'projects',  route: '#/projects',  label: 'Projects',  icon: 'projects' },
    { key: 'my-work',   route: '#/my-work',   label: 'My Work',   icon: 'work' },
    { key: 'decisions', route: '#/decisions', label: 'Decisions', icon: 'decisions' },
    { key: 'inbox',     route: '#/inbox',     label: 'Inbox',     icon: 'inbox' },
  ];
  if (overdueWork > 0) {
    const mw = items.find(i => i.key === 'my-work');
    mw.badge = String(overdueWork); mw.badgeTone = 'orange';
  }
  if (inboxNeeds > 0) {
    const ib = items.find(i => i.key === 'inbox');
    ib.badge = String(inboxNeeds); ib.badgeTone = 'red';
  }
  return items;
}

const NAV_SECONDARY = [
  { key: 'clients',   route: '#/clients',   label: 'Clients',   icon: 'building' },
];

const NAV_UTIL = [
  { key: 'settings', route: '#/settings', label: 'Settings', icon: 'settings' },
];

function useHashRoute(defaultRoute = 'home') {
  const parse = (h) => {
    const m = (h || '').match(/^#\/(.+)$/);
    if (!m) return { full: defaultRoute, top: defaultRoute, sub1: null, sub2: null, sub3: null, sub4: null };
    const full = m[1];
    const parts = full.split('/');
    return { full, top: parts[0], sub1: parts[1] || null, sub2: parts[2] || null, sub3: parts[3] || null, sub4: parts[4] || null };
  };
  const [route, setRoute] = React.useState(() => {
    const initial = (typeof location !== 'undefined' && location.hash) || '';
    if (initial) return parse(initial);
    const stored = localStorage.getItem('mygeni:route');
    if (stored) return parse('#/' + stored);
    return { full: defaultRoute, top: defaultRoute, sub1: null, sub2: null };
  });
  React.useEffect(() => {
    const onHash = () => {
      const r = parse(location.hash);
      setRoute(r);
      localStorage.setItem('mygeni:route', r.full);
    };
    window.addEventListener('hashchange', onHash);
    if (!location.hash) location.hash = '#/' + route.full;
    return () => window.removeEventListener('hashchange', onHash);
  }, [defaultRoute]);
  return route;
}

// Global sidebar state hook. Persisted; default = collapsed.
function useSidebarState() {
  const [state, setState] = React.useState(() => {
    if (typeof localStorage === 'undefined') return 'collapsed';
    const v = localStorage.getItem('mygeni:sidebar');
    return (v === 'expanded' || v === 'collapsed') ? v : 'collapsed';
  });
  React.useEffect(() => {
    try { localStorage.setItem('mygeni:sidebar', state); } catch (e) {}
    // Reflect on shell root as a CSS var so both columns transition.
    const root = document.querySelector('.shell');
    if (root) {
      root.setAttribute('data-sidebar', state);
      root.style.setProperty('--shell-nav-w', state === 'expanded' ? '232px' : '72px');
    }
  }, [state]);
  return [state, setState];
}

function SidebarItem({ item, active, collapsed }) {
  return (
    <a href={item.route}
       className={`side-item${active ? ' active' : ''}`}
       data-collapsed={collapsed ? '1' : '0'}
       data-tip={collapsed ? item.label : null}
    >
      <Icon name={item.icon} size={20} className="side-icon" strokeWidth={1.6} />
      <span className="side-label">{item.label}</span>
      {item.badge && (
        <span className={`side-badge ${item.badgeTone || ''}`}>{item.badge}</span>
      )}
    </a>
  );
}

function SidebarToggle({ collapsed, onToggle, position }) {
  // "position" is 'top' or 'bottom' — two identical affordances so it's
  // obvious how to collapse/expand from either end of the sidebar.
  const label = collapsed ? 'Expand sidebar' : 'Collapse sidebar';
  return (
    <button
      className={`side-toggle side-toggle-${position}`}
      onClick={onToggle}
      aria-label={label}
      title={label}
      data-tip={collapsed && position === 'top' ? 'Expand sidebar' : null}
    >
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none"
           style={{ transform: collapsed ? 'rotate(0deg)' : 'rotate(180deg)', transition: 'transform 200ms ease' }}>
        <path d="M9 6l6 6-6 6" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
    </button>
  );
}

function Sidebar({ active, workspace, user }) {
  const [sidebarState, setSidebarState] = useSidebarState();
  const collapsed = sidebarState === 'collapsed';
  const toggle = () => setSidebarState(collapsed ? 'expanded' : 'collapsed');

  return (
    <aside className={`side side-v2 ${collapsed ? 'side-collapsed' : 'side-expanded'}`}>
      <div className="side-ws" role="button" aria-label="Switch workspace">
        <div className="brand-mark" style={{ color: 'white' }}>
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" aria-label="My Geni">
            <circle cx="12" cy="12" r="8.5" fill="currentColor" opacity="0.18" />
            <path d="M18.2 8.2 A 7 7 0 1 0 19 12 H 13"
                  fill="none" stroke="currentColor"
                  strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" />
            <circle cx="12" cy="12" r="1.6" fill="currentColor" />
          </svg>
        </div>
        <div className="ws-meta">
          <div className="ws-1">{workspace.name}</div>
          <div className="ws-2">Product Operating System</div>
        </div>
        <SidebarToggle collapsed={collapsed} onToggle={toggle} position="top" />
      </div>

      <div className="side-search" role="button" data-tip={collapsed ? 'Search · ⌘K' : null}>
        <Icon name="search" size={16} strokeWidth={1.75} />
        <span className="side-label">Jump to…</span>
        <span className="kbd">⌘K</span>
      </div>

      <nav aria-label="Primary">
        {_navPrimary().map((it) => (
          <SidebarItem key={it.key} item={it} active={it.key === active} collapsed={collapsed} />
        ))}
      </nav>

      <div className="side-divider" />

      <nav aria-label="People">
        {NAV_SECONDARY.map((it) => (
          <SidebarItem key={it.key} item={it} active={it.key === active} collapsed={collapsed} />
        ))}
      </nav>

      <div className="side-spacer" />

      <nav aria-label="Utility" style={{ marginBottom: 6 }}>
        {NAV_UTIL.map((it) => (
          <SidebarItem key={it.key} item={it} active={it.key === active} collapsed={collapsed} />
        ))}
      </nav>

      <div className="side-user" role="button" onClick={toggle}
           data-tip={collapsed ? `${user.name} · click to expand` : null}>
        <Avatar name={user.name} size="md" />
        <div className="u-meta side-label">
          <div className="u-name">{user.name}</div>
          <div className="u-role">{user.role}</div>
        </div>
        <SidebarToggle collapsed={collapsed} onToggle={toggle} position="bottom" />
      </div>
    </aside>
  );
}

// Breadcrumb per route (top-level only; project chrome handles nested wayfinding).
const CRUMBS = {
  home:            ['Home'],
  projects:        ['Projects'],
  'my-work':       ['My Work'],
  decisions:       ['Decisions'],
  inbox:           ['Inbox'],
  clients:         ['Clients'],
  settings:        ['Settings'],
  'design-system': ['Design system'],
};

// --- Top-right profile popover (Phase 22).
function ProfileMenu({ user }) {
  const [open, setOpen] = React.useState(false);
  const anchorRef = React.useRef(null);
  const popRef = React.useRef(null);

  React.useEffect(() => {
    function onDown(e) {
      if (!open) return;
      if (popRef.current && popRef.current.contains(e.target)) return;
      if (anchorRef.current && anchorRef.current.contains(e.target)) return;
      setOpen(false);
    }
    function onKey(e) { if (e.key === 'Escape') setOpen(false); }
    document.addEventListener('mousedown', onDown);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDown);
      document.removeEventListener('keydown', onKey);
    };
  }, [open]);

  // Close on route change
  React.useEffect(() => {
    function onHash() { setOpen(false); }
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  const R = window.MYGENI_PEOPLE;
  const entry = R && R.get(user.name);

  return (
    <div style={{ position: 'relative' }} ref={anchorRef}>
      <button
        className="icon-btn"
        aria-label="Profile"
        title={user.name}
        onClick={() => setOpen(v => !v)}
        style={{ padding: 0, width: 36, height: 36, borderRadius: '50%', overflow: 'hidden' }}
      >
        <Avatar name={user.name} size="md" />
      </button>
      {open && (
        <div ref={popRef} className="profile-popover">
          <div className="pp-head">
            <Avatar name={user.name} size="xl" />
            <div className="pp-id">
              <div className="pp-name">{user.name}</div>
              <div className="pp-role">{user.role}</div>
              <div className="pp-status">
                <span className="pp-dot" /> <span>Available</span>
              </div>
            </div>
          </div>
          <div className="pp-sep" />
          <a className="pp-row" href="#/home"          onClick={() => setOpen(false)}>
            <Icon name="home" size={16} strokeWidth={1.7} /><span>Home</span>
          </a>
          <a className="pp-row" href="#/my-work"       onClick={() => setOpen(false)}>
            <Icon name="work" size={16} strokeWidth={1.7} /><span>My Work</span>
          </a>
          <a className="pp-row" href="#/settings"      onClick={() => setOpen(false)}>
            <Icon name="settings" size={16} strokeWidth={1.7} /><span>Preferences</span>
          </a>
          <div className="pp-sep" />
          <button className="pp-row pp-row-btn" onClick={() => setOpen(false)}>
            <Icon name="moreH" size={16} strokeWidth={1.7} /><span>Sign out</span>
            <span className="pp-mock">local mock</span>
          </button>
          <div className="pp-foot">MY&nbsp;GENI · v2 · local prototype</div>
        </div>
      )}
    </div>
  );
}

function Header({ workspace, route, user }) {
  const crumbs = CRUMBS[route] || [route.replace(/-/g, ' ')];
  const inboxNeeds = (window.MYGENI_DATA?.inboxItems || [])
    .filter(i => i.state === 'needs-action').length;
  return (
    <header className="header header-v2">
      <div className="crumb">
        <span>{workspace.product}</span>
        <Icon name="chevronRight" size={14} className="sep" strokeWidth={2} />
        <span className="now">{crumbs[0]}</span>
      </div>

      <div className="header-spacer" />

      <div className="header-search" role="button">
        <Icon name="search" size={16} strokeWidth={1.75} />
        <span>Search across {workspace.product}…</span>
        <span className="kbd">⌘K</span>
      </div>

      <a className="btn btn-white" title="Open Inbox" href="#/inbox" style={{ textDecoration: 'none' }}>
        <Icon name="inbox" size={16} strokeWidth={1.75} />
        <span>Inbox</span>
        {inboxNeeds > 0 && (
          <span
            style={{
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              minWidth: 22, height: 22, padding: '0 7px',
              borderRadius: 8, background: 'var(--secondary-01)', color: 'var(--shade-02)',
              fontSize: 12, fontWeight: 700, letterSpacing: '-0.015em',
              marginLeft: 2,
            }}
          >
            {inboxNeeds}
          </span>
        )}
      </a>

      <button className="icon-btn" title="Notifications" aria-label="Notifications">
        <Icon name="bell" size={18} strokeWidth={1.75} />
        <span className="dot" />
      </button>

      <button className="btn btn-primary">
        <Icon name="plus" size={16} strokeWidth={2} />
        <span>Create</span>
      </button>

      {user && <ProfileMenu user={user} />}
    </header>
  );
}

Object.assign(window, { Sidebar, Header, useHashRoute });
