/* ========================================================================
   AGENTS PAGE — index (cards grid) + agent detail (config columns,
   criteria editor, scheduled plays, results preview / performance).
   Port of js/09-agents.js + js/12-agent-detail.js rendering.
   ======================================================================== */

/* ---- criteria table (shared: agent editor, template editor, instance) ----- */
function CriteriaTable({ agent, readonly }) {
  useAppState();
  if (!(agent.criteria || []).length) return null;
  return (
    <div className="crit-table">
      <div className="crit-thead">
        <div>Criterion</div>
        <div>Kind</div>
        <div className="crit-thead-weight">Weight</div>
        {!readonly ? <div></div> : null}
      </div>
      <div>
        {agent.criteria.map((c) =>
        <div className={cx('crit-row', c.dir === '−' && 'penalty-row')} key={c.id}>
            <div className="crit-text" style={!readonly ? { cursor: 'pointer' } : undefined}
          onClick={!readonly ? () => openCriterionEditor(agent, c) : undefined}>
              <div className="crit-name">{c.name}</div>
              <div className="crit-desc">{c.desc}</div>
            </div>
            <div><span className={cx('crit-kind', c.dir !== '+' && 'penalty')}>{c.dir === '+' ? 'Boost' : 'Penalty'}</span></div>
            {c.dir === '−' ?
          <div className="crit-weight crit-abs" title="Penalties exclude any match">
                <span className="crit-abs-pill"><Icon name="filter-x" size={11} />Excludes match</span>
              </div> :

          <div className="crit-weight" title="Weight">
                {[1, 2, 3, 4, 5].map((n) =>
            <button key={n} className={cx('crit-dot', n <= c.weight && 'filled')} type="button" disabled={readonly || undefined}
            onClick={!readonly ? () => {c.weight = c.weight === n ? Math.max(1, n - 1) : n;notify();} : undefined}></button>
            )}
              </div>
          }
            {!readonly ?
          <button className="crit-remove" type="button" title="Remove"
          onClick={(e) => {
            e.stopPropagation();
            const idx = agent.criteria.findIndex((x) => x.id === c.id);
            if (idx >= 0) agent.criteria.splice(idx, 1);
            notify();
          }}><Icon name="x" size={14} /></button> :
          null}
          </div>
        )}
      </div>
    </div>);

}

/* ---- shared card chrome -------------------------------------------------- */
function AgentCardSection({ icon, title, titleExtra, action, lockChip, locked, lockedIcon = 'filter', lockedMsg = '', cardClass, children, bodyRaw }) {
  return (
    <section className={cx('floating-widget', cardClass)}>
      <div className="fw-toolbar">
        <div className="fw-toolbar-title">
          <Icon name={icon} size={14} />
          {title}{titleExtra || null}
        </div>
        {lockChip || null}{action || null}
      </div>
      {locked ?
      <div className="cfg-body">
          <div className="agent-setup-empty">
            <div className="ase-icon"><Icon name={lockedIcon} size={16} /></div>
            {lockedMsg}
          </div>
        </div> :
      bodyRaw != null ? bodyRaw : <div className="cfg-body" style={{ paddingTop: 6 }}>{children}</div>}
    </section>);

}

function AgentAvatarTile({ seed }) {
  if (!window.AgentAvatars) return null;
  const h = AgentAvatars.hueFor(seed);
  const svg = AgentAvatars.build('M', String(seed), { sw: 1.75 });
  return (
    <div
      className="aix-avatar"
      style={{ background: `oklch(0.96 0.03 ${h})`, color: `oklch(0.52 0.13 ${h})`, borderColor: `oklch(0.90 0.05 ${h})` }}
      dangerouslySetInnerHTML={{ __html: svg }}>
    </div>);

}

function AgentStatusPill({ status }) {
  const map = {
    enabled: { cls: 'on', icon: 'check', label: 'Enabled' },
    disabled: { cls: 'off', icon: 'pause', label: 'Disabled' },
    draft: { cls: 'draft', icon: 'pencil-ruler', label: 'Draft' }
  };
  const s = map[status] || map.enabled;
  return <span className={cx('tpl-pub-pill', s.cls, 'agent-status-pill')}><Icon name={s.icon} size={12} />{s.label}</span>;
}

