/* DMS app shell — Sidebar + Topbar + state (ported 1:1 from state/app.tsx) + Tweaks + mount. */
(function () {
  const DMS = window.DMS;
  const { Icon, TweakContext } = window;
  const { useTweaks, TweaksPanel, TweakSection, TweakRadio, TweakColor } = window;
  const { PERSONS, ROLES, tenantById, recordCountOfDepartment, DEPARTMENTS } = DMS;
  const AppProvider = window.AppProvider; // shared from state.jsx

  /* ── Sidebar ──────────────────────────────────────────────── */
  function NavItem({ label, icon, active, onClick, badge }) {
    return (
      <button onClick={onClick}
        className={`flex w-full items-center justify-between gap-2 rounded-btn px-2.5 py-[7px] text-left text-[13.5px] transition-colors focusring ${active ? 'bg-primary-tint font-semibold text-primary' : 'text-text hover:bg-surface-2'}`}>
        <span className="flex min-w-0 items-center gap-2.5">
          <Icon name={icon} size={16} strokeWidth={active ? 1.9 : 1.7} className={active ? 'text-primary' : 'text-text-muted'} />
          <span className="truncate">{label}</span>
        </span>
        {badge !== undefined && badge > 0 && (
          <span className={`tnum rounded-full px-1.5 text-[11px] ${active ? 'bg-primary/15 text-primary' : 'bg-surface-2 text-text-faint'}`}>{badge}</span>
        )}
      </button>
    );
  }

  function SectionLabel({ children }) {
    return <div className="mb-1 mt-4 px-2.5 text-[10.5px] font-semibold uppercase tracking-[0.09em]" style={{ color: 'rgb(var(--c-accent2-ink))' }}>{children}</div>;
  }

  function Sidebar() {
    const { person, view, go } = window.useApp();
    const isActive = (v) => view.name === v.name && (v.name !== 'department' || view.dept === v.dept);
    const roles = person.roles;
    const showIntake = roles.some((r) => ['contributor', 'archivist', 'dept_head'].includes(r));
    const showSafe = person.clearance >= 3;
    const showAudit = roles.includes('internal_auditor') || roles.includes('admin');
    const showManage = roles.includes('archivist');

    return (
      <aside className="flex w-[260px] shrink-0 flex-col overflow-y-auto border-r border-border bg-surface px-3 py-3">
        <div className="flex flex-col gap-0.5">
          <NavItem label="Lobby" icon="home" active={view.name === 'lobby'} onClick={() => go({ name: 'lobby' })} />
          <NavItem label="Search" icon="search" active={view.name === 'search'} onClick={() => go({ name: 'search' })} />
          <NavItem label="E1–E12 test" icon="checks" active={view.name === 'edge'} onClick={() => go({ name: 'edge' })} />
        </div>

        <SectionLabel>Shelves (departments)</SectionLabel>
        <div className="flex flex-col gap-0.5">
          {DEPARTMENTS.map((d) => (
            <NavItem key={d.code} label={`${d.code} ${d.name}`} icon="archive"
              active={isActive({ name: 'department', dept: d.code })}
              badge={recordCountOfDepartment(d.code, person.tenantId)}
              onClick={() => go({ name: 'department', dept: d.code })} />
          ))}
        </div>

        <SectionLabel>Special zones</SectionLabel>
        <div className="flex flex-col gap-0.5">
          {showIntake && <NavItem label="Recipient" icon="inbox" active={view.name === 'intake'} onClick={() => go({ name: 'intake' })} />}
          {showSafe && <NavItem label="Safe" icon="vault" active={view.name === 'safe'} onClick={() => go({ name: 'safe' })} />}
          <NavItem label="Reading room" icon="book" active={view.name === 'reading'} onClick={() => go({ name: 'reading' })} />
        </div>

        {(showAudit || showManage) && (
          <>
            <SectionLabel>Oversight</SectionLabel>
            <div className="flex flex-col gap-0.5">
              {showAudit && <NavItem label="Audit trail" icon="history" active={view.name === 'audit'} onClick={() => go({ name: 'audit' })} />}
              {showManage && <NavItem label="Nomenclature mgmt" icon="settings" active={view.name === 'manage'} onClick={() => go({ name: 'manage' })} />}
            </div>
          </>
        )}
      </aside>
    );
  }

  /* ── Topbar ───────────────────────────────────────────────── */
  function Topbar() {
    const { person, persons, setPersonId, go, canBack, back } = window.useApp();
    const [q, setQ] = React.useState('');
    const tenant = tenantById(person.tenantId);
    return (
      <header className="flex items-center gap-3 border-b border-border bg-surface px-4 py-2.5">
        <button onClick={back} disabled={!canBack} title="Back"
          className="flex h-8 w-8 items-center justify-center rounded-btn border border-border text-text-muted transition-colors hover:bg-surface-2 hover:text-text disabled:opacity-30 focusring">
          <Icon name="arrowLeft" size={16} />
        </button>
        <div className="flex items-center gap-2 pr-1">
          <span className="flex h-8 w-8 items-center justify-center rounded-btn bg-primary text-white">
            <Icon name="archive" size={18} strokeWidth={1.8} />
          </span>
          <span className="text-[17px] font-bold tracking-[0.12em] text-text">NUSKHA</span>
        </div>

        <form className="mx-auto flex w-full max-w-md items-center" onSubmit={(e) => { e.preventDefault(); go({ name: 'search' }); }}>
          <div className="relative w-full">
            <Icon name="search" size={15} className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-text-faint" />
            <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search metadata…" onFocus={() => go({ name: 'search' })}
              className="w-full rounded-btn border border-border bg-bg py-1.5 pl-9 pr-3 text-sm outline-none transition-colors focus:border-primary focus:bg-surface focusring" />
          </div>
        </form>

        <div className="flex items-center gap-2">
          <span className="inline-flex items-center gap-1.5 rounded-btn bg-surface-2 px-2.5 py-1.5 text-xs text-text-muted" title="Entity (tenant isolation)">
            <Icon name="building" size={14} /> {tenant?.name}
          </span>
          <label className="flex items-center gap-2 rounded-btn border border-border bg-surface py-1 pl-2.5 pr-1.5">
            <span className="flex items-center gap-1.5 text-xs font-medium text-text-muted"><Icon name="eye" size={14} /> View as</span>
            <select value={person.id} onChange={(e) => setPersonId(e.target.value)}
              className="max-w-[230px] rounded-[5px] bg-surface-2 px-2 py-1 text-[13px] font-medium text-text outline-none focusring">
              {persons.map((p) => (
                <option key={p.id} value={p.id}>{p.id} · {p.name} ({p.roles.map((r) => ROLES[r].label).join(', ')}) · clr {p.clearance}</option>
              ))}
            </select>
          </label>
        </div>
      </header>
    );
  }

  /* ── Content router ───────────────────────────────────────── */
  function Content() {
    const { view, person } = window.useApp();
    const S = window.Screens;
    // Skeleton on first load + role-switch ("View as" resets to lobby) — the
    // authentic "fetching the archive" moment. Navigation stays instant.
    const [loading, setLoading] = React.useState(true);
    React.useEffect(() => {
      setLoading(true);
      const t = setTimeout(() => setLoading(false), 650);
      return () => clearTimeout(t);
    }, [person.id]);
    if (loading) return <S.LobbySkeleton />;
    switch (view.name) {
      case 'lobby': return <S.Lobby />;
      case 'department': return <S.DepartmentScreen dept={view.dept} />;
      case 'category': return <S.CategoryScreen cat={view.cat} />;
      case 'case': return <S.CaseScreen caseId={view.caseId} />;
      case 'record': return <S.RecordScreen recordId={view.recordId} />;
      case 'search': return <S.SearchScreen />;
      case 'intake': return <S.IntakeScreen />;
      case 'safe': return <S.SafeScreen />;
      case 'reading': return <S.ReadingRoomScreen />;
      case 'audit': return <S.AuditScreen />;
      case 'manage': return <S.ManageScreen />;
      case 'edge': return <S.EdgeCasesScreen />;
      default: return null;
    }
  }

  /* ── accent helpers ───────────────────────────────────────── */
  function hexToChannels(hex) {
    const m = hex.replace('#', '');
    const n = parseInt(m.length === 3 ? m.split('').map((c) => c + c).join('') : m, 16);
    return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
  }
  function darken([r, g, b], f = 0.78) {
    return [Math.round(r * f), Math.round(g * f), Math.round(b * f)];
  }

  const ACCENTS = ['#2557D6', '#1D4ED8', '#0F766E', '#3F4756'];
  const SANS_STACK = "'Noto Sans Georgian', system-ui, -apple-system, 'Segoe UI', sans-serif";
  const SERIF_STACK = "'Noto Serif Georgian', 'Noto Serif', Georgia, 'Times New Roman', serif";

  const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
    accent: '#2557D6',
    density: 'comfortable',
    badgeStyle: 'soft',
    heading: 'serif',
    paper: 'warm',
    recordLayout: 'blocks',
    tableStyle: 'lines',
    deniedStyle: 'panel',
  }/*EDITMODE-END*/;

  /* ── Root ─────────────────────────────────────────────────── */
  function Shell() {
    const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

    React.useEffect(() => {
      const root = document.documentElement;
      const ch = hexToChannels(t.accent);
      root.style.setProperty('--c-primary', ch.join(' '));
      root.style.setProperty('--c-primary-hover', darken(ch).join(' '));
      root.dataset.density = t.density;
      root.dataset.paper = t.paper;
      root.style.setProperty('--font-serif', t.heading === 'serif' ? SERIF_STACK : SANS_STACK);
    }, [t.accent, t.density, t.paper, t.heading]);

    const twValue = {
      badgeStyle: t.badgeStyle,
      density: t.density,
      recordLayout: t.recordLayout,
      tableStyle: t.tableStyle,
      deniedStyle: t.deniedStyle,
    };

    return (
      <TweakContext.Provider value={twValue}>
        <AppProvider>
          <div className="flex h-screen flex-col">
            <Topbar />
            <div className="flex min-h-0 flex-1">
              <Sidebar />
              <main className="min-w-0 flex-1 overflow-y-auto bg-bg p-6">
                <Content />
              </main>
            </div>
          </div>

          <TweaksPanel title="Tweaks">
            <TweakSection label="Color & density" />
            <TweakColor label="Accent" value={t.accent} options={ACCENTS} onChange={(v) => setTweak('accent', v)} />
            <TweakRadio label="Density" value={t.density} options={[{ value: 'comfortable', label: 'Comf.' }, { value: 'compact', label: 'Dense' }]} onChange={(v) => setTweak('density', v)} />

            <TweakSection label="Character (typography · paper)" />
            <TweakRadio label="Heading font" value={t.heading} options={[{ value: 'serif', label: 'Serif' }, { value: 'sans', label: 'Sans' }]} onChange={(v) => setTweak('heading', v)} />
            <TweakRadio label="Background tone" value={t.paper} options={[{ value: 'warm', label: 'Parchment' }, { value: 'cool', label: 'Cool' }]} onChange={(v) => setTweak('paper', v)} />

            <TweakSection label="Confidentiality badge" />
            <TweakRadio label="Style" value={t.badgeStyle} options={[{ value: 'soft', label: 'Soft' }, { value: 'solid', label: 'Full' }, { value: 'outline', label: 'Outline' }]} onChange={(v) => setTweak('badgeStyle', v)} />

            <TweakSection label="Screen directions" />
            <TweakRadio label="Doc card" value={t.recordLayout} options={[{ value: 'blocks', label: 'Blocks' }, { value: 'rail', label: 'Panel' }]} onChange={(v) => setTweak('recordLayout', v)} />
            <TweakRadio label="Table" value={t.tableStyle} options={[{ value: 'lines', label: 'Lines' }, { value: 'zebra', label: 'Zebra' }]} onChange={(v) => setTweak('tableStyle', v)} />
            <TweakRadio label="Deny screen" value={t.deniedStyle} options={[{ value: 'panel', label: 'Panel' }, { value: 'inline', label: 'Built-in' }]} onChange={(v) => setTweak('deniedStyle', v)} />
          </TweaksPanel>
        </AppProvider>
      </TweakContext.Provider>
    );
  }

  ReactDOM.createRoot(document.getElementById('root')).render(<Shell />);
})();
