// components.jsx — shared primitives: banner, navigation, chips, cards, rows,
// filters, segmented control, states. Exposed to window for later modules.

const { useState, useEffect, useRef } = React;

// ── helpers ──────────────────────────────────────────────────────────────────
function cx(...parts) { return parts.filter(Boolean).join(" "); }
function collectionIcon(c) { return c === "runbooks" ? <I.Runbook /> : <I.Spec />; }
function statusClass(stage) { return "status status--" + (stage || "active"); }
function fmtDate(s) { return s ? String(s).slice(0, 10) : "—"; }

function StatusChip({ stage, status }) {
  return (
    <span className={statusClass(stage)} title={"Status: " + (status || stage)}>
      <span className="chip__dot" /> {status || stage || "—"}
    </span>
  );
}

function DomainChips({ domains, max = 2 }) {
  if (!domains || !domains.length) return null;
  const shown = domains.slice(0, max);
  const extra = domains.length - shown.length;
  return (
    <React.Fragment>
      {shown.map((d, i) => <span className="chip" key={i} title={d.role + " · " + d.label}><span className="chip__dot" style={{ background: "var(--uk-color-fg-muted)" }} />{d.label}</span>)}
      {extra > 0 && <span className="chip mono">+{extra}</span>}
    </React.Fragment>
  );
}

// ── Banner ───────────────────────────────────────────────────────────────────
function Banner({ onMenu, crumbs, onSearch, theme, onToggleTheme, onHome }) {
  return (
    <header className="banner" role="banner">
      <button className="iconbtn banner__menu" onClick={onMenu} aria-label="Open navigation"><I.Menu /></button>
      <a className="banner__brand" href="#/" onClick={(e) => { e.preventDefault(); onHome(); }}>
        <svg viewBox="0 0 32 32" aria-hidden="true"><rect width="32" height="32" rx="3" fill="var(--uk-color-charcoal-800)"/><circle cx="16" cy="16" r="4" fill="var(--uk-color-blue-accent)"/></svg>
        <b>unikode</b>
      </a>
      <nav className="banner__crumbs" aria-label="Breadcrumb">
        {(crumbs || []).map((c, i, arr) => (
          <React.Fragment key={i}>
            {i > 0 && <span className="banner__sep">/</span>}
            {c.href && i < arr.length - 1
              ? <a href={c.href}>{c.label}</a>
              : <a href={c.href || "#"} className="cur" aria-current="page" onClick={(e) => !c.href && e.preventDefault()}>{c.label}</a>}
          </React.Fragment>
        ))}
      </nav>
      <div className="banner__spacer" />
      <button className="banner__search" onClick={onSearch} aria-label="Search the library (Command K)">
        <I.Search /><span className="lbl">Search</span><kbd>⌘K</kbd>
      </button>
      <button className="iconbtn" onClick={onToggleTheme} aria-label={theme === "dark" ? "Switch to light theme" : "Switch to dark theme"} title="Toggle theme">
        {theme === "dark" ? <I.Sun /> : <I.Moon />}
      </button>
    </header>
  );
}

// ── Navigation ─────────────────────────────────────────────────────────────────
function navItems(collections) {
  const items = [{ id: "home", label: "Library", href: "#/", icon: <I.Home /> }];
  for (const c of (collections || [])) {
    items.push({ id: c.id, label: c.label, href: "#/" + c.id, icon: collectionIcon(c.id), count: c.count });
  }
  items.push({ id: "map", label: "Map", href: "#/map", icon: <I.Map /> });
  return items;
}
function NavList({ active, collections, onNavigate }) {
  return (
    <React.Fragment>
      <div className="nav__group-label">Browse</div>
      {navItems(collections).map((it) => (
        <a key={it.id} href={it.href} className={cx("nav__item", active === it.id && "active")}
           aria-current={active === it.id ? "page" : undefined}
           onClick={(e) => { e.preventDefault(); onNavigate(it.href); }}>
          {it.icon}
          <span className="nav__item-label">{it.label}</span>
          {typeof it.count === "number" && <span className="count">{it.count}</span>}
        </a>
      ))}
    </React.Fragment>
  );
}
function Nav(props) { return <nav className="nav" aria-label="Primary">{NavList(props)}</nav>; }
function Drawer({ open, onClose, ...rest }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <React.Fragment>
      <button className="scrim" aria-label="Close navigation" onClick={onClose} />
      <nav className="drawer" aria-label="Primary">
        <div className="drawer__head">
          <span className="mono muted" style={{ fontSize: "11px" }}>NAVIGATION</span>
          <button className="iconbtn" onClick={onClose} aria-label="Close"><I.Close /></button>
        </div>
        {NavList(rest)}
      </nav>
    </React.Fragment>
  );
}