/* ---- read-only filter chips ------------------------------------------------ */
function AgentFilterChip({ f }) {
  const field = FIELD_BY_ID[f.fieldId];
  if (!field) return null;
  const op = (OPS[field.type] || []).find((o) => o.id === f.op);
  const val = formatValue(field, f.op, f.value);
  const showOp = field.type !== 'multi';
  return (
    <span className="filter-chip filter-chip--readonly" data-field-id={f.fieldId}>
      <span className="fc-part fc-field">{field.label}</span>
      {showOp ? <span className="fc-part fc-op">{op ? op.label : f.op}</span> : null}
      <span className="fc-part fc-val">{val || <em>any</em>}</span>
    </span>);

}
function AgentFiltersSummary({ agent }) {
  if (!agent.filters.length) {
    return <div className="qs-meta" style={{ padding: '8px 2px' }}>No filters yet. Click <strong>Edit filters</strong> to add some.</div>;
  }
  const groups = new Map();
  for (const f of agent.filters) {
    const field = FIELD_BY_ID[f.fieldId];
    if (!field) continue;
    const g = field.group || 'Other';
    if (!groups.has(g)) groups.set(g, []);
    groups.get(g).push(f);
  }
  return (
    <div className="qs-list">
      {Array.from(groups).map(([groupName, filters]) =>
      <div className="qs-row" key={groupName}>
          <span className="qs-key">{groupName}</span>
          <div className="qs-chips">{filters.map((f, i) => <AgentFilterChip f={f} key={i} />)}</div>
        </div>
      )}
    </div>);

}

/* ---- inline filter editor (FilterPanel instance) ----------------------------- */
function startEditingAgentFilters(agent) {
  state.editingAgentFiltersForId = agent.id;
  state.filters = (agent.filters || []).map((spec) => ({
    id: uid(), fieldId: spec.fieldId, op: spec.op, value: deepClone(spec.value)
  }));
  // The panel's own editable buffer.
  const panel = {
    state: {
      entity: agent.entity || 'signals',
      filters: (agent.filters || []).map((spec) => ({ id: uid(), fieldId: spec.fieldId, op: spec.op, value: deepClone(spec.value) })),
      openFieldId: null,
      editorAnchor: null
    },
    opts: { hideField: (f) => f.entity === 'contacts' },
    afterMutation() {
      // Mirror committed specs into state.filters so the live preview
      // (effectiveAgentFilters) reflects in-flight edits.
      state.filters = this.state.filters.filter(isFilterComplete).map((f) => ({
        id: uid(), fieldId: f.fieldId, op: f.op, value: deepClone(f.value)
      }));
    }
  };
  window.activeFilterPanel = panel;
  notify();
}
function saveAgentFiltersEdit() {
  const agent = findAgent(state.editingAgentFiltersForId);
  const panel = window.activeFilterPanel;
  if (agent && panel) {
    agent.filters = panel.state.filters.filter(isFilterComplete).
    map((f) => ({ fieldId: f.fieldId, op: f.op, value: deepClone(f.value) }));
  }
  window.activeFilterPanel = null;
  state.editingAgentFiltersForId = null;
  state.filters = [];
  notify();
}
function cancelAgentFiltersEdit() {
  window.activeFilterPanel = null;
  state.editingAgentFiltersForId = null;
  state.filters = [];
  notify();
}

function AgentFilterEditorCard() {
  useAppState();
  const panel = window.activeFilterPanel;
  if (!panel) return null;
  const committed = panel.state.filters.filter(isFilterComplete);
  return (
    <section className="floating-widget agent-filter-editor">
      <div className="fw-toolbar">
        <div className="fw-toolbar-title">
          <Icon name="filter" size={14} />
          Filters
        </div>
        <div className="afe-actions">
          <button className="btn-toolbar" type="button" onClick={cancelAgentFiltersEdit}>Cancel</button>
          <button className="btn-secondary-cta" type="button" onClick={saveAgentFiltersEdit}>
            <span className="icon-frame"><Icon name="check" size={16} /></span>
            Save filters
          </button>
        </div>
      </div>
      <div className="afe-body">
        {committed.length ?
        <div className="chip-rail" style={{ padding: '8px 12px 0' }}>
            {committed.map((f) => <FilterChip f={f} key={f.id} />)}
          </div> :
        null}
        <div className="afe-field-list-slot">
          <FieldList panel={panel} />
        </div>
      </div>
    </section>);

}

