/* Ward Desk shell — SIDEBAR shell in RAIL + PANEL mode, one navigation owner.
   The rail owns the category, the panel owns the destinations inside it, and the
   top bar is utility only: it holds no destination and repeats nothing.
   Frame: two navigation columns on one tinted plane, each divided by a single
   hairline; the content column sits flush on the page colour with no inset pane
   and is the only scroll owner.
   Density: tight — 28px nav rows, 20px page gutters, 40px table rows.
   Separation: full-bleed hairline rules and the gutter. No cards, no elevation
   inside the content column; rounding belongs to controls and to overlays.
   Active state: --sidebar-accent wash + foreground token + medium weight; the
   rail's active category takes the page colour and a hairline instead, so it
   reads as the selected tab of the panel beside it.
   App-scope duties: search → top bar, a read-only field that opens the palette ·
   session and account → the rail footer, at every width · utility →
   top bar (notifications, theme) · page context → the page header band.
   Primary content per destination:
     Today          — figure row, then the ward board and the four lists of work
                      that is actually waiting on somebody
     Patients       — directory table with a photo per row; /patients/:id is one
                      person's admission, chart, procedures and notes
     Admissions     — the ward board as a table, bed waits first
     Interventions  — today's theatre list as a timed ladder over the full table;
                      /interventions/:id is one procedure, its consent and team
     Medication     — orders table scoped by ward, with the dose clock per row
     Formulary      — stock table with a reorder bar per line
     Doctors        — directory of the medical family, by specialty
     Employees      — the whole badge list, by job family
     Feed           — one chronological feed of what the hospital did, and the
                      notes owed a reply
     Import/export  — job table, and the row-review screen an import needs
   Interventions is the destination that would most plausibly have been a plain
   table and is not: the question a theatre list answers is "what happens next,
   and can it start", which a timed ladder answers in one glance.
   Sign-in and the reset flow render with no shell at all (AGENTS §7.1). */

const {
  Button, Input, Kbd, Avatar, MenuItem, MenuGroupLabel,
  Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator,
  Toast, ToastRegion,
} = window.OriginDesignSystem_7c998b;

const HD_BRAND_MARK = "../../assets/templates/logos/24-logo-demo.svg";

/* One declaration for the whole shell: 1280 rail + panel · 1024 rail only, the
   panel's destinations become a flyout · below that one off-canvas drawer
   carrying both columns. */
