// bulk-reg.jsx — Bulk Registration screen
// ─────────────────────────────────────────────────────────────────
// Five-tab pipeline UI:
//   01 COMPOSE   — pick format · pick entities (selection model) · format options
//   02 VALIDATE  — pre-flight validation results · severity ladder
//   03 PREVIEW   — rendered file preview (with syntax tabs by format)
//   04 OUTBOX    — pending transmissions · channel picker · send
//   05 HISTORY   — past runs · re-build · download · replay
//
// Exports: window.ScreenBulkReg
// ─────────────────────────────────────────────────────────────────
(function () {
  if (typeof window === 'undefined' || !window.React) return;
  const _S = React.useState, _E = React.useEffect, _M = React.useMemo;

  const E = window.BULK_REG_ENGINE;
  const V = window.BULK_REG_VALIDATE;
  if (!E || !V) { console.warn('[bulk-reg] engine/validate missing'); return; }

  // ── primitives ──────────────────────────────────────────────────
  function Mono({ children, upper, size, color, style, ...rest }) {
    return <span className={'ff-mono' + (upper?' upper':'')} style={{ fontSize: size||11, color: color||'var(--ink)', letterSpacing: upper?'.08em':0, ...style }} {...rest}>{children}</span>;
  }
  function Pill({ tone, children }) {
    const tones = {
      ok:    { bg:'#0a8754', fg:'#fff' },
      warn:  { bg:'#d4881f', fg:'#fff' },
      err:   { bg:'#a32a18', fg:'#fff' },
      block: { bg:'#5b0a0a', fg:'#fff' },
      info:  { bg:'#1a4ed8', fg:'#fff' },
      mono:  { bg:'var(--ink)', fg:'var(--bg)' },
      ghost: { bg:'transparent', fg:'var(--ink-2)', bd:'1px solid var(--rule)' },
    };
    const t = tones[tone] || tones.mono;
    return <span className="ff-mono upper" style={{ fontSize: 9, padding: '2px 7px', background: t.bg, color: t.fg, border: t.bd || 0, letterSpacing: '.08em' }}>{children}</span>;
  }
  function Cell({ label, value, sub, tone }) {
    return (
      <div style={{ padding: '18px 22px', borderRight: '1px solid var(--rule)' }}>
        <Mono upper size={9} color="var(--ink-3)">{label}</Mono>
        <div className="ff-display" style={{ fontSize: 24, fontWeight: 600, letterSpacing: '-0.02em', marginTop: 4, color: tone || 'var(--ink)' }}>{value}</div>
        <div style={{ fontSize: 11, color: 'var(--ink-2)', marginTop: 3 }}>{sub}</div>
      </div>
    );
  }
  function Btn({ kind, onClick, children, disabled, style }) {
    const looks = {
      pri: { bg:'var(--ink)', fg:'var(--bg)', bd:'1px solid var(--ink)' },
      sec: { bg:'transparent', fg:'var(--ink)', bd:'1px solid var(--rule)' },
      dan: { bg:'#a32a18', fg:'#fff', bd:'1px solid #a32a18' },
    };
    const k = looks[kind || 'sec'];
    return <button onClick={onClick} disabled={disabled} style={{ background:k.bg, color:k.fg, border:k.bd, padding:'8px 14px', fontSize:11, letterSpacing:'.06em', textTransform:'uppercase', cursor:disabled?'not-allowed':'pointer', opacity:disabled?0.4:1, fontFamily:'var(--ff-mono, ui-monospace, Menlo, monospace)', ...style }}>{children}</button>;
  }

  // ── screen ──────────────────────────────────────────────────────
  function ScreenBulkReg({ go, payload }) {
    const [tab, setTab] = _S('compose');
    const [formatId, setFormatId] = _S(payload?.formatId || 'mlc-bdf');
    const [selectionKind, setSelectionKind] = _S('all');
    const [selectionN, setSelectionN] = _S(20);
    const [society, setSociety] = _S('ASCAP');
    const [submitterPubNumber, setSubmitterPubNumber] = _S('');
    const [channel, setChannel] = _S('download');
    const [outbox, setOutbox] = _S([]);
    const [history, setHistory] = _S(() => E.loadHistory());
    const [lastBuild, setLastBuild] = _S(null);

    const adapter = E.ADAPTERS[formatId];
    const selectionModel = _M(() => {
      if (selectionKind === 'recent') return { kind: 'recent', n: selectionN };
      if (selectionKind === 'untransmitted') return { kind: 'untransmitted' };
      return { kind: 'all' };
    }, [selectionKind, selectionN]);

    const validation = _M(() => V.validate(formatId, selectionModel, { society, submitterPubNumber }), [formatId, selectionModel, society, submitterPubNumber]);

    const buildOpts = { society, submitterPubNumber };
    function doBuild() {
      const result = E.build(formatId, selectionModel, buildOpts);
      setLastBuild(result);
      setTab('preview');
      return result;
    }
    function queueOutbox() {
      const built = lastBuild || doBuild();
      const item = { id: 'OB-' + Date.now(), built, formatId, channel, status: 'queued', at: new Date().toISOString() };
      setOutbox((o) => [item, ...o]);
      setTab('outbox');
    }
    function send(item) {
      const updated = { ...item, status: 'sent', sentAt: new Date().toISOString() };
      setOutbox((o) => o.map((x) => x.id === item.id ? updated : x));
      const newHistory = E.recordRun({
        formatId: item.formatId,
        adapter: item.built.adapter.label,
        entityCount: item.built.entityCount,
        entityIds: item.built.entityIds,
        channel: item.channel,
        fileName: item.built.name,
        fileSize: item.built.content.length,
        status: 'sent',
      });
      setHistory(newHistory);
    }
    function downloadFile(built) {
      const blob = new Blob([built.content], { type: built.mime });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url; a.download = built.name; a.click();
      setTimeout(() => URL.revokeObjectURL(url), 1000);
    }

    // ── header ───────────────────────────────────────────────────
    const tabs = [
      { id: 'compose',  l: '01 · COMPOSE' },
      { id: 'validate', l: '02 · VALIDATE' },
      { id: 'preview',  l: '03 · PREVIEW' },
      { id: 'outbox',   l: '04 · OUTBOX', badge: outbox.filter((o) => o.status === 'queued').length },
      { id: 'history',  l: '05 · HISTORY', badge: history.length },
    ];

    return (
      <div style={{ paddingBottom: 60 }}>
        {/* Header */}
        <div style={{ borderBottom: '1px solid var(--rule)', paddingBottom: 18, marginBottom: 22 }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 14 }}>
            <Mono upper size={10} color="var(--ink-3)">TOOLS · TRANSMISSIONS</Mono>
            <span style={{ flex: 1 }} />
            <Pill tone="mono">8 ADAPTERS</Pill>
          </div>
          <h1 className="ff-display" style={{ margin: '8px 0 0', fontSize: 38, letterSpacing: '-0.02em', fontWeight: 500 }}>
            Bulk registrations & notifications
          </h1>
          <div style={{ marginTop: 8, fontSize: 13, color: 'var(--ink-2)', maxWidth: 760 }}>
            Build and dispatch registration files in MLC, HFA, SoundExchange, Xperi, DDEX, ASCAP/BMI formats.
            CWR & CAF live separately — those are <a href="#" onClick={(ev) => { ev.preventDefault(); go('cwr'); }} style={{ color:'var(--ink)' }}>under Registrations</a>.
          </div>
        </div>

        {/* Tab bar */}
        <div style={{ display: 'flex', gap: 0, borderBottom: '1px solid var(--rule)', marginBottom: 22 }}>
          {tabs.map((t) => (
            <button key={t.id} onClick={() => setTab(t.id)}
              style={{ padding:'10px 16px', border:0, background:'transparent', cursor:'pointer',
                fontSize:11, letterSpacing:'.08em', textTransform:'uppercase',
                fontFamily:'var(--ff-mono, ui-monospace, Menlo, monospace)',
                color: tab === t.id ? 'var(--ink)' : 'var(--ink-3)',
                borderBottom: tab === t.id ? '2px solid var(--ink)' : '2px solid transparent',
                marginBottom: -1 }}>
              {t.l}
              {t.badge ? <span style={{ marginLeft:8, padding:'1px 6px', background:'var(--ink)', color:'var(--bg)', fontSize:9 }}>{t.badge}</span> : null}
            </button>
          ))}
        </div>

        {tab === 'compose' && (
          <ComposeTab formatId={formatId} setFormatId={setFormatId}
            selectionKind={selectionKind} setSelectionKind={setSelectionKind}
            selectionN={selectionN} setSelectionN={setSelectionN}
            society={society} setSociety={setSociety}
            submitterPubNumber={submitterPubNumber} setSubmitterPubNumber={setSubmitterPubNumber}
            channel={channel} setChannel={setChannel}
            adapter={adapter} validation={validation}
            onBuild={doBuild} onQueue={queueOutbox}
            setTab={setTab} />
        )}
        {tab === 'validate' && <ValidateTab validation={validation} adapter={adapter} setTab={setTab} onBuild={doBuild} />}
        {tab === 'preview'  && <PreviewTab built={lastBuild} onBuild={doBuild} onDownload={downloadFile} onQueue={queueOutbox} />}
        {tab === 'outbox'   && <OutboxTab outbox={outbox} onSend={send} onDownload={downloadFile} />}
        {tab === 'history'  && <HistoryTab history={history} onClear={() => { localStorage.removeItem('astro_bulk_reg_history_v1'); setHistory([]); }} />}
      </div>
    );
  }

  // ════════════════════════════════════════════════════════════════
  // 01 COMPOSE
  // ════════════════════════════════════════════════════════════════
  function ComposeTab({ formatId, setFormatId, selectionKind, setSelectionKind, selectionN, setSelectionN,
                       society, setSociety, submitterPubNumber, setSubmitterPubNumber,
                       channel, setChannel, adapter, validation, onBuild, onQueue, setTab }) {
    const formats = Object.values(E.ADAPTERS);
    const counts = validation.counts || {};
    return (
      <div>
        {/* metric row */}
        <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', border:'1px solid var(--rule)', marginBottom: 22 }}>
          <Cell label="FORMAT" value={adapter.label.split(' · ')[1] || adapter.label} sub={adapter.kind} />
          <Cell label="VERSION" value={adapter.version} sub={adapter.ext.toUpperCase()} />
          <Cell label="ENTITIES" value={validation.entities ? validation.entities.length : 0} sub={adapter.entity} />
          <Cell label="STATUS" value={validation.ok ? 'READY' : 'BLOCKED'} sub={`${counts.blocker||0} blocker · ${counts.error||0} err · ${counts.warn||0} warn`} tone={validation.ok ? '#0a8754' : '#a32a18'} />
        </div>

        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 22 }}>
          {/* LEFT — Format picker */}
          <div style={{ border:'1px solid var(--rule)' }}>
            <div style={{ padding:'14px 18px', borderBottom:'1px solid var(--rule)', background:'var(--surface)' }}>
              <Mono upper size={9} color="var(--ink-3)">PICK FORMAT</Mono>
            </div>
            <div>
              {formats.map((f) => (
                <button key={f.id} onClick={() => setFormatId(f.id)}
                  style={{ display:'block', width:'100%', textAlign:'left', padding:'12px 18px',
                    border:0, borderBottom:'1px solid var(--rule)', cursor:'pointer',
                    background: formatId === f.id ? 'var(--surface-2, #f3f1ec)' : 'var(--bg)' }}>
                  <div style={{ display:'flex', alignItems:'baseline', gap:10 }}>
                    <Mono upper size={9} color="var(--ink-3)" style={{ minWidth: 90 }}>{f.id}</Mono>
                    <span style={{ fontSize:13, fontWeight: formatId === f.id ? 600 : 500 }}>{f.label}</span>
                    <span style={{ flex:1 }} />
                    <Pill tone="ghost">{f.ext.toUpperCase()}</Pill>
                  </div>
                  <div style={{ fontSize:11, color:'var(--ink-2)', marginTop:3, paddingLeft:100 }}>
                    {f.kind} · {f.entity} · v{f.version}
                  </div>
                </button>
              ))}
            </div>
          </div>

          {/* RIGHT — Selection + options + delivery */}
          <div>
            <div style={{ border:'1px solid var(--rule)', marginBottom: 18 }}>
              <div style={{ padding:'14px 18px', borderBottom:'1px solid var(--rule)', background:'var(--surface)' }}>
                <Mono upper size={9} color="var(--ink-3)">SELECTION MODEL</Mono>
              </div>
              <div style={{ padding: 18 }}>
                {[
                  { id:'all', l:'All entities', sub:`Everything in catalog (${E.selectEntities(adapter.entity, { kind:'all' }).length} ${adapter.entity})` },
                  { id:'recent', l:'Recently added', sub:`Most recent N · adjustable` },
                  { id:'untransmitted', l:'Not yet sent to this format', sub:`Excludes anything in History matching ${adapter.id}` },
                ].map((opt) => (
                  <label key={opt.id} style={{ display:'flex', alignItems:'flex-start', gap:10, padding:'8px 0', cursor:'pointer' }}>
                    <input type="radio" checked={selectionKind === opt.id} onChange={() => setSelectionKind(opt.id)} style={{ marginTop:3 }} />
                    <div>
                      <div style={{ fontSize:13, fontWeight:500 }}>{opt.l}</div>
                      <div style={{ fontSize:11, color:'var(--ink-2)' }}>{opt.sub}</div>
                      {opt.id === 'recent' && selectionKind === 'recent' && (
                        <input type="number" min={1} max={500} value={selectionN} onChange={(e) => setSelectionN(+e.target.value || 20)}
                          style={{ marginTop:6, padding:'4px 8px', border:'1px solid var(--rule)', width:80, fontSize:12 }} />
                      )}
                    </div>
                  </label>
                ))}
              </div>
            </div>

            {formatId === 'pro-direct' && (
              <div style={{ border:'1px solid var(--rule)', marginBottom: 18 }}>
                <div style={{ padding:'14px 18px', borderBottom:'1px solid var(--rule)', background:'var(--surface)' }}>
                  <Mono upper size={9} color="var(--ink-3)">PRO OPTIONS</Mono>
                </div>
                <div style={{ padding: 18 }}>
                  <div style={{ display:'flex', gap:10, marginBottom:12 }}>
                    {['ASCAP','BMI','SESAC','GMR'].map((s) => (
                      <button key={s} onClick={() => setSociety(s)}
                        style={{ padding:'6px 12px', border:'1px solid var(--rule)', background: society === s ? 'var(--ink)' : 'var(--bg)', color: society === s ? 'var(--bg)' : 'var(--ink)', fontSize:11, cursor:'pointer', letterSpacing:'.06em' }}>
                        {s}
                      </button>
                    ))}
                  </div>
                  {society === 'BMI' && (
                    <div>
                      <Mono upper size={9} color="var(--ink-3)">SUBMITTER PUBLISHER NUMBER (BMI · required)</Mono>
                      <input type="text" value={submitterPubNumber} onChange={(e) => setSubmitterPubNumber(e.target.value)}
                        placeholder="e.g. 12345" style={{ display:'block', marginTop:6, padding:'6px 10px', border:'1px solid var(--rule)', width:160, fontSize:12 }} />
                    </div>
                  )}
                </div>
              </div>
            )}

            <div style={{ border:'1px solid var(--rule)', marginBottom: 18 }}>
              <div style={{ padding:'14px 18px', borderBottom:'1px solid var(--rule)', background:'var(--surface)' }}>
                <Mono upper size={9} color="var(--ink-3)">DELIVERY CHANNEL</Mono>
              </div>
              <div style={{ padding: 18 }}>
                {E.CHANNELS.map((c) => (
                  <label key={c.id} style={{ display:'flex', alignItems:'flex-start', gap:10, padding:'6px 0', cursor:'pointer' }}>
                    <input type="radio" checked={channel === c.id} onChange={() => setChannel(c.id)} style={{ marginTop:3 }} />
                    <div>
                      <div style={{ fontSize:13, fontWeight:500 }}>{c.label}</div>
                      <div style={{ fontSize:11, color:'var(--ink-2)' }}>{c.note}</div>
                    </div>
                  </label>
                ))}
              </div>
            </div>

            <div style={{ display:'flex', gap:10 }}>
              <Btn kind="sec" onClick={() => setTab('validate')}>Validate ({(counts.blocker||0)+(counts.error||0)})</Btn>
              <Btn kind="sec" onClick={onBuild}>Build &amp; preview</Btn>
              <Btn kind="pri" onClick={onQueue} disabled={!validation.ok}>Build &amp; queue →</Btn>
            </div>
          </div>
        </div>
      </div>
    );
  }

  // ════════════════════════════════════════════════════════════════
  // 02 VALIDATE
  // ════════════════════════════════════════════════════════════════
  function ValidateTab({ validation, adapter, setTab, onBuild }) {
    const [filter, setFilter] = _S('all');
    const errors = validation.errors || [];
    const filtered = filter === 'all' ? errors : errors.filter((e) => e.severity === filter);
    const c = validation.counts || {};
    return (
      <div>
        <div style={{ display:'grid', gridTemplateColumns:'repeat(5, 1fr)', border:'1px solid var(--rule)', marginBottom: 18 }}>
          <Cell label="ENTITIES" value={validation.entities ? validation.entities.length : 0} sub={adapter.entity} />
          <Cell label="BLOCKERS" value={c.blocker || 0} sub="must fix" tone={c.blocker ? '#5b0a0a' : 'var(--ink)'} />
          <Cell label="ERRORS" value={c.error || 0} sub="will reject" tone={c.error ? '#a32a18' : 'var(--ink)'} />
          <Cell label="WARNINGS" value={c.warn || 0} sub="recommended" tone={c.warn ? '#d4881f' : 'var(--ink)'} />
          <Cell label="STATUS" value={validation.ok ? 'PASS' : 'FAIL'} sub={validation.ok ? 'ready to build' : 'fix blockers first'} tone={validation.ok ? '#0a8754' : '#a32a18'} />
        </div>

        <div style={{ display:'flex', gap:8, marginBottom: 14 }}>
          {['all','blocker','error','warn','info'].map((f) => (
            <button key={f} onClick={() => setFilter(f)}
              style={{ padding:'6px 12px', border:'1px solid var(--rule)', background: filter === f ? 'var(--ink)' : 'var(--bg)', color: filter === f ? 'var(--bg)' : 'var(--ink)', fontSize:11, letterSpacing:'.06em', textTransform:'uppercase', cursor:'pointer' }}>
              {f} ({f === 'all' ? errors.length : (c[f] || 0)})
            </button>
          ))}
          <span style={{ flex:1 }} />
          <Btn kind="pri" onClick={() => { onBuild(); setTab('preview'); }} disabled={!validation.ok}>Build →</Btn>
        </div>

        <div style={{ border:'1px solid var(--rule)' }}>
          {filtered.length === 0 && (
            <div style={{ padding:40, textAlign:'center', color:'var(--ink-2)' }}>
              {validation.ok ? '✓ No issues. Ready to build.' : 'No issues at this severity.'}
            </div>
          )}
          {filtered.map((e, i) => (
            <div key={i} style={{ padding:'12px 18px', borderBottom: i < filtered.length-1 ? '1px solid var(--rule)' : 0, display:'flex', gap:14, alignItems:'flex-start' }}>
              <Pill tone={e.severity === 'blocker' ? 'block' : e.severity === 'error' ? 'err' : e.severity === 'warn' ? 'warn' : 'info'}>{e.severity}</Pill>
              <div style={{ flex:1 }}>
                <div style={{ fontSize:13, fontWeight:500 }}>{e.msg}</div>
                <div style={{ fontSize:11, color:'var(--ink-2)', marginTop:3 }}>
                  <Mono>{e.code}</Mono>
                  {e.entityId ? <> · <Mono>{e.entityType}:{e.entityId}</Mono></> : null}
                  {e.hint ? <> · <em>{e.hint}</em></> : null}
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  // ════════════════════════════════════════════════════════════════
  // 03 PREVIEW
  // ════════════════════════════════════════════════════════════════
  function PreviewTab({ built, onBuild, onDownload, onQueue }) {
    if (!built) {
      return (
        <div style={{ padding:60, textAlign:'center', border:'1px dashed var(--rule)' }}>
          <div style={{ fontSize:13, color:'var(--ink-2)', marginBottom:14 }}>No file built yet.</div>
          <Btn kind="pri" onClick={onBuild}>Build now</Btn>
        </div>
      );
    }
    const lines = built.content.split('\n');
    const preview = lines.slice(0, 200).join('\n');
    return (
      <div>
        <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', border:'1px solid var(--rule)', marginBottom: 18 }}>
          <Cell label="FILE" value={built.name} sub={built.mime} />
          <Cell label="SIZE" value={`${(built.content.length / 1024).toFixed(1)} KB`} sub={`${lines.length} lines`} />
          <Cell label="ENTITIES" value={built.entityCount} sub={built.adapter.entity} />
          <Cell label="ERRORS" value={(built.errors || []).length} sub="build-time" tone={(built.errors || []).length ? '#a32a18' : 'var(--ink)'} />
        </div>

        <div style={{ display:'flex', gap:10, marginBottom:14 }}>
          <Btn kind="sec" onClick={() => onDownload(built)}>↓ Download</Btn>
          <Btn kind="pri" onClick={onQueue}>Queue for transmission →</Btn>
          <span style={{ flex:1 }} />
          <Mono upper size={9} color="var(--ink-3)" style={{ alignSelf:'center' }}>
            SHOWING FIRST {Math.min(200, lines.length)} / {lines.length} LINES
          </Mono>
        </div>

        <pre style={{ border:'1px solid var(--rule)', background:'var(--surface)', padding:18, fontSize:11, lineHeight:1.6, overflow:'auto', maxHeight:520, fontFamily:'var(--ff-mono, ui-monospace, Menlo, monospace)' }}>
          {preview}
        </pre>
      </div>
    );
  }

  // ════════════════════════════════════════════════════════════════
  // 04 OUTBOX
  // ════════════════════════════════════════════════════════════════
  function OutboxTab({ outbox, onSend, onDownload }) {
    if (!outbox.length) {
      return <div style={{ padding:40, textAlign:'center', border:'1px dashed var(--rule)', color:'var(--ink-2)' }}>Outbox is empty. Build &amp; queue from Compose.</div>;
    }
    return (
      <div style={{ border:'1px solid var(--rule)' }}>
        <div style={{ display:'grid', gridTemplateColumns:'150px 1fr 110px 110px 100px 200px', padding:'10px 16px', borderBottom:'1px solid var(--rule)', background:'var(--surface)' }}>
          {['FORMAT','FILE','ENTITIES','CHANNEL','STATUS','ACTIONS'].map((h) => (
            <Mono key={h} upper size={9} color="var(--ink-3)">{h}</Mono>
          ))}
        </div>
        {outbox.map((it) => (
          <div key={it.id} style={{ display:'grid', gridTemplateColumns:'150px 1fr 110px 110px 100px 200px', padding:'12px 16px', borderBottom:'1px solid var(--rule)', alignItems:'center' }}>
            <div style={{ fontSize:12 }}>{it.built.adapter.label}</div>
            <div style={{ fontSize:12, fontFamily:'var(--ff-mono, monospace)', color:'var(--ink-2)' }}>{it.built.name}</div>
            <div style={{ fontSize:12 }}>{it.built.entityCount}</div>
            <div style={{ fontSize:12, textTransform:'uppercase' }}>{it.channel}</div>
            <div><Pill tone={it.status === 'sent' ? 'ok' : 'warn'}>{it.status}</Pill></div>
            <div style={{ display:'flex', gap:6 }}>
              <Btn kind="sec" onClick={() => onDownload(it.built)} style={{ padding:'4px 8px', fontSize:10 }}>↓</Btn>
              {it.status === 'queued' && <Btn kind="pri" onClick={() => onSend(it)} style={{ padding:'4px 10px', fontSize:10 }}>Send</Btn>}
            </div>
          </div>
        ))}
      </div>
    );
  }

  // ════════════════════════════════════════════════════════════════
  // 05 HISTORY
  // ════════════════════════════════════════════════════════════════
  function HistoryTab({ history, onClear }) {
    if (!history.length) {
      return <div style={{ padding:40, textAlign:'center', border:'1px dashed var(--rule)', color:'var(--ink-2)' }}>No transmissions yet.</div>;
    }
    return (
      <div>
        <div style={{ display:'flex', marginBottom:14 }}>
          <span style={{ flex:1 }} />
          <Btn kind="sec" onClick={() => { if (confirm('Clear all history?')) onClear(); }}>Clear history</Btn>
        </div>
        <div style={{ border:'1px solid var(--rule)' }}>
          <div style={{ display:'grid', gridTemplateColumns:'180px 1fr 110px 110px 100px 100px', padding:'10px 16px', borderBottom:'1px solid var(--rule)', background:'var(--surface)' }}>
            {['SENT','FORMAT','ENTITIES','CHANNEL','SIZE','STATUS'].map((h) => (
              <Mono key={h} upper size={9} color="var(--ink-3)">{h}</Mono>
            ))}
          </div>
          {history.map((r) => (
            <div key={r.id} style={{ display:'grid', gridTemplateColumns:'180px 1fr 110px 110px 100px 100px', padding:'12px 16px', borderBottom:'1px solid var(--rule)', alignItems:'center' }}>
              <div style={{ fontSize:11, fontFamily:'var(--ff-mono, monospace)', color:'var(--ink-2)' }}>{new Date(r.at).toLocaleString()}</div>
              <div style={{ fontSize:12 }}>{r.adapter}</div>
              <div style={{ fontSize:12 }}>{r.entityCount}</div>
              <div style={{ fontSize:12, textTransform:'uppercase' }}>{r.channel}</div>
              <div style={{ fontSize:11, color:'var(--ink-2)' }}>{((r.fileSize || 0) / 1024).toFixed(1)} KB</div>
              <div><Pill tone="ok">{r.status}</Pill></div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  window.ScreenBulkReg = ScreenBulkReg;
})();