/* ---- criterion editor modal ---------------------------------------------------- */
var critEditorState = null; // { agent, criterion|null }
function openCriterionEditor(agent, criterion) {
  critEditorState = { agent, criterion: criterion || null };
  notify();
}
function CriterionEditorModal() {
  useAppState();
  if (!critEditorState) return null;
  return <CriterionEditorBody key={(critEditorState.criterion || {}).id || 'new'} />;
}
function CriterionEditorBody() {
  const { agent, criterion } = critEditorState;
  const isNew = !criterion;
  const [name, setName] = React.useState(criterion ? criterion.name : '');
  const [desc, setDesc] = React.useState(criterion ? criterion.desc : '');
  const [dir, setDir] = React.useState(criterion ? criterion.dir : '+');
  const [weight, setWeight] = React.useState(criterion ? criterion.weight : 3);
  const close = () => {critEditorState = null;notify();};
  const save = () => {
    const n = name.trim();
    if (!n) return;
    if (isNew) {
      agent.criteria.push({ id: 'crit-' + uid(), name: n, desc: desc.trim(), dir, weight });
    } else {
      criterion.name = n;criterion.desc = desc.trim();criterion.dir = dir;criterion.weight = weight;
    }
    close();
  };
  const del = () => {
    if (isNew) return;
    const idx = agent.criteria.findIndex((x) => x.id === criterion.id);
    if (idx >= 0) agent.criteria.splice(idx, 1);
    close();
  };
  return (
    <div className="modal-overlay" onMouseDown={(e) => {if (e.target === e.currentTarget) close();}}>
      <div className="modal" role="dialog">
        <div className="modal-header">
          <div className="modal-title">{isNew ? 'Add criterion' : 'Edit criterion'}</div>
          <button className="modal-close" aria-label="Close" onClick={close}>×</button>
        </div>
        <div className="modal-body">
          <div className="modal-field">
            <label className="modal-field-label">Name</label>
            <div className="modal-combo-wrap">
              <input className="modal-input" type="text" placeholder="e.g. Past performance match" autoComplete="off"
              value={name} autoFocus onChange={(e) => setName(e.target.value)} />
            </div>
          </div>
          <div className="modal-field">
            <label className="modal-field-label">Criteria</label>
            <textarea className="modal-textarea" placeholder="Describe what this criterion measures and how a signal earns or loses points…"
            value={desc} onChange={(e) => setDesc(e.target.value)}></textarea>
          </div>
          <div className="modal-field">
            <label className="modal-field-label">Kind</label>
            <div className="dv-segmented">
              <button className={cx('dv-seg', dir === '+' && 'active')} type="button" onClick={() => setDir('+')}>Boost</button>
              <button className={cx('dv-seg', dir === '−' && 'active')} type="button" onClick={() => setDir('−')}>Penalty</button>
            </div>
          </div>
          {dir === '+' ?
          <div className="modal-field">
              <label className="modal-field-label">Weight</label>
              <div className="crit-weight">
                {[1, 2, 3, 4, 5].map((n) =>
              <button key={n} className={cx('crit-dot', n <= weight && 'filled')} type="button"
              onClick={() => setWeight(weight === n ? Math.max(1, n - 1) : n)}></button>
              )}
              </div>
            </div> :

          <div className="modal-field">
              <div className="crit-penalty-note">
                <Icon name="filter-x" size={14} />
                <span>Penalties are <strong>absolute filters</strong> — any match is excluded outright, so there's no weight to set.</span>
              </div>
            </div>
          }
        </div>
        <div className="modal-footer">
          {!isNew ? <button className="btn-modal" style={{ marginRight: 'auto' }} onClick={del}>Delete</button> : null}
          <button className="btn-modal" onClick={close}>Cancel</button>
          <button className="btn-modal btn-modal-primary" onClick={save}>Save</button>
        </div>
      </div>
    </div>);

}

/* ---- leave-guard modal ------------------------------------------------------------ */
function AgentGuardModal() {
  useAppState();
  const g = window.agentGuardStateRef;
  if (!g) return null;
  const isNew = g.mode === 'new';
  const canSave = agentSetupState(g.agent).canSave;
  const proceedNow = () => {
    const fn = g.proceed;
    closeAgentSaveGuard();
    if (fn) fn();
  };
  return (
    <div className="modal-overlay" onMouseDown={(e) => {if (e.target === e.currentTarget) closeAgentSaveGuard();}}>
      <div className="modal modal-sm" role="dialog">
        <div className="modal-header">
          <div className="modal-title">{isNew ? 'Save this agent?' : 'Save changes?'}</div>
          <button className="modal-close" aria-label="Close" onClick={closeAgentSaveGuard}>×</button>
        </div>
        <div className="fb-val-sub" style={{ padding: '4px 22px 18px' }}>
          {isNew ?
          'You started a new agent but haven\u2019t saved it yet. Save it before leaving?' :
          'You have unsaved changes to this agent.'}
        </div>
        <div className="modal-footer">
          <button className="btn-modal" onClick={() => {
            if (isNew) discardNewAgent(g.agent);else
            revertAgentToBaseline(g.agent);
            proceedNow();
          }}>Don't save</button>
          <button className="btn-modal btn-modal-primary" disabled={isNew && !canSave} onClick={() => {
            if (isNew) {
              if (!agentSetupState(g.agent).canSave) return;
              commitSaveAgent(g.agent);
              showToast({ message: `Agent "${g.agent.name}" saved`, icon: 'check' });
            } else {
              captureAgentBaseline(g.agent);
              showToast({ message: `Changes to "${g.agent.name}" saved`, icon: 'check' });
            }
            proceedNow();
          }}>{isNew ? 'Save Agent' : 'Save'}</button>
        </div>
      </div>
    </div>);

}