function useShellMode() {
  const read = () => (window.innerWidth >= 1280 ? "expanded" : window.innerWidth >= 1024 ? "rail" : "drawer");
  const [mode, setMode] = React.useState(read);
  React.useEffect(() => {
    const onResize = () => setMode(read());
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, []);
  return mode;
}

function NavLink({ route, active, badge, onNavigate }) {
  return (
    <button type="button" className="hd-link" aria-current={active ? "page" : undefined} onClick={() => onNavigate(route.path)}>
      <Icon name={route.icon} size={15} />
      <span className="hd-link__label">{route.label}</span>
      {badge && badge.count > 0 ? <span className="hd-link__count" aria-label={badge.count + " " + badge.label}>{badge.count}</span> : null}
    </button>
  );
}

/* The rail. A category is not a route (nav.js says so), so these are tabs over
   the panel rather than links: they carry aria-selected, and the label survives
   as both a tooltip and an aria-label at every width. */
function CategoryRail({ categories, selected, path, data, viewer, onSelect, mode, onNavigate }) {
  return (
    <nav className="hd-rail" aria-label={HD_HOSPITAL.short + " — categories"}>
      <span className="hd-rail__brand" aria-hidden="true"><img src={HD_BRAND_MARK} alt="" width="20" height="20" /></span>
      <div className="hd-rail__list" role="tablist" aria-orientation="vertical" aria-label="Categories">
        {categories.map((category) => {
          const on = category.id === selected;
          const signal = categoryHasSignal(category, data, viewer.id);
          const button = (
            <button type="button" role="tab" className={"hd-cat" + (on ? " is-on" : "")} aria-selected={on} aria-label={category.label + " — " + category.note}
              aria-controls={mode === "expanded" ? "hd-panel" : undefined} onClick={() => onSelect(category.id)}>
              <Icon name={category.icon} size={18} />
              {signal ? <span className="hd-cat__dot" aria-hidden="true" /> : null}
            </button>
          );
          if (mode === "expanded") return <FloatingTip key={category.id} label={category.label}>{button}</FloatingTip>;
          /* Rail mode: the panel is gone, so the category opens its own list. */
          return (
            <Floating key={category.id} align="start" width="15rem" label={category.label} panelClass="o-menu hd-flyout"
              trigger={button}>
              {(close) => (
                <>
                  <span className="hd-flyout__title">{category.label} — {category.note}</span>
                  {category.items.map((route) => {
                    const spec = route.badge ? HD_NAV_BADGES[route.badge] : null;
                    const count = spec ? spec.count(data, viewer.id) : 0;
                    return (
                      <MenuItem key={route.path} onClick={() => { onSelect(category.id); onNavigate(route.path); close(); }}>
                        {route.label}{count > 0 ? " · " + count + " " + spec.label : ""}
                      </MenuItem>
                    );
                  })}
                </>
              )}
            </Floating>
          );
        })}
      </div>
      <div className="hd-rail__foot">
        <AccountMenu rail viewer={viewer} onNavigate={onNavigate} />
      </div>
    </nav>
  );
}

function CategoryPanel({ category, path, data, viewer, onNavigate, onClose }) {
  return (
    <div className="hd-panel" id="hd-panel" role="tabpanel" aria-label={category.label}>
      <div className="hd-panel__head">
        <span className="hd-panel__hospital">{HD_HOSPITAL.short}</span>
        <span className="hd-panel__title">{category.label}</span>
        <span className="hd-panel__note">{category.note}</span>
      </div>
      <div className="hd-panel__nav">
        {category.items.map((route) => {
          const spec = route.badge ? HD_NAV_BADGES[route.badge] : null;
          return (
            <NavLink
              key={route.path}
              route={route}
              active={route.path === path || (route.path !== "/" && path.indexOf(route.path + "/") === 0)}
              badge={spec ? { count: spec.count(data, viewer.id), label: spec.label } : null}
              onNavigate={(p) => { onNavigate(p); if (onClose) onClose(); }}
            />
          );
        })}
      </div>
    </div>
  );
}

function AccountMenu({ rail, viewer, onNavigate }) {
  const trigger = (
    <button type="button" className={"hd-account" + (rail ? " hd-account--rail" : "")} aria-label={"Account — " + viewer.name + ", " + viewer.jobTitle}>
      <Avatar size={rail ? 28 : 32} src={viewer.avatar} alt="" fallback={initialsOf(viewer.name)} />
      {rail ? null : (
        <span className="hd-account__text">
          <span className="hd-account__name">{viewer.name}</span>
          <span className="hd-account__role">{viewer.jobTitle}</span>
        </span>
      )}
    </button>
  );
  return (
    <Floating trigger={trigger} align="start" width="16rem" label="Account">
      {(close) => (
        <>
          <MenuGroupLabel>{viewer.name} · {viewer.jobTitle}</MenuGroupLabel>
          {HD_ACCOUNT_MENU.map((route) => (
            <MenuItem key={route.path} onClick={() => { onNavigate(route.path); close(); }}>{route.label}</MenuItem>
          ))}
          <MenuItem onClick={() => { onNavigate("/signin"); close(); }}>Sign out</MenuItem>
        </>
      )}
    </Floating>
  );
}

function NotificationsButton({ items, unread, onRead, onNavigate }) {
  const trigger = (
    <span className="hd-utility">
      <Button variant="ghost" size="icon-sm" aria-label={unread ? unread + " unread notifications" : "Notifications"}>
        <Icon name="bell" />
      </Button>
      {unread ? <span className="hd-badge-dot" aria-hidden="true">{unread}</span> : null}
    </span>
  );
  return (
    <FloatingTip label="Notifications" side="bottom">
      <Floating trigger={trigger} align="end" width="24rem" role="dialog" panelClass="o-popover hd-notify" label="Notifications">
        {(close) => (
          <>
            <div className="hd-notify__head">
              <span className="o-popover__title">Notifications</span>
              <Button variant="ghost" size="xs" onClick={onRead}>Mark all read</Button>
            </div>
            <div className="hd-notify__list">
              {items.map((n) => (
                <button type="button" key={n.id} className="hd-notify__item" onClick={() => { onNavigate(n.route); close(); }}>
                  <span className="hd-notify__title">{n.title}</span>
                  <span className="hd-notify__body">{n.body}</span>
                  <span className="hd-notify__time" title={formatAbsolute(n.at)}>{formatWhen(n.at, HD_NOW)}</span>
                </button>
              ))}
            </div>
          </>
        )}
      </Floating>
    </FloatingTip>
  );
}

function TopBar({ mode, dark, onToggleTheme, onOpenPalette, onOpenDrawer, notifications, unread, onRead, onNavigate }) {
  return (
    <div className="hd-topbar">
      {mode === "drawer" ? (
        <Button variant="ghost" size="icon-sm" aria-label="Open navigation" onClick={onOpenDrawer}><Icon name="menu" /></Button>
      ) : null}
      <div className="hd-search" onClick={onOpenPalette}>
        <Input
          readOnly
          size="sm"
          aria-label={"Search " + HD_HOSPITAL.short}
          placeholder="Search patients, procedures, staff…"
          startAddon={<Icon name="search" />}
          endAddon={<Kbd>⌘K</Kbd>}
          onFocus={onOpenPalette}
        />
      </div>
      <span className="hd-search-btn">
        <FloatingTip label="Search — ⌘K" side="bottom">
          <Button variant="ghost" size="icon-sm" aria-label={"Search " + HD_HOSPITAL.short} onClick={onOpenPalette}><Icon name="search" /></Button>
        </FloatingTip>
      </span>
      <div className="hd-topbar__utility">
        <NotificationsButton items={notifications} unread={unread} onRead={onRead} onNavigate={onNavigate} />
        <FloatingTip label={dark ? "Switch to light" : "Switch to dark"} side="bottom">
          <Button variant="ghost" size="icon-sm" aria-label={dark ? "Switch to light theme" : "Switch to dark theme"} onClick={onToggleTheme}>
            <Icon name={dark ? "sun" : "moon"} />
          </Button>
        </FloatingTip>
      </div>
    </div>
  );
}

/* Every screen renders PageHeader and none of them pass the router, so the shell
   registers it once per render and the crumbs read it from here. */
let breadcrumbNavigate = null;

/* The last crumb NAMES the record: the trail still comes from the route table,
   but a parameterised route's own segment reads the record's name rather than
   the generic label, because "Patients / Patient" tells the reader nothing. */
function PageHeader({ path, title, sub, actions, params, crumb }) {
  const trail = breadcrumb(path, HD_ROUTES).map((seg, i, all) => (
    crumb && i === all.length - 1 ? Object.assign({}, seg, { label: crumb }) : seg
  ));
  return (
    <header className="hd-pagehead">
      <div>
        <Breadcrumb>
          <BreadcrumbList>
            {trail.map((seg, i) => (
              <React.Fragment key={seg.path}>
                {i > 0 ? <BreadcrumbSeparator /> : null}
                <BreadcrumbItem>
                  {i === trail.length - 1
                    ? <BreadcrumbPage>{seg.label}</BreadcrumbPage>
                    : seg.isNamespace ? <span>{seg.label}</span>
                      : <BreadcrumbLink href={"#" + resolvePath(seg.path, params || {})} onSelect={() => breadcrumbNavigate && breadcrumbNavigate(resolvePath(seg.path, params || {}))}>{seg.label}</BreadcrumbLink>}
                </BreadcrumbItem>
              </React.Fragment>
            ))}
          </BreadcrumbList>
        </Breadcrumb>
        <h1 className="hd-pagetitle">{title}</h1>
        {sub ? <p className="hd-pagesub">{sub}</p> : null}
      </div>
      {actions ? <div className="hd-actions">{actions}</div> : null}
    </header>
  );
}

function HdShell({ path, onNavigate, dark, onToggleTheme, data, viewer, notifications, unread, onRead, palette, toasts, onDismissToast, children }) {
  breadcrumbNavigate = onNavigate;
  const mode = useShellMode();
  const [drawer, setDrawer] = React.useState(false);
  /* The panel follows the route, and a reader may also browse a category without
     navigating — the rail is a tablist over the panel, not a set of links. */
  const [category, setCategory] = React.useState(() => categoryOf(path) || HD_RAIL[0].id);
  React.useEffect(() => { const next = categoryOf(path); if (next) setCategory(next); }, [path]);
  React.useEffect(() => { if (mode !== "drawer") setDrawer(false); }, [mode]);
  const selected = HD_RAIL.find((c) => c.id === category) || HD_RAIL[0];

  const rail = (
    <CategoryRail categories={HD_RAIL} selected={selected.id} path={path} data={data} viewer={viewer}
      onSelect={setCategory} mode={mode === "rail" ? "rail" : "expanded"} onNavigate={(p) => { onNavigate(p); setDrawer(false); }} />
  );
  const panel = (
    <CategoryPanel category={selected} path={path} data={data} viewer={viewer}
      onNavigate={onNavigate} onClose={() => setDrawer(false)} />
  );

  return (
    <div className="hd-shell" data-mode={mode}>
      {mode === "drawer" ? (
        drawer ? (
          <>
            <div className="hd-drawer-scrim" onClick={() => setDrawer(false)} />
            <div className="hd-drawer">{rail}{panel}</div>
          </>
        ) : null
      ) : (
        <>
          {rail}
          {mode === "expanded" ? panel : null}
        </>
      )}

      <main className="hd-main">
        <TopBar
          mode={mode}
          dark={dark}
          onToggleTheme={onToggleTheme}
          onOpenPalette={() => palette.setOpen(true)}
          onOpenDrawer={() => setDrawer(true)}
          notifications={notifications}
          unread={unread}
          onRead={onRead}
          onNavigate={onNavigate}
        />
        {children}
      </main>

      <ToastRegion>
        {toasts.map((t) => (
          <Toast key={t.id} variant={t.variant} title={t.title} description={t.description} onClose={() => onDismissToast(t.id)}
            action={t.onUndo ? <Button variant="outline" size="xs" onClick={() => { t.onUndo(); onDismissToast(t.id); }}>Undo</Button> : null} />
        ))}
      </ToastRegion>
    </div>
  );
}

Object.assign(window, { HdShell, PageHeader, useShellMode, AccountMenu, HD_BRAND_MARK });
