/* ========================================================================
   DETAIL PAGE — records-nav (left) + detail body (header, segmented
   sections, tables / signal cards). Port of 08-detail.js rendering.
   ======================================================================== */

/* ---- shared layout helpers ---------------------------------------------- */
function DvCard({ title, count, children }) {
  return (
    <div className="dv-card">
      <div className="dv-card-head">
        <span className="dv-card-title">{title}</span>
        {count != null ? <span className="dv-card-count">{count}</span> : null}
      </div>
      {children}
    </div>
  );
}

/* Bare results-card table matching the search-results styling. */
function ResultsTableLike({ columns, rows }) {
  return (
    <div className="results-card">
      <table className="data-table">
        <thead>
          <tr>
            {columns.map((c, i) => (
              <th key={i} style={c.align === 'right' ? { textAlign: 'right' } : undefined}>{c.label}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((r, ri) => (
            <tr key={ri}>
              {columns.map((c, ci) => {
                const raw = r[c.key];
                const val = c.format ? c.format(raw) : (raw == null || raw === '' ? '—' : raw);
                const muted = (raw == null || raw === '') ? ' cell-muted' : '';
                let onClick;
                if (c.target) {
                  const t = c.target(r);
                  if (t && t.entity && t.key) onClick = () => detailLinkClick(t.entity, String(t.key));
                }
                return (
                  <td
                    key={ci}
                    className={((c.cls || '') + muted).trim() || undefined}
                    style={c.align === 'right' ? { textAlign: 'right' } : undefined}
                    onClick={onClick}
                  >{String(val)}</td>
                );
              })}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function DvTableEmpty({ children }) {
  return <div className="dv-table-empty">{children}</div>;
}

/* ---- section renderers ----------------------------------------------------- */
function AccountSignalsTab({ a }) {
  const signals = (a.signals || []).slice().sort((x, y) => (x.daysAgo || 0) - (y.daysAgo || 0));
  if (!signals.length) {
    return (
      <DvCard title="Signals">
        <span className="dv-field-value muted">No signals on this account yet. They appear here when our AI surfaces relevant activity.</span>
      </DvCard>
    );
  }
  return <React.Fragment>{signals.map((s, i) => <SignalCard s={s} sourceAccount={a} key={i} />)}</React.Fragment>;
}

function AccountContactsTab({ a }) {
  const contacts = a.contacts || [];
  if (!contacts.length) return <DvTableEmpty>No contacts on this account yet.</DvTableEmpty>;
  return (
    <div className="results-card">
      <table className="data-table">
        <thead><tr><th>Contact</th><th>Title</th><th>Department</th><th>Account</th><th>State</th></tr></thead>
        <tbody>
          {contacts.map((c, i) => (
            <tr key={i}>
              <td className="cell-link" onClick={() => detailLinkClick('contacts', contactDetailKey(a.accountId, c.email || c.name), null, { entity: 'accounts', key: accountDetailKey(a.accountId) })}>{c.name}</td>
              <td>{c.title || ''}</td>
              <td className="cell-muted">{c.department || ''}</td>
              <td className="cell-link" onClick={() => detailLinkClick('accounts', accountDetailKey(a.accountId))}>{a.name || ''}</td>
              <td className="cell-mono cell-muted">{a.state || ''}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function sectionsFor(entity, record) {
  if (entity === 'accounts') return accountSections(record);
  if (entity === 'contacts') return contactSections(record);
  if (entity === 'signals') return signalSections(record);
  return [];
}
function accountSections(a) {
  const signals = a.signals || [];
  const contacts = a.contacts || [];
  const docs = documentsForAccount(a);
  const tech = mockTechnologiesFor(a);
  const pos = mockPOsFor(a);
  return [
    { id: 'signals', label: 'Signals', count: signals.length, render: () => <AccountSignalsTab a={a} /> },
    { id: 'contacts', label: 'Contacts', count: contacts.length, render: () => <AccountContactsTab a={a} /> },
    { id: 'documents', label: 'Documents', count: docs.length, render: () => (
        docs.length
          ? <ResultsTableLike columns={[
              { label: 'Name', key: 'name', cls: 'cell-link' },
              { label: 'Type', key: 'type' },
              { label: 'Date', key: 'date', cls: 'cell-mono cell-muted', align: 'right' },
            ]} rows={docs} />
          : <DvTableEmpty>No documents indexed for this account.</DvTableEmpty>
      ) },
    { id: 'tech', label: 'Technologies', count: tech.length, render: () => (
        tech.length
          ? <ResultsTableLike columns={[
              { label: 'Function', key: 'function' },
              { label: 'Vendor', key: 'vendor', cls: 'cell-link' },
            ]} rows={tech} />
          : <DvTableEmpty>No technology vendors identified for this account.</DvTableEmpty>
      ) },
    { id: 'pos', label: 'Purchase orders', count: pos.length, render: () => (
        pos.length
          ? <ResultsTableLike columns={[
              { label: 'Number', key: 'number', cls: 'cell-link cell-mono' },
              { label: 'Date', key: 'date', cls: 'cell-mono' },
              { label: 'Vendor', key: 'vendor' },
              { label: 'Description', key: 'description' },
              { label: 'Amount', key: 'amount', cls: 'cell-mono', align: 'right', format: (v) => `$${Number(v).toLocaleString()}` },
            ]} rows={pos} />
          : <DvTableEmpty>No purchase orders on file.</DvTableEmpty>
      ) },
  ];
}
function contactSections(c) {
  const colleagues = colleaguesFor(c);
  const prior = mockPriorAffiliationsFor(c);
  const docs = documentsForContact(c);
  return [
    { id: 'colleagues', label: 'Colleagues', count: colleagues.length, render: () => (
        colleagues.length
          ? <ResultsTableLike columns={[
              { label: 'Name', key: 'name', cls: 'cell-link',
                target: (row) => ({ entity: 'contacts', key: contactDetailKey(row.accountId, row.email || row.name) }) },
              { label: 'Title', key: 'title' },
              { label: 'Account', key: 'account', cls: 'cell-link',
                target: (row) => ({ entity: 'accounts', key: accountDetailKey(row.accountId) }) },
              { label: 'Email', key: 'email', cls: 'cell-mono' },
              { label: 'Phone', key: 'phone', cls: 'cell-mono' },
              { label: 'Confidence', key: 'confidence', cls: 'cell-mono', align: 'right', format: (v) => `${v}/100` },
            ]} rows={colleagues} />
          : <DvTableEmpty>No other contacts on this account.</DvTableEmpty>
      ) },
    { id: 'prior', label: 'Prior affiliations', count: prior.length, render: () => (
        prior.length
          ? <ResultsTableLike columns={[
              { label: 'Account', key: 'account', cls: 'cell-link' },
              { label: 'Title', key: 'title' },
              { label: 'Dates', key: 'dateRange', cls: 'cell-mono', align: 'right' },
            ]} rows={prior} />
          : <DvTableEmpty>No prior affiliations on record.</DvTableEmpty>
      ) },
    { id: 'documents', label: 'Documents', count: docs.length, render: () => (
        docs.length
          ? <ResultsTableLike columns={[
              { label: 'Name', key: 'name', cls: 'cell-link' },
              { label: 'Type', key: 'type' },
              { label: 'Date', key: 'date', cls: 'cell-mono cell-muted', align: 'right' },
            ]} rows={docs} />
          : <DvTableEmpty>No documents reference this contact.</DvTableEmpty>
      ) },
  ];
}
function signalSections(s) {
  const a = s.account;
  if (!a) return [];
  return accountSections(a)
    .filter(sec => sec.count > 0)
    .sort((x, y) => y.count - x.count);
}

/* ---- detail header ------------------------------------------------------------ */
function detailHeaderConfig(entity, r) {
  if (entity === 'accounts') {
    const websiteHost = (r.name || '').toLowerCase().replace(/[^a-z0-9]+/g, '').slice(0, 28) + '.gov';
    return {
      diorama: dioramaVariantFor(r),
      eyebrow: `${r.state || ''}${r.region ? ', ' + r.region : ''}`,
      name: r.name,
      facts: [
        { icon: 'tag', label: 'Type', value: r.type },
        { icon: 'globe', label: 'Website', link: `https://${websiteHost}`, value: websiteHost },
        { icon: 'map-pin', label: 'State', value: r.state },
        { icon: 'book', label: 'FY budget', value: r.budget != null ? `$${formatBudget(r.budget)}` : '—', mono: true },
        { icon: 'users', label: 'Population', value: r.population != null ? formatPopulation(r.population) : '—', mono: true },
      ],
    };
  }
  if (entity === 'contacts') {
    const a = r.account || {};
    return {
      initials: initialsOf(r.name),
      eyebrow: `${r.title || ''} · ${a.name || ''}`,
      name: r.name,
      facts: [
        { icon: 'briefcase', label: 'Title', value: r.title },
        { icon: 'at-sign', label: 'Email', value: r.email, mono: true },
        { icon: 'phone', label: 'Phone', value: r.phone || mockPhoneFor(r), mono: true },
        { icon: 'layers', label: 'Department', value: r.department },
        { icon: 'building-2', label: 'Account', value: a.name },
        { icon: 'star', label: 'Seniority', value: r.seniority },
        { icon: 'percent', label: 'Confidence', value: r.confidence },
      ],
    };
  }
  if (entity === 'signals') {
    const a = r.account;
    return a
      ? { ...detailHeaderConfig('accounts', a), accountLink: a.accountId }
      : { eyebrow: r.sigType || '', name: r.name || r.sigType, facts: [] };
  }
  return { eyebrow: '', name: '', facts: [] };
}

function DetailHeader({ entity, record }) {
  const cfg = detailHeaderConfig(entity, record);
  return (
    <div className="detail-head">
      {cfg.diorama ? (
        <div className="dv-illustration">
          <img src={(window.__resources&&window.__resources["dioramaMuni_"+cfg.diorama])||`assets/diorama-muni-${cfg.diorama}.svg`} alt="" width="162" height="139" />
        </div>
      ) : cfg.initials ? (
        <div className="dv-illustration"><div className="dv-illustration--placeholder">{cfg.initials}</div></div>
      ) : null}
      <div className="detail-head-text">
        {cfg.eyebrow ? <div className="dv-eyebrow">{cfg.eyebrow}</div> : null}
        <h1 className="detail-record-name">
          {cfg.accountLink ? (
            <a
              className="detail-record-name-link" href="#"
              onClick={(e) => { e.preventDefault(); detailLinkClick('accounts', accountDetailKey(cfg.accountLink)); }}
            >{cfg.name}</a>
          ) : cfg.name}
        </h1>
        <div className="dv-facts-grid">
          {cfg.facts.map((f, i) => (
            <div className="dv-fact" key={i}>
              <span className="dv-fact-label">
                <Icon name={f.icon} className="dv-fact-icon" size={14} />
                {f.label}
              </span>
              <span className={cx('dv-fact-value', f.mono && 'mono', (f.value == null || f.value === '') && 'muted')}>
                {f.link ? <a href={f.link} target="_blank" rel="noopener">{f.value}</a>
                  : (f.value == null || f.value === '' ? '—' : String(f.value))}
              </span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ---- draft toolbar split (signal detail + inbox body) -------------------------- */
function DraftEmailSplit() {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      if (ref.current && ref.current.contains(e.target)) return;
      setOpen(false);
    };
    document.addEventListener('mousedown', onDown);
    return () => document.removeEventListener('mousedown', onDown);
  }, [open]);
  return (
    <div className="card-split-btn" ref={ref}>
      <button className="card-split-main" type="button">
        <span className="icon-frame"><Icon name="pen-line" size={16} /></span>
        Draft Email
      </button>
      <div className="card-split-divider"></div>
      <button
        className="card-split-trigger" type="button" aria-label="More draft options"
        onClick={(e) => { e.preventDefault(); e.stopPropagation(); setOpen(o => !o); }}
      ><Icon name="chevron-down" size={16} /></button>
      {open ? (
        <div className="btn-split-menu">
          <button className="btn-split-item" type="button" onClick={() => setOpen(false)}>
            <Icon name="list-checks" size={14} /> Write Talking Points
          </button>
          <button className="btn-split-item" type="button" onClick={() => setOpen(false)}>
            <Icon name="zap" size={14} /> Create a Play
          </button>
        </div>
      ) : null}
    </div>
  );
}

/* ---- records nav ----------------------------------------------------------------- */
function RecordsNav({ entity, records, activeKey, parentRecord, onSelect, onBack, backLabel, headTitle, headCount, selectable = true }) {
  useAppState();
  const selSet = state.selectedRowIds[entity] || new Set();
  return (
    <div className="records-nav" id="records-nav">
      <button className="rn-back" type="button" onClick={onBack}>
        <Icon name="arrow-left" size={14} />
        <span className="rn-back-label">{backLabel}</span>
      </button>
      <div className="rn-head">
        <span className="rn-head-title">{headTitle}</span>
        <span className="rn-head-count">{headCount}</span>
      </div>
      <div className="rn-sel-row">
        {selectable && selSet.size > 0 ? (
          <span className="rn-sel-badge"><Icon name="square-check" size={11} />{selSet.size} selected</span>
        ) : null}
      </div>
      <div className="rn-list">
        {records.length === 0 ? <div className="rn-empty">No {entity} in this view.</div> : null}
        {records.map(r => {
          const k = detailKeyFor(r, entity);
          const checked = selSet.has(k);
          return (
            <button
              key={k}
              className={cx('rn-item', k === activeKey && 'active')}
              data-detail-key={k}
              type="button"
              onClick={() => onSelect(k)}
            >
              {selectable ? (
                <span
                  className={cx('rn-item-check', checked && 'checked')}
                  onClick={(e) => {
                    e.stopPropagation();
                    if (checked) selSet.delete(k); else selSet.add(k);
                    notify();
                  }}
                >{checked ? <Icon name="check" size={12} /> : null}</span>
              ) : null}
              <span className="rn-item-body">
                <span className="rn-item-name">{recordDisplayName(r, entity)}</span>
                <span className="rn-item-meta">{recordsNavSecondary(r, entity)}</span>
              </span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* ---- header bulk actions (detail mode) --------------------------------------------- */
function HeaderBulkActions() {
  useAppState();
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      if (ref.current && ref.current.contains(e.target)) return;
      setOpen(false);
    };
    document.addEventListener('mousedown', onDown);
    return () => document.removeEventListener('mousedown', onDown);
  }, [open]);
  if (!state.detailRecord) return null;
  const entity = state.detailRecord.entity;
  const set = state.selectedRowIds[entity];
  const n = set ? set.size : 0;
  if (n === 0) return null;
  const actions = entity === 'signals'
    ? [
        { id: 'opportunities', icon: 'briefcase-business', label: 'Save to Opportunities' },
        { id: 'worksheet', icon: 'arrow-down-to-line', label: 'Save to Worksheet' },
        { id: 'crm-salesforce', icon: 'brand-salesforce', label: 'Save to Salesforce' },
        { id: 'crm-hubspot', icon: 'brand-hubspot', label: 'Save to HubSpot' },
        { id: 'csv', icon: 'file-down', label: 'Save to CSV' },
      ]
    : [
        { id: 'worksheet', icon: 'arrow-down-to-line', label: 'Save to Worksheet' },
        { id: 'crm-salesforce', icon: 'brand-salesforce', label: 'Save to Salesforce' },
        { id: 'crm-hubspot', icon: 'brand-hubspot', label: 'Save to HubSpot' },
        { id: 'csv', icon: 'file-down', label: 'Save to CSV' },
      ];
  const def = actions[0];
  const doAction = (id) => {
    setOpen(false);
    if (id === 'worksheet' && typeof openSaveToWorksheetModal === 'function') {
      openSaveToWorksheetModal({ count: n, entity });
    }
  };
  return (
    <div className="header-bulk-split" ref={ref}>
      <button className="hbs-main" type="button" onClick={() => doAction(def.id)}>
        <Icon name={def.icon} size={16} />
        {def.label} ({n})
      </button>
      <div className="hbs-divider"></div>
      <button
        className="hbs-trigger" type="button" aria-label="More save options"
        onClick={(e) => { e.preventDefault(); e.stopPropagation(); setOpen(o => !o); }}
      ><Icon name="chevron-down" size={16} /></button>
      {open ? (
        <div className="hbs-menu">
          {actions.slice(1).map(a => (
            <button className="hbs-item" type="button" key={a.id} onClick={() => doAction(a.id)}>
              <Icon name={a.icon} size={14} />
              {a.label}
            </button>
          ))}
        </div>
      ) : null}
    </div>
  );
}

/* ---- breadcrumbs (search + detail) -------------------------------------------------- */
function SearchBreadcrumbs() {
  useAppState();
  const dr = state.detailRecord;
  if (!dr) {
    return (
      <div className="breadcrumbs">
        <img src={(window.__resources&&window.__resources.logoColor)||"react/assets/logo-color.svg"} alt="Pursuit" width="14" height="17" />
        <Icon name="chevron-right" className="breadcrumb-sep" size={14} />
        <span className="breadcrumb-item current">Search</span>
      </div>
    );
  }
  const record = findDetailRecord(dr.entity, dr.key);
  const parentRecord = dr.parent ? findDetailRecord(dr.parent.entity, dr.parent.key) : null;
  const rootEntity = parentRecord ? dr.parent.entity : dr.entity;
  return (
    <div className="breadcrumbs">
      <img src={(window.__resources&&window.__resources.logoColor)||"react/assets/logo-color.svg"} alt="Pursuit" width="14" height="17" />
      <Icon name="chevron-right" className="breadcrumb-sep" size={14} />
      <button className="breadcrumb-link" type="button" onClick={exitDetail}>Search</button>
      <Icon name="chevron-right" className="breadcrumb-sep" size={14} />
      <button className="breadcrumb-link" type="button" onClick={exitDetail}>{ENTITY[rootEntity].plural}</button>
      {parentRecord ? (
        <React.Fragment>
          <Icon name="chevron-right" className="breadcrumb-sep" size={14} />
          <button className="breadcrumb-link" type="button" onClick={popDetailToParent}>
            {recordDisplayName(parentRecord, dr.parent.entity)}
          </button>
        </React.Fragment>
      ) : null}
      <Icon name="chevron-right" className="breadcrumb-sep" size={14} />
      <span className="breadcrumb-item current">{record ? recordDisplayName(record, dr.entity) : '…'}</span>
    </div>
  );
}

/* ---- the page ------------------------------------------------------------------------ */
function DetailPage() {
  useAppState();
  const dr = state.detailRecord;
  const record = dr ? findDetailRecord(dr.entity, dr.key) : null;

  // rowKey no longer resolves — back out to results.
  React.useEffect(() => {
    if (dr && !record) exitDetail();
  }, [dr ? dr.key : null, !!record]);

  // Keyboard ↑/↓ moves the records-nav selection.
  React.useEffect(() => {
    const onKey = (e) => {
      if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return;
      if (e.metaKey || e.ctrlKey || e.altKey) return;
      const ae = document.activeElement;
      if (ae && ae !== document.body) {
        const tag = ae.tagName;
        if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;
        if (ae.isContentEditable) return;
      }
      const rows = Array.from(document.querySelectorAll('.rn-item[data-detail-key]'));
      if (!rows.length || !state.detailRecord) return;
      e.preventDefault();
      const idx = rows.findIndex(r => r.dataset.detailKey === state.detailRecord.key);
      let next;
      if (idx < 0) next = e.key === 'ArrowDown' ? rows[0] : rows[rows.length - 1];
      else {
        let n = idx + (e.key === 'ArrowDown' ? 1 : -1);
        if (n < 0) n = 0;
        if (n >= rows.length) n = rows.length - 1;
        if (n === idx) return;
        next = rows[n];
      }
      switchDetailRecord(next.dataset.detailKey);
    };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, []);

  if (!dr || !record) return null;

  let navRecords;
  let parentRecord = null;
  if (dr.parent) {
    parentRecord = findDetailRecord(dr.parent.entity, dr.parent.key);
    if (parentRecord) {
      navRecords = childrenOf(parentRecord, dr.parent.entity, dr.entity);
    } else {
      navRecords = applyFilters(datasetFor(dr.entity), state.filters, dr.entity);
    }
  } else {
    navRecords = applyFilters(datasetFor(dr.entity), state.filters, dr.entity);
  }

  const backLabel = parentRecord
    ? `Back to ${recordDisplayName(parentRecord, dr.parent.entity)}`
    : 'Back to results';
  const headCount = parentRecord
    ? `${navRecords.length} ${navRecords.length === 1 ? ENTITY[dr.entity].singular.toLowerCase() : ENTITY[dr.entity].plural.toLowerCase()}`
    : `${navRecords.length} ${navRecords.length === 1 ? 'result' : 'results'}`;

  return (
    <div className="body">
      <div className="floating-widget-spacer">
        <div className="floating-widget">
          <RecordsNav
            entity={dr.entity}
            records={navRecords}
            activeKey={dr.key}
            parentRecord={parentRecord}
            onSelect={switchDetailRecord}
            onBack={parentRecord ? popDetailToParent : exitDetail}
            backLabel={backLabel}
            headTitle={ENTITY[dr.entity].plural}
            headCount={headCount}
          />
        </div>
      </div>
      <div className="content-panel">
        <div id="work-area">
          <div data-role="detail">
            <DetailBody entity={dr.entity} record={record} />
          </div>
        </div>
      </div>
      <SaveSearchModal />
    </div>
  );
}

/* data-agent-ref for a detail record — frozen registry key convention. */
function detailAgentRef(entity, record) {
  if (!record) return undefined;
  if (entity === 'accounts') return 'accounts:' + record.accountId;
  if (entity === 'contacts') return 'contacts:' + (record.account?.accountId || '') + '::' + (record.email || record.name);
  return 'signals:' + signalRowKey(record);
}

function DetailBody({ entity, record, extraSections, activeSectionId, onSelectSection }) {
  useAppState();
  if (entity === 'signals') {
    return (
      <React.Fragment>
        <DetailHeader entity={entity} record={record} />
        <div className="dv-page-toolbar">
          <span className="dv-page-toolbar-spacer"></span>
          <DraftEmailSplit />
          <button className="btn-secondary-cta dv-page-ask">
            <span className="icon-frame"><Icon name="sparkles" size={16} /></span>
            Chat about Account
          </button>
        </div>
        <div className="detail-body" data-agent-ref={detailAgentRef(entity, record)}>
          <SignalCard s={record} sourceAccount={record.account} rich />
        </div>
      </React.Fragment>
    );
  }
  const baseSections = sectionsFor(entity, record);
  const sections = (extraSections && extraSections.length) ? [...extraSections, ...baseSections] : baseSections;
  let activeId = activeSectionId != null ? activeSectionId : state.detailSectionByEntity[entity];
  let active = sections.find(s => s.id === activeId);
  if (!active && sections.length) active = sections[0];
  const select = onSelectSection || setDetailSection;

  const segmented = sections.length ? (
    <div className="dv-segmented" role="tablist">
      {sections.map(s => (
        <button
          key={s.id}
          className={cx('dv-seg', active && s.id === active.id && 'active')}
          role="tab" type="button"
          onClick={() => select(s.id)}
        >
          {s.label}
          {s.count != null ? <span className="dv-seg-count">{s.count}</span> : null}
        </button>
      ))}
    </div>
  ) : <div className="dv-segmented-empty">No related content yet.</div>;

  return (
    <React.Fragment>
      <DetailHeader entity={entity} record={record} />
      {entity === 'accounts' ? (
        <div className="dv-tabbar-row">
          {segmented}
          <button className="btn-secondary-cta dv-tabbar-cta">
            <span className="icon-frame"><Icon name="sparkles" size={16} /></span>
            Chat about Account
          </button>
        </div>
      ) : segmented}
      <div className="detail-body" data-agent-ref={detailAgentRef(entity, record)}>{active ? active.render() : null}</div>
    </React.Fragment>
  );
}

window.PAGE_BREADCRUMBS = window.PAGE_BREADCRUMBS || {};
window.PAGE_BREADCRUMBS.search = SearchBreadcrumbs;
Object.assign(window, {
  DetailPage, DetailBody, DetailHeader, RecordsNav, HeaderBulkActions,
  DraftEmailSplit, ResultsTableLike, DvCard, DvTableEmpty, sectionsFor,
  SearchBreadcrumbs, detailHeaderConfig,
});