/* ---- results preview ----------------------------------------------------------------- */
function AgentResultsList({ agent }) {
  useAppState();
  const setup = agentSetupState(agent);
  if (!setup.preview) {
    const needFilters = !(agent.filters || []).length;
    return (
      <div className="agent-setup-empty">
        <div className="ase-icon"><Icon name={needFilters ? 'filter' : 'target'} size={16} /></div>
        <strong>{needFilters ? 'Add filters to begin' : 'Add scoring criteria'}</strong>
        {needFilters ?
        'Define what this agent searches for, then add scoring criteria to preview matches here.' :
        'Add at least one scoring criterion and matches will rank here in real time.'}
      </div>);

  }
  const matches = getAgentMatches(agent).filter((s) => !agentExcludedByPenalty(agent, s));
  const ranked = matches.
  map((s) => ({ s, score: scoreForAgentSignal(agent, s) })).
  sort((a, b) => b.score - a.score).
  slice(0, 5);
  if (!ranked.length) {
    return (
      <div style={{ padding: '32px 18px', textAlign: 'center', color: 'var(--muted-foreground)', fontSize: 13 }}>
        <Icon name="search-x" size={22} style={{ opacity: 0.5, marginBottom: 6 }} />
        <div>No signals match these filters.</div>
      </div>);

  }
  return (
    <React.Fragment>
      {ranked.map(({ s, score }) => {
        const reasons = reasonsForAgentSignal(agent, s);
        const tier = tierForAgentScore(score);
        const sigClass = signalTypeClass(s.sigType);
        const dateLabel = formatSignalDate(s.date) || (s.daysAgo != null ? `${s.daysAgo}d ago` : '');
        const acct = s.account || {};
        return (
          <article className="agent-res-card" key={(acct.accountId || '') + '::' + (s.name || s.sigType || '')}>
            <div className="agent-res-head">
              <div className="agent-res-head-text">
                <button className="agent-res-account" type="button">{acct.name || 'Unknown account'}</button>
                <button className="agent-res-title" type="button">{s.name || s.sigType || ''}</button>
              </div>
              <div className="agent-res-head-right">
                <span className={cx('score-pill', tier)}>
                  <Icon name="target" size={10} />
                  <span className="score-n">{score}</span> score
                </span>
                <div className="agent-res-date">{dateLabel}</div>
              </div>
            </div>
            {s.text ?
            <p className="agent-res-synopsis">
                {s.sigType ? <span className={`dv-signal-tag dv-tag--${sigClass} agent-res-sigtype-inline`}>{s.sigType}</span> : null}
                {s.text}
              </p> :
            null}
            <div className="agent-res-meta">
              {acct.type ? <span>{acct.type}</span> : null}
              {acct.type && acct.state ? <span className="dot"></span> : null}
              {acct.state ? <span>{acct.state}</span> : null}
              {s.competitor ? <React.Fragment><span className="dot"></span><span>Incumbent: <span className="value">{s.competitor}</span></span></React.Fragment> : null}
            </div>
            <div className="agent-res-reasons">
              <span className="agent-res-reasons-label">Why</span>
              {reasons.map((rs, i) =>
              <span className={cx('reason', rs.dir)} key={i}>
                  <Icon name={rs.dir === 'up' ? 'trending-up' : 'trending-down'} size={10} />
                  {rs.label}
                </span>
              )}
            </div>
          </article>);

      })}
    </React.Fragment>);

}

function AgentPreviewCard({ agent }) {
  return (
    <AgentCardSection icon="zap" title="Results Preview" bodyRaw={
    <React.Fragment>
        <div className="fw-items" style={{ padding: 0 }}>
          <div className="agent-res-list"><AgentResultsList agent={agent} /></div>
        </div>
        <div className="agent-res-foot-row">
          <div className="agent-res-foot-meta">Top matches shown</div>
          <button className="btn-toolbar" type="button" onClick={() => switchPage('opportunities')}>
            <Icon name="arrow-right" className="toolbar-icon" size={16} />
            View all in Opportunities
          </button>
        </div>
      </React.Fragment>
    } />);

}

