/* ========================================================================
   RESULTS — entity switch, results bar (selection + save split), data
   table with checkbox selection, smart-parse skeleton, empty-state hero.
   Port of renderEntitySwitch / renderResults / resultsTableHTML.
   ======================================================================== */

function EntitySwitch() {
  useAppState();
  const st = fpState();
  const signalLocked = hasSignalFilter();
  const contactLocked = hasContactFilter();
  const hasResults = st.filters.some(isFilterComplete);
  const signalReachable = signalLocked || hasProfileSignalCriteria();
  // Coercions (mirror of renderEntitySwitch) — safe during render since
  // they converge immediately.
  if (signalLocked && st.entity === 'contacts') st.entity = 'signals';
  if (contactLocked && st.entity === 'signals') st.entity = 'contacts';
  const entities = ['accounts', 'contacts', 'signals'];
  const disabled = {
    accounts: false,
    contacts: signalLocked,
    signals: !signalReachable && hasResults,
  };
  const disabledReason = {
    contacts: 'Not available with a Signal filter applied',
    signals: contactLocked
      ? 'Not available with a Contact filter applied'
      : 'Add a Signal filter to enable',
  };
  const committed = st.filters.filter(isFilterComplete);
  return (
    <div className="entity-switch" id="entity-switch">
      {entities.map(e => {
        const t = ENTITY[e];
        const isDisabled = disabled[e];
        const count = (!isDisabled && committed.length > 0)
          ? applyFilters(datasetFor(e), st.filters, e).length
          : null;
        return (
          <button
            key={e}
            className={cx(st.entity === e && 'active', isDisabled && 'disabled')}
            disabled={isDisabled || undefined}
            aria-disabled={isDisabled ? 'true' : undefined}
            data-helper-tip={isDisabled ? (disabledReason[e] || '') : undefined}
            onClick={isDisabled ? undefined : () => setEntity(e)}
          >
            <span className="es-label">{t.plural}</span>
            {count != null ? <span className="es-count">{count.toLocaleString()}</span> : null}
          </button>
        );
      })}
    </div>
  );
}

/* ---- selection ------------------------------------------------------------- */
function rowKey(r) {
  if (fpState().entity === 'accounts') return r.accountId;
  if (fpState().entity === 'contacts') return (r.account?.accountId || '') + '::' + (r.email || r.name);
  return (r.account?.accountId || '') + '::' + (r.name || r.sigType) + '::' + (r.date || r.daysAgo);
}
function toggleRowSelect(id) {
  const set = state.selectedRowIds[fpState().entity];
  if (set.has(id)) set.delete(id); else set.add(id);
  notify();
}
function toggleAllRowSelect(visibleIds) {
  const set = state.selectedRowIds[fpState().entity];
  const allSelected = visibleIds.every(id => set.has(id));
  if (allSelected) visibleIds.forEach(id => set.delete(id));
  else visibleIds.forEach(id => set.add(id));
  notify();
}

function RowCheckbox({ id }) {
  const set = state.selectedRowIds[fpState().entity];
  const checked = set.has(id);
  return (
    <td className="cell-select">
      <label className="cb-wrap">
        <input type="checkbox" className="row-check" checked={checked}
          onClick={(e) => e.stopPropagation()}
          onChange={() => toggleRowSelect(id)} />
        <span className={cx('cb-box', checked && 'checked')}>
          {checked ? <Icon name="check" size={12} /> : null}
        </span>
      </label>
    </td>
  );
}

function openDetail(entity, key, opts) {
  if (typeof enterDetail === 'function') enterDetail(entity, key, opts || {});
}

/* Cross-record link helper — mirrors the [data-detail-target-*] delegated
   handler from Mk7: drill-in vs lateral resolution. */
function detailLinkClick(targetEntity, targetKey, targetSection, explicitParent) {
  if (targetSection) state.detailSectionByEntity[targetEntity] = targetSection;
  const opts = {};
  // An explicit parent (passed by callers that already know the owning record —
  // e.g. the account-contacts table, which renders inside both the search-detail
  // AND the worksheet-detail view) always wins. This avoids inferring the parent
  // from state.detailRecord, which is stale/null in the worksheet context.
  if (explicitParent && explicitParent.entity && explicitParent.key) {
    if (state.page !== 'search') state.page = 'search';
    openDetail(targetEntity, targetKey, { parent: explicitParent });
    return;
  }
  const cur = state.detailRecord;
  if (cur && cur.entity === 'accounts' && (targetEntity === 'contacts' || targetEntity === 'signals')) {
    if (targetKey.startsWith(cur.key + '::')) opts.parent = { entity: 'accounts', key: cur.key };
  } else if (cur && cur.parent && cur.parent.entity === 'accounts'
             && (targetEntity === 'contacts' || targetEntity === 'signals')
             && targetKey.startsWith(cur.parent.key + '::')) {
    opts.parent = { entity: 'accounts', key: cur.parent.key };
  } else if (!cur && (state.page === 'opportunities' || state.page === 'saved-opportunities')
             && (targetEntity === 'contacts' || targetEntity === 'signals')) {
    const idx = targetKey.indexOf('::');
    if (idx > 0) opts.parent = { entity: 'accounts', key: targetKey.slice(0, idx) };
  }
  if (state.page !== 'search') state.page = 'search';
  openDetail(targetEntity, targetKey, opts);
}

