/* ========================================================================
   SEARCH PAGE — composition: filter widget + content panel (empty hero /
   parsing skeleton / results), editor popover, save modal. Also registers
   the header save-split + create-agent hooks and the sidebar recent-
   searches nav. Port of render()'s search branch (06-render.js).
   ======================================================================== */

/* Mutual-exclusion cleanup + entity defaults — runs at the top of every
   Search render, mirroring Mk7's render(). Render-time mutation is safe:
   it converges immediately and later reads in the same pass agree. */
let _prevSignalActive = false;
let _prevContactActive = false;
function normalizeSearchState() {
  const signalActive = hasSignalFilter();
  const contactActive = hasContactFilter();
  const dropContact = signalActive || state.entity === 'signals';
  const dropSignal = contactActive || state.entity === 'contacts';
  if (dropContact || dropSignal) {
    const before = state.filters.length;
    state.filters = state.filters.filter(f => {
      const ent = FIELD_BY_ID[f.fieldId]?.entity;
      if (dropContact && ent === 'contacts') return false;
      if (dropSignal && ent === 'signals') return false;
      return true;
    });
    if (state.filters.length !== before && state.openFieldId) {
      const stillOpen = state.filters.find(f => f.fieldId === state.openFieldId);
      if (!stillOpen) { state.openFieldId = null; state.editorAnchor = null; }
    }
  }
  if (signalActive && !_prevSignalActive) state.entity = 'signals';
  else if (signalActive && state.entity === 'contacts') state.entity = 'signals';
  else if (contactActive && !_prevContactActive) state.entity = 'contacts';
  else if (contactActive && state.entity === 'signals') state.entity = 'contacts';
  _prevSignalActive = signalActive;
  _prevContactActive = contactActive;
}

/* ---- module-level search input value (survives page hops) ---------------- */
let _searchValueBox = '';

function SearchPage() {
  useAppState();
  const [searchValue, _setSearchValue] = React.useState(_searchValueBox);
  const setSearchValue = (v) => { _searchValueBox = v; _setSearchValue(v); };

  // Detail mode — owned by the detail module once it's ported.
  if (state.detailRecord && window.DetailPage) {
    return <window.DetailPage />;
  }

  normalizeSearchState();

  const committed = state.filters.filter(isFilterComplete);
  const parsing = searchSmartMode === 'parsing';
  const emptyState = committed.length === 0 && !parsing;
  const title = parsing && committed.length === 0
    ? `Searching ${ENTITY[state.entity].plural}…`
    : `Searching ${ENTITY[state.entity].plural}…`;

  return (
    <React.Fragment>
      <div className="body">
        {emptyState ? <LandingParallelo /> : null}
        <FilterWidget />
        <div className="content-panel">
          {emptyState ? (
            <div data-role="empty">
              <div className="empty-prompt">
                <div className="ep-anim"><pursuit-lens-loop dwell-min="2400" dwell-max="3600"></pursuit-lens-loop></div>
                <div className="ep-title">What are you searching for?</div>
                <div className="ep-search-slot">
                  <SearchBar value={searchValue} setValue={setSearchValue} hero />
                </div>
                <div className="ep-body">You can also choose from the filters on the left.</div>
              </div>
            </div>
          ) : (
            <React.Fragment>
              <div className="page-header">
                <div className="page-title-row">
                  <h1 className="page-title">{title}</h1>
                </div>
                <SearchBar value={searchValue} setValue={setSearchValue} />
                <div className="entity-row">
                  <EntitySwitch />
                </div>
              </div>
              <div id="work-area">
                {parsing && committed.length === 0 ? <ParsingSkeleton /> : <SearchResults />}
              </div>
            </React.Fragment>
          )}
        </div>
      </div>
      <SaveSearchModal />
    </React.Fragment>
  );
}

/* ---- header: Save / Update split button ----------------------------------- */
function HeaderSaveSearchSplit() {
  useAppState();
  const [menuOpen, setMenuOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!menuOpen) return;
    const onDown = (e) => {
      if (ref.current && ref.current.contains(e.target)) return;
      setMenuOpen(false);
    };
    document.addEventListener('click', onDown);
    return () => document.removeEventListener('click', onDown);
  }, [menuOpen]);

  if (state.page !== 'search' || state.detailRecord) return null;

  const active = state.activeSavedSearchId ? findSavedSearch(state.activeSavedSearchId) : null;
  const dirty = isSavedSearchDirty();
  const committedCount = state.filters.filter(isFilterComplete).length;

  let mode = 'single', label = 'Save this Search', disabled = committedCount === 0;
  if (active && dirty) { mode = 'split'; label = 'Update Saved Search'; disabled = false; }
  else if (active) { mode = 'single'; label = 'Update Saved Search'; disabled = true; }

  return (
    <div
      className="btn-split btn-split-secondary" ref={ref}
      data-mode={mode} data-dirty={String(!!(active && dirty))} data-disabled={String(disabled)}
    >
      <button
        className="btn-split-main" type="button" disabled={disabled}
        onClick={() => {
          if (disabled) return;
          if (state.activeSavedSearchId) updateActiveSavedSearch();
          else openSaveSearchDialog();
        }}
      >
        <span className="icon-frame"><Icon name="bookmark" size={16} /></span>
        <span>{label}</span>
      </button>
      <div className="btn-split-divider"></div>
      <button
        className="btn-split-trigger" type="button" aria-label="More save options"
        onClick={(e) => { e.stopPropagation(); setMenuOpen(o => !o); }}
      ><Icon name="chevron-down" size={14} /></button>
      {menuOpen ? (
        <div className="btn-split-menu">
          <button className="btn-split-item" type="button"
            onClick={() => { setMenuOpen(false); openSaveSearchDialog(); }}>
            <Icon name="bookmark-plus" size={14} />
            Save this Search…
          </button>
        </div>
      ) : null}
    </div>
  );
}

/* ---- header: Create Agent (Signals browsing only) -------------------------- */
function HeaderCreateAgentBtn() {
  useAppState();
  if (state.page !== 'search' || state.detailRecord) return null;
  if (state.entity !== 'signals') return null;
  if (!state.filters.some(isFilterComplete)) return null;
  return (
    <button
      className="btn-primary-cta" type="button"
      onClick={() => { if (typeof createAgentFromCurrentSearch === 'function') createAgentFromCurrentSearch(); }}
    >
      <span className="icon-frame"><Icon name="bot-message-square" size={16} /></span>
      Create Agent
    </button>
  );
}

/* ---- sidebar: recent searches under Search --------------------------------- */
function NavRecentSearches() {
  useAppState();
  if (!RECENT_SEARCHES.length) return null;
  return (
    <div className="nav-children">
      {RECENT_SEARCHES.map(q => (
        <button
          key={q} className="nav-child-item nav-child-link" type="button"
          onClick={() => {
            if (state.page !== 'search') switchPage('search');
            setTimeout(() => {
              if (window.__searchBar) window.__searchBar.setQuery(q);
              runSmartParse(q);
            }, 0);
          }}
        >
          <Icon name="search" size={14} />
          {q}
        </button>
      ))}
    </div>
  );
}

window.PAGES.search = SearchPage;
Object.assign(window, { SearchPage, HeaderSaveSearchSplit, HeaderCreateAgentBtn, NavRecentSearches, normalizeSearchState });