function AgentPerformanceCard({ agent }) {
  const p = agentPerformanceData(agent);
  const up = p.trend >= 0;
  const seg = [
  { label: 'unread', n: p.unread, cls: 'unread' },
  { label: 'reviewed', n: p.reviewed, cls: 'reviewed' },
  { label: 'saved', n: p.saved, cls: 'saved' },
  { label: 'dismissed', n: p.dismissed, cls: 'dismissed' }];

  return (
    <AgentCardSection
      icon="bar-chart-3" title="Performance" cardClass="perf-card"
      action={
      <div className="perf-head-right">
          <span className={cx('perf-trend', up ? 'up' : 'down')}><Icon name={up ? 'trending-up' : 'trending-down'} size={13} />{up ? '+' : ''}{p.trend}%</span>
          <span className="perf-window">· last 30 days</span>
        </div>
      }
      bodyRaw={
      <div className="cfg-body" style={{ paddingTop: 6 }}>
          <div className="perf-stats">
            <div className="perf-stat"><div className="perf-stat-value">{p.matches}</div><div className="perf-stat-label">Matches</div></div>
            <div className="perf-stat"><div className="perf-stat-value">{fmtMoneyK(p.pipelineK)}</div><div className="perf-stat-label">Pipeline</div></div>
            <div className="perf-stat"><div className="perf-stat-value">{p.reviewedPct}%</div><div className="perf-stat-label">Reviewed</div></div>
          </div>
          <div className="perf-bar-label">Disposition <span className="perf-bar-total">{p.matches} matches</span></div>
          <div className="perf-bar">
            {seg.filter((s) => s.n > 0).map((s) => <span className={`perf-seg perf-seg--${s.cls}`} style={{ flex: s.n }} key={s.cls}></span>)}
          </div>
          <div className="perf-legend">
            {seg.map((s) => <span className="perf-legend-item" key={s.cls}><span className={`perf-dot perf-dot--${s.cls}`}></span>{s.n} {s.label}</span>)}
          </div>
        </div>
      } />);


}

/* ---- scheduled plays card --------------------------------------------------------------- */
function AgentPlaysCard({ agent, setup }) {
  useAppState();
  const d = agent.delivery || {};
  const rows = [
  ['inbox', 'Send to Opportunities Inbox', d.inbox && d.inbox.detail || 'New matches land in your inbox'],
  ['email', 'Generate Email', 'Draft a personalized outreach email for each match'],
  ['talking', 'Generate Talking Points', 'Prep a call battlecard of talking points per match'],
  ['slack', 'Post to Slack', null],
  ['webhook', 'Webhook', 'POST to a URL · for CRM sync']];

  const sched = agent.schedule || {};
  const dowAll = ['Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa'];
  return (
    <AgentCardSection
      icon="calendar-clock" title="Scheduled Plays"
      locked={!setup.schedule}
      lockedIcon="target"
      lockedMsg="Configure your Scoring Criteria first"
      action={setup.schedule && !setup.isDraft && !agentReadyToEnable(agent) ?
      <span className="cfg-lock-hint cfg-lock-hint--warn"><Icon name="alert-triangle" size={13} /> At least one play required to enable</span> :
      null}
      bodyRaw={
      <div className="agent-card-body">
          <div className="cfg-body">
            <div className="agent-sched-row" style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '4px 2px 10px', flexWrap: 'wrap' }}>
              <div className="dv-segmented" role="tablist" aria-label="Schedule">
                {['hourly', 'daily', 'weekly'].map((m) =>
              <button key={m} className={cx('dv-seg', sched.mode === m && 'active')} type="button"
              onClick={() => {agent.schedule.mode = m;notify();}}>
                    {m[0].toUpperCase() + m.slice(1)}
                  </button>
              )}
              </div>
              {sched.mode === 'weekly' ?
            <div className="agent-dow-chips" style={{ display: 'flex', gap: 4 }}>
                  {dowAll.map((label, idx) =>
              <button key={idx} type="button"
              className={cx('inbox-view-chip', (sched.days || []).includes(idx) && 'active')}
              onClick={() => {
                const i = agent.schedule.days.indexOf(idx);
                if (i >= 0) agent.schedule.days.splice(i, 1);else
                {agent.schedule.days.push(idx);agent.schedule.days.sort((a, b) => a - b);}
                notify();
              }}>{label}</button>
              )}
                </div> :
            null}
              <span className="qs-meta" style={{ marginLeft: 'auto' }}>{formatSchedule(sched)}</span>
            </div>
            <div className="delivery-list">
              {rows.map(([kind, name, detail]) => {
              const on = !!(d[kind] && d[kind].on);
              return (
                <div key={kind} className={cx('fl-item', on && 'active')}
                onClick={(e) => {
                  if (e.target.tagName === 'INPUT') return;
                  agent.delivery[kind].on = !agent.delivery[kind].on;
                  notify();
                }}>
                    <span className="fl-glyph"><Icon name={deliveryIcon(kind)} size={13} /></span>
                    <span className="fl-name">
                      <div className="fl-name-primary">{name}</div>
                      <div className="fl-item-detail">
                        {kind === 'slack' ?
                      <React.Fragment>Post to <input type="text" defaultValue={d.slack && d.slack.channel || ''} onClick={(e) => e.stopPropagation()} onChange={(e) => {agent.delivery.slack.channel = e.target.value;}} /></React.Fragment> :
                      detail}
                      </div>
                    </span>
                    <span className="fl-toggle" role="switch" aria-checked={on ? 'true' : 'false'} aria-label={name}>
                      <span className="fl-toggle-knob"></span>
                    </span>
                  </div>);

            })}
            </div>
          </div>
        </div>
      } />);


}