/* ---- results table ----------------------------------------------------------- */
function ResultsTable({ records }) {
  useAppState();
  const st = fpState();
  if (records.length === 0) {
    return <div className="empty-table"><strong>No {st.entity} match your filters</strong>Try removing a chip or switching entities.</div>;
  }
  const shown = records.slice(0, 10);
  const visibleIds = shown.map(rowKey);
  const set = state.selectedRowIds[st.entity];
  const allChecked = visibleIds.every(id => set.has(id));
  const anyChecked = visibleIds.some(id => set.has(id));
  const headerCheckbox = (
    <th className="cell-select">
      <label className="cb-wrap">
        <input type="checkbox" className="row-check" checked={allChecked}
          onClick={(e) => e.stopPropagation()}
          onChange={() => toggleAllRowSelect(visibleIds)} />
        <span className={cx('cb-box', allChecked ? 'checked' : (anyChecked ? 'indeterminate' : ''))}>
          {allChecked ? <Icon name="check" size={12} /> : null}
          {(!allChecked && anyChecked) ? <Icon name="minus" size={12} /> : null}
        </span>
      </label>
    </th>
  );
  if (st.entity === 'accounts') {
    return (
      <table className="data-table">
        <thead><tr>{headerCheckbox}<th>Account</th><th>State</th><th>Type</th><th>Budget</th><th>Population</th><th>Contacts</th></tr></thead>
        <tbody>
          {shown.map(r => (
            <tr key={rowKey(r)} data-agent-ref={'accounts:' + rowKey(r)}>
              <RowCheckbox id={rowKey(r)} />
              <td className="cell-link" onClick={(e) => { e.stopPropagation(); openDetail(st.entity, rowKey(r)); }}>{r.name}</td>
              <td className="cell-muted">{r.state}</td>
              <td>{r.type}</td>
              <td className="cell-mono">${r.budget.toLocaleString()}M</td>
              <td className="cell-mono">{r.population.toLocaleString()}K</td>
              <td className="cell-mono cell-link"
                onClick={(e) => { e.stopPropagation(); detailLinkClick('accounts', String(r.accountId), 'contacts'); }}>
                {(r.contacts || []).length}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    );
  }
  if (st.entity === 'contacts') {
    return (
      <table className="data-table">
        <thead><tr>{headerCheckbox}<th>Contact</th><th>Title</th><th>Department</th><th>Account</th><th>State</th></tr></thead>
        <tbody>
          {shown.map(r => (
            <tr key={rowKey(r)} data-agent-ref={'contacts:' + rowKey(r)}>
              <RowCheckbox id={rowKey(r)} />
              <td className="cell-link" onClick={(e) => { e.stopPropagation(); openDetail(st.entity, rowKey(r)); }}>{r.name}</td>
              <td>{r.title}</td>
              <td className="cell-muted">{r.department}</td>
              <td className="cell-link" onClick={(e) => { e.stopPropagation(); detailLinkClick('accounts', String(r.account?.accountId || '')); }}>{r.account?.name || ''}</td>
              <td className="cell-mono cell-muted">{r.account?.state || ''}</td>
            </tr>
          ))}
        </tbody>
      </table>
    );
  }
  return (
    <table className="data-table data-table-signals">
      <thead><tr>{headerCheckbox}<th>Signal</th><th>Type</th><th>Account</th><th>Synopsis</th><th>Date</th></tr></thead>
      <tbody>
        {shown.map(r => (
          <tr key={rowKey(r)} data-agent-ref={'signals:' + rowKey(r)}>
            <RowCheckbox id={rowKey(r)} />
            <td className="cell-link" onClick={(e) => { e.stopPropagation(); openDetail(st.entity, rowKey(r)); }}>{r.name || r.sigType}</td>
            <td className="cell-muted">{r.sigType}</td>
            <td className="cell-link" onClick={(e) => { e.stopPropagation(); detailLinkClick('accounts', String(r.account?.accountId || '')); }}>{r.account?.name || ''}</td>
            <td className="cell-synopsis">{r.text || ''}</td>
            <td className="cell-mono cell-muted">{r.date || ''}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

/* ---- results bar (selection badge + save split) -------------------------------- */
function ResultsSaveSplit({ filtered }) {
  useAppState();
  const [menuOpen, setMenuOpen] = React.useState(false);
  const splitRef = React.useRef(null);
  const st = fpState();
  const selSet = state.selectedRowIds[st.entity];
  const filteredIds = filtered.slice(0, 10).map(rowKey);
  const selectedCount = filteredIds.filter(id => selSet.has(id)).length;

  React.useEffect(() => {
    if (!menuOpen) return;
    const onDown = (e) => {
      if (splitRef.current && splitRef.current.contains(e.target)) return;
      setMenuOpen(false);
    };
    document.addEventListener('mousedown', onDown);
    return () => document.removeEventListener('mousedown', onDown);
  }, [menuOpen]);

  const isSignals = st.entity === 'signals';
  const primaryAction = isSignals ? 'opportunities' : 'worksheet';
  const primaryIcon = isSignals ? 'briefcase-business' : 'arrow-down-to-line';
  const primaryLabel = isSignals ? 'Save to Opportunities' : 'Save to Worksheet';
  const menuItems = [
    ['opportunities', 'briefcase-business', 'Save to Opportunities'],
    ['worksheet', 'layout-list', 'Save to Worksheet'],
    ['crm-salesforce', 'brand-salesforce', 'Save to Salesforce'],
    ['crm-hubspot', 'brand-hubspot', 'Save to HubSpot'],
    ['csv', 'file-down', 'Save to CSV'],
  ].filter(([k]) => isSignals || k !== 'opportunities')
   .filter(([k]) => k !== primaryAction);

  const doAction = (action) => {
    setMenuOpen(false);
    const entity = st.entity;
    const count = state.selectedRowIds[entity]?.size || 0;
    if (action === 'worksheet' && typeof openSaveToWorksheetModal === 'function') {
      openSaveToWorksheetModal({ count, entity });
    } else if ((action === 'crm-salesforce' || action === 'crm-hubspot' || action === 'csv') && typeof openExportModal === 'function') {
      // Search results carry no AI columns — only the standard fields are
      // exportable. Pass a representative record so the preview is real.
      const r0 = filtered && filtered[0];
      let record = null, recordName = null;
      const host = (n) => (typeof wsWebsiteHost === 'function' && n) ? wsWebsiteHost(n) : undefined;
      const popStr = (p) => (p != null ? (p * 1000).toLocaleString('en-US') : undefined);
      if (r0 && entity === 'contacts') {
        record = { name: r0.name, title: r0.title, department: r0.department, email: r0.email, account: r0.account?.name };
        recordName = r0.name;
      } else if (r0 && entity === 'signals') {
        const a = r0.account || {};
        record = { name: a.name, state: a.state, type: a.type, population: popStr(a.population), website: host(a.name) };
        recordName = a.name || r0.name;
      } else if (r0) {
        record = { name: r0.name, state: r0.state, type: r0.type, population: popStr(r0.population), website: host(r0.name) };
        recordName = r0.name;
      }
      openExportModal(action.startsWith('crm') ? 'crm' : action, {
        count, entity, sample: {}, record, recordName,
        provider: action === 'crm-hubspot' ? 'hubspot' : 'salesforce',
      });
    }
  };

  return (
    <div className="results-bar">
      <div className="results-count">
        {selectedCount > 0 ? (
          <span className="selection-badge"><Icon name="square-check" size={14} />{selectedCount} selected</span>
        ) : null}
      </div>
      <div className="results-actions">
        <div className={cx('card-split-btn', selectedCount > 0 && 'card-split-btn--primary')} ref={splitRef}>
          <button className="card-split-main" disabled={selectedCount === 0} onClick={() => doAction(primaryAction)}>
            <span className="icon-frame"><Icon name={primaryIcon} size={16} /></span>
            {primaryLabel}
          </button>
          <div className="card-split-divider"></div>
          <button
            className="card-split-trigger" disabled={selectedCount === 0} aria-label="More save options"
            onClick={(e) => { e.preventDefault(); e.stopPropagation(); setMenuOpen(o => !o); }}
          ><Icon name="chevron-down" size={16} /></button>
          {menuOpen ? (
            <div className="btn-split-menu">
              {menuItems.map(([k, icon, label]) => (
                <button className="btn-split-item" key={k} onClick={() => doAction(k)}>
                  <Icon name={icon} size={14} /> {label}
                </button>
              ))}
            </div>
          ) : null}
        </div>
      </div>
    </div>
  );
}

/* ---- work area states ----------------------------------------------------------- */
function ParsingSkeleton() {
  useAppState();
  const st = fpState();
  return (
    <div data-role="parsing">
      <div className="results-bar">
        <div className="results-count">
          <span className="parsing-status">
            Searching <strong>{ENTITY[st.entity].plural}</strong> for "<em>{searchSmartQuery}</em>"…
          </span>
        </div>
      </div>
      <div className="results-card">
        <div className="parsing-skel-table">
          <div className="parsing-skel-row parsing-skel-head"></div>
          <div className="parsing-skel-row"></div>
          <div className="parsing-skel-row"></div>
          <div className="parsing-skel-row"></div>
          <div className="parsing-skel-row"></div>
          <div className="parsing-skel-row"></div>
        </div>
      </div>
    </div>
  );
}

function SearchResults() {
  useAppState();
  const st = fpState();
  const filtered = applyFilters(datasetFor(st.entity), st.filters, st.entity);
  return (
    <div data-role="results" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      <ResultsSaveSplit filtered={filtered} />
      <div className="results-card"><ResultsTable records={filtered} /></div>
    </div>
  );
}

Object.assign(window, {
  EntitySwitch, ResultsTable, SearchResults, ParsingSkeleton, ResultsSaveSplit,
  rowKey, toggleRowSelect, toggleAllRowSelect, detailLinkClick, openDetail,
});