// ── Gallery card / row ─────────────────────────────────────────────────────────
function DocCard({ doc, onOpen }) {
  return (
    <button className="card" onClick={() => onOpen(doc)} aria-label={"Open " + doc.title}>
      <div className="card__top">
        <h3 className="card__title">{doc.title}</h3>
        <StatusChip stage={doc.statusStage} status={doc.status} />
      </div>
      <span className="card__uid">{doc.id}</span>
      {doc.description && <p className="card__desc">{doc.description}</p>}
      <div className="card__meta">
        <DomainChips domains={doc.domains} max={1} />
        {doc.version && <span className="card__mono">{doc.version}</span>}
        <span className="dot">·</span>
        <span className="card__mono">{fmtDate(doc.lastUpdated)}</span>
        {doc.relationCount > 0 && <span className="card__mono" title="Linked documents">· {doc.relationCount} linked</span>}
      </div>
    </button>
  );
}
function DocRow({ doc, onOpen }) {
  const primary = doc.domains && doc.domains[0];
  return (
    <button className="row" onClick={() => onOpen(doc)} aria-label={"Open " + doc.title}>
      <div className="row__main">
        <div className="row__title">{doc.title}</div>
        <div className="row__sub">{doc.id}</div>
      </div>
      <div className="row__aside">
        {primary && <span className="row__cell row__cell--hide">{primary.label}</span>}
        <span className="row__cell row__cell--hide">{doc.version || "—"}</span>
        <span className="row__cell row__cell--hide">{fmtDate(doc.lastUpdated)}</span>
        <StatusChip stage={doc.statusStage} status={doc.status} />
      </div>
    </button>
  );
}

// ── Filters ─────────────────────────────────────────────────────────────────────
function FilterGroup({ label, options, selected, onToggle }) {
  if (!options || !options.length) return null;
  return (
    <div className="filters__group">
      <div className="filters__head"><span className="filters__label">{label}</span></div>
      {options.map((o) => {
        const on = selected.includes(o.code);
        return (
          <button key={o.code} className="facet" aria-pressed={on} onClick={() => onToggle(o.code)}>
            <span className="facet__box">{on && <I.Check />}</span>
            <span className="facet__name" title={o.label}>{o.label}</span>
            <span className="facet__count">{o.count}</span>
          </button>
        );
      })}
    </div>
  );
}

function Segmented({ options, value, onChange, ariaLabel }) {
  return (
    <div className="seg" role="group" aria-label={ariaLabel}>
      {options.map((o) => (
        <button key={o.value} aria-pressed={value === o.value} onClick={() => onChange(o.value)} title={o.title || o.label}>
          {o.icon}{o.label && <span>{o.label}</span>}
        </button>
      ))}
    </div>
  );
}

// ── States ─────────────────────────────────────────────────────────────────────
function SkeletonGrid({ n = 9 }) {
  return <div className="cardgrid" aria-hidden="true">{Array.from({ length: n }).map((_, i) => <div key={i} className="skel skel-card" />)}</div>;
}
function EmptyState({ title, msg, action }) {
  return (
    <div className="state" role="status">
      <I.Empty />
      <div className="state__title">{title || "Nothing here"}</div>
      {msg && <div className="state__msg">{msg}</div>}
      {action}
    </div>
  );
}
function ErrorState({ title, msg, onRetry }) {
  return (
    <div className="state" role="alert">
      <I.Alert />
      <div className="state__title">{title || "Something went wrong"}</div>
      {msg && <div className="state__msg">{msg}</div>}
      {onRetry && <button className="btn btn--sm" onClick={onRetry}>Retry</button>}
    </div>
  );
}
function Loading({ label }) {
  return <div className="state" role="status" aria-live="polite"><I.Loader /><div className="state__msg">{label || "Loading…"}</div></div>;
}

Object.assign(window, {
  cx, collectionIcon, statusClass, fmtDate,
  StatusChip, DomainChips, Banner, Nav, Drawer, NavList, navItems,
  DocCard, DocRow, FilterGroup, Segmented, SkeletonGrid, EmptyState, ErrorState, Loading
});