/* ---- agent detail ---------------------------------------------------------------------- */
function AgentDetail({ agent }) {
  useAppState();
  const setup = agentSetupState(agent);
  const editing = state.editingAgentFiltersForId === agent.id;
  const nameRef = React.useRef(null);

  React.useEffect(() => {
    if (state.agentBaselineId !== agent.id) captureAgentBaseline(agent);
  }, [agent.id]);

  // Consistency guard: saved agent that lost its enable requirements.
  if (!agent.draft && !agent.paused && !agentReadyToEnable(agent)) {
    agent.paused = true;
  }

  const tab = state.agentRightTab && state.agentRightTab[agent.id] || (
  agent._createdHere ? 'preview' : 'performance');

  return (
    <div className="agent-work">
      <div className="detail-head">
        <div className="detail-head-text">
          <AgentStatusPill status={setup.isDraft ? 'draft' : agent.paused ? 'disabled' : 'enabled'} />
          <div className="detail-record-name-row">
            <h1
              ref={nameRef}
              className="detail-record-name" contentEditable spellCheck={false}
              suppressContentEditableWarning
              onBlur={(e) => {
                const next = e.currentTarget.textContent.trim();
                if (!next) {e.currentTarget.textContent = agent.name;return;}
                agent.name = next;
                notify();
              }}
              onKeyDown={(e) => {if (e.key === 'Enter') {e.preventDefault();e.currentTarget.blur();}}}>
              {agent.name}</h1>
          </div>
          <div className="dv-facts-grid">
            <div className="dv-fact">
              <div className="dv-fact-label"><Icon name="history" className="dv-fact-icon" size={14} />Last run</div>
              <div className="dv-fact-value">{agent.meta.lastRun}</div>
            </div>
          </div>
        </div>
        <div className="detail-head-actions">
          {setup.isDraft ?
          <button className="btn-primary-cta" type="button" disabled={!setup.canSave}
          onClick={() => {
            if (!agentSetupState(agent).canSave) return;
            commitSaveAgent(agent);
            showToast({ message: `Agent "${agent.name}" saved`, icon: 'check' });
            notify();
          }}>
              <span className="icon-frame"><Icon name="check" size={16} /></span>
              Save Agent
            </button> :

          <React.Fragment>
              <button className="btn-secondary-cta" type="button"
            disabled={agent.paused && !agentReadyToEnable(agent) || undefined}
            title={agent.paused && !agentReadyToEnable(agent) ? 'Turn on at least one play to enable' : undefined}
            onClick={() => {
              if (agent.paused && !agentReadyToEnable(agent)) return;
              agent.paused = !agent.paused;
              notify();
            }}>
                <span className="icon-frame"><Icon name={agent.paused ? 'power' : 'power-off'} size={16} /></span>
                {agent.paused ? 'Enable' : 'Disable'}
              </button>
              <button className="btn-secondary-cta" type="button" onClick={() => notify()}>
                <span className="icon-frame"><Icon name="play-circle" size={16} /></span>
                Test Run
              </button>
            </React.Fragment>
          }
        </div>
      </div>

      <div className="agent-cols">
        <div className={cx('agent-cfg-col', editing && 'editing')}>
          <div className="agent-cfg-stack">
            {editing ? <AgentFilterEditorCard /> : null}
            <AgentCardSection icon="filter" title="Filters"
            action={!editing ?
            <button className="btn-toolbar" type="button" onClick={() => startEditingAgentFilters(agent)}>
                  <Icon name="pencil" className="toolbar-icon" size={16} />
                  Edit filters
                </button> :
            null}>
              <AgentFiltersSummary agent={agent} />
            </AgentCardSection>
            <AgentCardSection icon="target" title="Scoring criteria"
            locked={!setup.scoring}
            lockedMsg="Configure your filters first"
            action={setup.scoring ?
            <button className="btn-toolbar" type="button" onClick={() => openCriterionEditor(agent, null)}>
                  <Icon name="plus" className="toolbar-icon" size={16} />
                  Add criterion
                </button> :
            null}>
              {(agent.criteria || []).length ?
              <CriteriaTable agent={agent} /> :

              <div className="crit-empty">
                  <p className="crit-empty-lead">Scoring criteria tell this agent what makes a signal valuable to you. Describe the traits of your best opportunities and every match is ranked against them — the strongest matches surface first.</p>
                  <div className="crit-empty-examples">
                    {[
                  ['target', 'Account fit', 'Traits of an ideal buyer — e.g. \u201cCity or county with an aging on-prem footprint.\u201d'],
                  ['zap', 'Buying intent', 'Signals that show they\u2019re in-market — e.g. \u201cCyber grant secured or an active CJIS RFP.\u201d'],
                  ['clock-3', 'Timing', 'Recency or urgency — e.g. \u201cPosted in the last 30 days.\u201d']].
                  map(([icon, title, desc]) =>
                  <div className="crit-eg" key={title}>
                        <span className="crit-eg-glyph"><Icon name={icon} size={14} /></span>
                        <span className="crit-eg-text"><span className="crit-eg-title">{title}</span><span className="crit-eg-desc">{desc}</span></span>
                      </div>
                  )}
                  </div>
                  <p className="crit-empty-foot">Each criterion can boost or penalize a match, weighted by how much it matters.</p>
                </div>
              }
            </AgentCardSection>
            <AgentPlaysCard agent={agent} setup={setup} />
          </div>
        </div>
        <div className="agent-cfg-col agent-preview-col">
          <div className="agent-cfg-stack">
            {setup.isDraft ?
            <AgentPreviewCard agent={agent} /> :

            <React.Fragment>
                <div className="agent-right-segwrap">
                  <div className="dv-segmented" role="tablist" aria-label="Right panel view">
                    <button className={cx('dv-seg', tab === 'preview' && 'active')} type="button" role="tab"
                  onClick={() => {state.agentRightTab = state.agentRightTab || {};state.agentRightTab[agent.id] = 'preview';notify();}}>
                      <Icon name="zap" size={14} />Results Preview
                    </button>
                    <button className={cx('dv-seg', tab === 'performance' && 'active')} type="button" role="tab"
                  onClick={() => {state.agentRightTab = state.agentRightTab || {};state.agentRightTab[agent.id] = 'performance';notify();}}>
                      <Icon name="bar-chart-3" size={14} />Performance
                    </button>
                  </div>
                </div>
                {tab === 'performance' ? <AgentPerformanceCard agent={agent} /> : <AgentPreviewCard agent={agent} />}
              </React.Fragment>
            }
          </div>
        </div>
      </div>
    </div>);

}

/* ---- index ---------------------------------------------------------------------------- */
function agentHits7d(id) {
  let h = 0;
  for (let i = 0; i < 7; i++) h += stableHash((id || '') + ':d' + i) % 6 + 1;
  return h;
}

function InstanceCard({ inst }) {
  const tpl = instanceTemplate(inst);
  if (!tpl) return null;
  return (
    <button className="agent-index-card" type="button"
    onClick={() => {state.instanceId = inst.id;state.agentId = null;notify();}}>
      <div className="aix-identity">
        <AgentAvatarTile seed={tpl.id} />
        <div className="aix-identity-text">
          <h3 className="aix-name">{tpl.name}</h3>
          <span className="aix-status-sub" style={{ display: 'inline-flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
            <AgentStatusPill status={inst.paused ? 'disabled' : 'enabled'} />
            <span className="aix-managed assigned"><Icon name="shield-check" size={12} />Assigned</span>
          </span>
        </div>
      </div>
    </button>);

}

function AgentsIndex() {
  useAppState();
  const admin = isAdmin();
  const me = admin ? null : currentMember();
  const insts = admin ? [] : instancesForUser(me.id);
  const mine = agentsForUser(admin ? agentAdminId() : me.id);
  return (
    <div className="agent-index">
      <header className="agent-index-head">
        <h1 className="agent-index-title">Agents</h1>
        <p className="agent-index-sub">
          {admin ?
          'Automated searches that monitor for new opportunities and deliver matches on a schedule.' :
          'Automated searches that monitor for new opportunities and deliver matches on a schedule. Build your own, or run the ones your team\u2019s admin assigns you.'}
        </p>
      </header>
      {insts.length ?
      <React.Fragment>
          <div className="agent-index-section-label"><Icon name="shield-check" size={12} />Assigned to you</div>
          <div className="agent-index-grid">{insts.map((inst) => <InstanceCard inst={inst} key={inst.id} />)}</div>
        </React.Fragment> :
      null}
      {!admin ? <div className="agent-index-section-label"><Icon name="bot-message-square" size={12} />Your agents</div> : null}
      <div className="agent-index-grid">
        {mine.map((a) =>
        <button className="agent-index-card" type="button" key={a.id}
        onClick={() => {state.agentId = a.id;notify();}}>
            <div className="aix-identity">
              <AgentAvatarTile seed={a.id} />
              <div className="aix-identity-text">
                <h3 className="aix-name">{a.name}</h3>
                <span className="aix-status-sub" style={{ display: 'inline-flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
                  <AgentStatusPill status={a.draft ? 'draft' : a.paused ? 'disabled' : 'enabled'} />
                </span>
              </div>
            </div>
          </button>
        )}
        <button className="agent-index-new" type="button" onClick={createBlankAgent}>
          <span className="aix-new-icon"><Icon name="plus" size={22} /></span>
          <span className="aix-new-text"><strong style={{ fontSize: "15px", fontWeight: "600" }}>Create new agent</strong></span>
        </button>
      </div>
    </div>);

}

/* ---- page + chrome hooks ----------------------------------------------------------------- */
function AgentsPage() {
  useAppState();
  const inst = state.instanceId ? instanceById(state.instanceId) : null;
  const agent = !inst && state.agentId ? findAgent(state.agentId) : null;
  return (
    <React.Fragment>
      <div className="body">
        <div className="content-panel">
          <div id="work-area">
            <div data-role="agent">
              {inst ? <InstanceDetail inst={inst} key={inst.id} /> :
              agent ? <AgentDetail agent={agent} key={agent.id} /> :
              <AgentsIndex />}
            </div>
          </div>
        </div>
      </div>
    </React.Fragment>);

}

function AgentsBreadcrumbs() {
  useAppState();
  const inst = state.instanceId ? instanceById(state.instanceId) : null;
  const agent = !inst && state.agentId ? findAgent(state.agentId) : null;
  const current = inst ? (instanceTemplate(inst) || {}).name : agent ? agent.name : null;
  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} />
      {current ?
      <React.Fragment>
          <button className="breadcrumb-link" type="button"
        onClick={() => guardLeaveAgent(() => {state.agentId = null;state.instanceId = null;notify();})}>Agents</button>
          <Icon name="chevron-right" className="breadcrumb-sep" size={14} />
          <span className="breadcrumb-item current">{current}</span>
        </React.Fragment> :

      <span className="breadcrumb-item current">Agents</span>
      }
    </div>);

}

function NavAgentsChildren({ inFlyout }) {
  useAppState();
  // The agents list renders persistently under the Agents nav item from
  // any page (Mk7 parity: renderAgentsNav populates #nav-agents-list at
  // boot and is never page-gated) — inline when expanded, in the flyout
  // when collapsed.
  const admin = isAdmin();
  const me = admin ? null : currentMember();
  const mine = agentsForUser(admin ? agentAdminId() : me.id);
  const insts = admin ? [] : instancesForUser(me.id);
  if (!mine.length && !insts.length) return null;
  return (
    <div className="nav-children">
      {mine.map((a) =>
      <button
        key={a.id}
        className={cx('nav-child-item', 'nav-child-link', state.page === 'agents' && !state.instanceId && state.agentId === a.id && 'active')}
        type="button"
        onClick={() => guardLeaveAgent(() => {
          state.agentId = a.id;
          state.instanceId = null;
          if (state.page !== 'agents') switchPage('agents');else
          notify();
        })}>
        {a.name}</button>
      )}
      {insts.map((inst) => {
        const tpl = instanceTemplate(inst);
        if (!tpl) return null;
        return (
          <button
            key={inst.id}
            className={cx('nav-child-item', 'nav-child-link', state.page === 'agents' && state.instanceId === inst.id && 'active')}
            type="button"
            onClick={() => guardLeaveAgent(() => {
              state.instanceId = inst.id;
              state.agentId = null;
              if (state.page !== 'agents') switchPage('agents');else
              notify();
            })}>
            {tpl.name}</button>);

      })}
    </div>);

}

window.PAGES.agents = AgentsPage;
window.PAGE_BREADCRUMBS = window.PAGE_BREADCRUMBS || {};
window.PAGE_BREADCRUMBS.agents = AgentsBreadcrumbs;
Object.assign(window, {
  AgentsPage, AgentsIndex, AgentDetail, AgentsBreadcrumbs, NavAgentsChildren,
  openCriterionEditor, startEditingAgentFilters, saveAgentFiltersEdit, cancelAgentFiltersEdit,
  CriterionEditorModal, AgentGuardModal
});