/* ========================================================================
   AGENT MANAGEMENT — role switch ("Viewing as"), Account page, Agent
   Templates (admin authoring), member instance detail, Assign modal,
   shared filter-editor modal. Port of js/10-agent-mgmt.js rendering.
   ======================================================================== */

/* ---- shared filter-editor modal (port of openFilterEditorModal, 11) ----- */
var filterEditorModal = null;  // { title, subtitle, saveLabel, panel, onSave }
function openFilterEditorModal({ title, subtitle, saveLabel, entity, filters, hideField, onSave }) {
  const panel = {
    state: {
      entity: entity || 'accounts',
      filters: (filters || []).map(f => ({ id: uid(), fieldId: f.fieldId, op: f.op, value: deepClone(f.value) })),
      openFieldId: null,
      editorAnchor: null,
    },
    opts: { hideField },
    afterMutation() {},
  };
  window.activeFilterPanel = panel;
  filterEditorModal = { title, subtitle, saveLabel: saveLabel || 'Save', panel, onSave };
  notify();
}
function closeFilterEditorModal() {
  window.activeFilterPanel = null;
  filterEditorModal = null;
  notify();
}
function FilterEditorModal() {
  useAppState();
  const m = filterEditorModal;
  if (!m) return null;
  const committed = m.panel.state.filters.filter(isFilterComplete);
  return (
    <div className="modal-overlay" onMouseDown={(e) => { if (e.target === e.currentTarget) closeFilterEditorModal(); }}>
      <div className="modal" role="dialog" style={{ width: 560, maxWidth: 'calc(100vw - 48px)' }}>
        <div className="modal-header">
          <div className="modal-title">{m.title}</div>
          <button className="modal-close" aria-label="Close" onClick={closeFilterEditorModal}>×</button>
        </div>
        {m.subtitle ? <div className="fb-val-sub" style={{ padding: '0 22px 8px' }}>{m.subtitle}</div> : null}
        <div className="modal-body" style={{ paddingTop: 4 }}>
          {committed.length ? (
            <div className="qs-chips" style={{ gap: 8, paddingBottom: 8 }}>
              {committed.map(f => <FilterChip f={f} key={f.id} />)}
            </div>
          ) : null}
          <div style={{ maxHeight: 320, overflowY: 'auto', margin: '0 -8px' }}>
            <FieldList panel={m.panel} />
          </div>
        </div>
        <div className="modal-footer">
          <button className="btn-modal" onClick={closeFilterEditorModal}>Cancel</button>
          <button className="btn-modal btn-modal-primary" onClick={() => {
            const out = m.panel.state.filters.filter(isFilterComplete)
              .map(f => ({ fieldId: f.fieldId, op: f.op, value: deepClone(f.value) }));
            const cb = m.onSave;
            closeFilterEditorModal();
            if (cb) cb(out);
          }}>{m.saveLabel}</button>
        </div>
      </div>
    </div>
  );
}

/* ---- role switch ("Viewing as") ------------------------------------------ */
function RoleSwitch() {
  useAppState();
  const wrapRef = React.useRef(null);
  const [open, setOpen] = React.useState(false);
  React.useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      if (wrapRef.current && wrapRef.current.contains(e.target)) return;
      setOpen(false);
    };
    document.addEventListener('mousedown', onDown);
    return () => document.removeEventListener('mousedown', onDown);
  }, [open]);
  const id = currentIdentity();
  const opts = [ADMIN_USER, ...TEAM_MEMBERS];
  return (
    <div ref={wrapRef} style={{ position: 'relative' }}>
      <button className="role-switch-btn" type="button" onClick={(e) => { e.stopPropagation(); setOpen(o => !o); }}>
        <span className="role-switch-meta">
          <span className="role-switch-testlabel">For testing…</span>
          <span className="role-switch-name">{id.name}</span>
          <span className="role-switch-role">{id.title}</span>
        </span>
        <Icon name="chevrons-up-down" className="role-switch-chev" size={15} />
      </button>
      {open ? (
        <div className="role-switch-pop">
          <div className="role-switch-pop-head">View product as</div>
          {opts.map(o => {
            const admin = o.id === ADMIN_USER.id;
            const active = admin ? isAdmin() : (!isAdmin() && state.viewAsUserId === o.id);
            return (
              <button key={o.id} className={cx('role-opt', active && 'active')} type="button"
                onClick={() => { setOpen(false); setIdentity(o.id); }}>
                <span className={cx('role-opt-avatar', admin && 'admin')}>{o.initials}</span>
                <span className="role-opt-meta">
                  <span className="role-opt-name">{o.name}</span>
                  <span className="role-opt-role">{o.title}{admin ? '' : ' · ' + o.patch}</span>
                </span>
                {active ? <Icon name="check" className="role-opt-check" size={15} /> : null}
              </button>
            );
          })}
        </div>
      ) : null}
    </div>
  );
}

/* ---- assign modal ----------------------------------------------------------- */
var assignModalTpl = null;
function openAssignModal(tpl) { assignModalTpl = tpl; notify(); }
function AssignModal() {
  useAppState();
  if (!assignModalTpl) return null;
  return <AssignModalBody key={assignModalTpl.id} tpl={assignModalTpl} />;
}
function AssignModalBody({ tpl }) {
  const [picks, setPicks] = React.useState(() => new Set());
  const [q, setQ] = React.useState('');
  const [hi, setHi] = React.useState(0);
  const inputRef = React.useRef(null);
  React.useEffect(() => { setTimeout(() => inputRef.current && inputRef.current.focus(), 30); }, []);
  const close = () => { assignModalTpl = null; notify(); };
  const locked = new Map(instancesForTemplate(tpl.id).map(i => [i.userId, i]));
  const ql = q.toLowerCase().trim();
  const cands = TEAM_MEMBERS.filter(m => {
    if (locked.has(m.id) || picks.has(m.id)) return false;
    if (!ql) return true;
    return (m.name + ' ' + m.title + ' ' + m.patch).toLowerCase().includes(ql);
  });
  const hiIdx = Math.min(hi, Math.max(0, cands.length - 1));
  const pick = (uid2) => {
    setPicks(prev => new Set([...prev, uid2]));
    setQ('');
    setHi(0);
    if (inputRef.current) inputRef.current.focus();
  };
  const commit = () => {
    const users = [...picks];
    if (!users.length) return;
    users.forEach(uid2 => {
      INSTANCES.push({ id: 'inst-' + Math.random().toString(36).slice(2, 7), templateId: tpl.id, userId: uid2, origin: 'assigned', openFilters: [], paused: false, meta: { since: 'Just now' }, _lastOrder: [] });
    });
    close();
    showToast({ message: `Assigned "${tpl.name}" to ${users.length} ${users.length === 1 ? 'person' : 'people'}`, icon: 'user-plus' });
  };
  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">Assign to people</div>
          <button className="modal-close" aria-label="Close" onClick={close}>×</button>
        </div>
        <div className="fb-val-sub" style={{ padding: '2px 22px 6px' }}>Assigned reps get a ready-to-run instance they can't leave. They just add their territory.</div>
        <div className="modal-body" style={{ paddingTop: 6 }}>
          <div className="asg-combo ve-tag-area">
            <div className="ve-tag-chips">
              {[...locked.entries()].map(([uid2, inst]) => {
                const m = memberById(uid2);
                if (!m) return null;
                return (
                  <span className="ve-tag-chip asg-chip-locked" key={uid2} title={`${m.name} already has this — Assigned`}>
                    <Icon name="lock" size={11} />{m.name}<span className="asg-chip-state">Assigned</span>
                  </span>
                );
              })}
              {[...picks].map(uid2 => {
                const m = memberById(uid2);
                if (!m) return null;
                return (
                  <span className="ve-tag-chip" key={uid2}>{m.name}
                    <button type="button" aria-label={`Remove ${m.name}`}
                      onClick={() => setPicks(prev => { const nx = new Set(prev); nx.delete(uid2); return nx; })}>×</button>
                  </span>
                );
              })}
            </div>
            <div className="ve-combo">
              <input ref={inputRef} type="text" className="ve-input" placeholder="Search people to assign…" autoComplete="off"
                value={q}
                onChange={(e) => { setQ(e.target.value); setHi(0); }}
                onKeyDown={(e) => {
                  if (e.key === 'ArrowDown') { e.preventDefault(); setHi(Math.min(cands.length - 1, hiIdx + 1)); }
                  else if (e.key === 'ArrowUp') { e.preventDefault(); setHi(Math.max(0, hiIdx - 1)); }
                  else if (e.key === 'Enter') { e.preventDefault(); if (cands[hiIdx]) pick(cands[hiIdx].id); }
                  else if (e.key === 'Escape') close();
                  else if (e.key === 'Backspace' && !q && picks.size) {
                    setPicks(prev => { const nx = new Set(prev); nx.delete([...prev].pop()); return nx; });
                  }
                }} />
              <div className="ve-combo-list">
                {cands.length ? cands.map((m, i) => (
                  <button key={m.id} className={cx('ve-combo-item', i === hiIdx && 'active')} type="button"
                    onMouseDown={(e) => { e.preventDefault(); pick(m.id); }}>
                    <span className="asg-opt-text">
                      <span className="asg-opt-name"><HighlightMatch text={m.name} query={q} /></span>
                      <span className="asg-opt-detail">{m.title} · {m.patch}</span>
                    </span>
                  </button>
                )) : (
                  <div className="ve-combo-empty">{ql ? `No people match "${ql}".` : 'Everyone has been added or already has this agent.'}</div>
                )}
              </div>
            </div>
          </div>
        </div>
        <div className="modal-footer">
          <button className="btn-modal" onClick={close}>Cancel</button>
          <button className="btn-modal btn-modal-primary" disabled={!picks.size} onClick={commit}>
            {picks.size ? `Assign to ${picks.size}` : 'Assign'}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ---- account page ------------------------------------------------------------ */
function startEditingAccountTerritory() {
  seedAccountFromIdentity();
  const hide = accountTerritoryHideSet();
  openFilterEditorModal({
    title: 'Set my territory',
    subtitle: 'Define your patch — geographic (state, region) or account-based (profile, account type, size). Only the fields relevant to a territory are shown.',
    saveLabel: 'Save territory',
    entity: 'accounts',
    filters: state.account.territory || [],
    hideField: (f) => f.id === 'account.territory' || hide.has(f.id),
    onSave: (filters) => {
      seedAccountFromIdentity();
      state.account.territory = filters.map(f => ({ id: _fid(), fieldId: f.fieldId, op: f.op, value: deepClone(f.value) }));
      if (typeof setManualTerritory === 'function') setManualTerritory(currentIdentity().id, deepClone(state.account.territory));
      notify();
    },
  });
}

function AccountPage() {
  useAppState();
  seedAccountFromIdentity();
  const acct = state.account;
  const ident = currentIdentity();
  const assignedTerrIds = (typeof territoriesForUser === 'function') ? territoriesForUser(ident.id) : [];
  const territoryAssigned = assignedTerrIds.length > 0;
  const sfOn = (typeof salesforceOn === 'function') && salesforceOn();
  const setField = (k) => (e) => { state.account[k] = e.target.value; notify(); };
  return (
    <div className="body">
      <div className="content-panel">
        <div id="work-area">
          <div data-role="agent">
            <div className="agent-work">
              <div className="detail-head">
                <div className="detail-head-text">
                  <div className="detail-record-name-row">
                    <h1 className="detail-record-name">Account</h1>
                  </div>
                </div>
                <div className="detail-head-actions">
                  <button className="btn-primary-cta" type="button" onClick={() => showToast({ message: 'Account details saved', icon: 'check' })}>
                    <span className="icon-frame"><Icon name="check" size={16} /></span>
                    Save Changes
                  </button>
                </div>
              </div>
              <div className="agent-cols agent-cols--single">
                <div className="agent-cfg-col">
                  <div className="agent-cfg-stack">
                    <section className="floating-widget">
                      <div className="fw-toolbar">
                        <div className="fw-toolbar-title"><Icon name="user-round" size={14} />Your details</div>
                      </div>
                      <div className="cfg-body" style={{ paddingTop: 6 }}>
                        <div className="acct-grid">
                          <label className="acct-field">
                            <span className="acct-label">First name</span>
                            <input className="acct-input" type="text" value={acct.firstName} placeholder="First name" onChange={setField('firstName')} />
                          </label>
                          <label className="acct-field">
                            <span className="acct-label">Last name</span>
                            <input className="acct-input" type="text" value={acct.lastName} placeholder="Last name" onChange={setField('lastName')} />
                          </label>
                          <label className="acct-field">
                            <span className="acct-label">Work email</span>
                            <input className="acct-input" type="email" value={acct.email} placeholder="name@company.com" onChange={setField('email')} />
                          </label>
                          <label className="acct-field">
                            <span className="acct-label">Phone number</span>
                            <input className="acct-input" type="tel" value={acct.phone} placeholder="Phone number" onChange={setField('phone')} />
                          </label>
                        </div>
                        <div className="acct-actions-row">
                          <button className="btn-secondary-cta" type="button" onClick={() => showToast({ message: 'Password reset link sent to your email', icon: 'key-round' })}>
                            <span className="icon-frame"><Icon name="key-round" size={16} /></span>
                            Change password
                          </button>
                        </div>
                      </div>
                    </section>

                    <section className="floating-widget open-filter-card">
                      <div className="fw-toolbar">
                        <div className="fw-toolbar-title"><Icon name="map-pin" size={14} />Your territory</div>
                        {territoryAssigned ? (
                          <span className="gov-badge inherited"><Icon name="lock" size={12} />{sfOn ? 'Synced from Salesforce' : 'Assigned by admin'}</span>
                        ) : (acct.territory && acct.territory.length) ? (
                          <button className="btn-toolbar" type="button" onClick={startEditingAccountTerritory}>
                            <Icon name="pencil" className="toolbar-icon" size={16} />Edit territory
                          </button>
                        ) : null}
                      </div>
                      <div className="cfg-body" style={{ paddingTop: 6 }}>
                        {territoryAssigned ? (
                          <React.Fragment>
                            <div className="qs-meta" style={{ padding: '2px 2px 10px' }}>
                              {sfOn
                                ? 'Your territory is synced from Salesforce account ownership and managed there — it can\u2019t be edited here.'
                                : 'Your territory was assigned by your team\u2019s admin and can\u2019t be edited here.'}
                            </div>
                            <div className="acct-terr-assigned">
                              {assignedTerrIds.map(tid => {
                                const t = (typeof territoryById === 'function') ? territoryById(tid) : null;
                                if (!t) return null;
                                return (
                                  <div className="acct-terr-block" key={tid}>
                                    <span className="uat-chip"><Icon name="map-pin" size={12} />{t.name}</span>
                                    {(t.filters && t.filters.length) ? (
                                      <div className="qs-chips" style={{ gap: 8 }}>
                                        {t.filters.map((f, i) => <AgentFilterChip f={f} key={i} />)}
                                      </div>
                                    ) : null}
                                  </div>
                                );
                              })}
                            </div>
                          </React.Fragment>
                        ) : (
                          <React.Fragment>
                            <div className="qs-meta" style={{ padding: '2px 2px 10px' }}>The accounts and regions you own. Agents and searches can scope to your territory so you only see what's yours.</div>
                            {(acct.territory && acct.territory.length) ? (
                              <div className="qs-chips" style={{ gap: 8 }}>
                                {acct.territory.map((f, i) => <AgentFilterChip f={f} key={i} />)}
                              </div>
                            ) : (
                              <div className="open-filter-empty">
                                <img className="ofe-illustration" src={(window.__resources&&window.__resources.dioramaUndeveloped)||"assets/diorama-development-undeveloped.svg"} alt="" width="160" height="109" />
                                <span><strong>No territory set</strong>Define the accounts and regions you own.</span>
                                <button className="btn-secondary-cta ofe-cta" type="button" onClick={startEditingAccountTerritory}>
                                  <span className="icon-frame"><Icon name="map-pin" size={16} /></span>Set My Territory
                                </button>
                              </div>
                            )}
                          </React.Fragment>
                        )}
                      </div>
                    </section>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
function AccountBreadcrumbs() {
  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">Account</span>
    </div>
  );
}
function HeaderAccountActions() {
  useAppState();
  if (state.page !== 'account') return null;
  return (
    <button className="btn-secondary-cta" type="button" onClick={() => showToast({ message: 'Signing out…', icon: 'log-out' })}>
      <span className="icon-frame"><Icon name="log-out" size={16} /></span>
      Log out
    </button>
  );
}

/* ---- templates: index + editor -------------------------------------------------- */
function TemplateCard({ tpl }) {
  return (
    <button className="agent-index-card" type="button" onClick={() => { state.templateId = tpl.id; 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' }}>
            <span className={cx('tpl-pub-pill', tpl.draft ? 'draft' : 'on')}>
              <Icon name={tpl.draft ? 'pencil-ruler' : 'check'} size={12} />
              {tpl.draft ? 'Draft' : 'Active'}
            </span>
          </span>
        </div>
      </div>
    </button>
  );
}

function createBlankTemplate() {
  const id = 'tpl-' + Math.random().toString(36).slice(2, 7);
  TEMPLATES.push({
    id, name: 'New template', desc: '', entity: 'signals', published: false, draft: true,
    filters: [], criteria: [], threshold: 65,
    schedule: { mode: 'daily', time: '07:00', tz: 'ET', days: [1, 2, 3, 4, 5] },
    delivery: { inbox: { on: true, detail: 'New matches land in the rep\u2019s inbox' }, slack: { on: false, channel: '' }, email: { on: false, addr: '' }, talking: { on: false }, webhook: { on: false } },
    meta: { createdBy: ADMIN_USER.name, createdAt: 'Just now' }, _lastOrder: [],
  });
  state.templateId = id;
  notify();
}

function TemplatesIndex() {
  useAppState();
  return (
    <div className="agent-index">
      <header className="agent-index-head">
        <h1 className="agent-index-title">Agent Templates</h1>
        <p className="agent-index-sub">Master blueprints you manage centrally. Locked filters, immutable scoring and delivery propagate to every instance reps run; reps add only their own territory.</p>
      </header>
      <div className="agent-index-grid">
        {TEMPLATES.map(tpl => <TemplateCard tpl={tpl} key={tpl.id} />)}
        <button className="agent-index-new" type="button" onClick={createBlankTemplate}>
          <span className="aix-new-icon"><Icon name="plus" size={16} /></span>
          <span className="aix-new-text">
            <strong>New template</strong>
            <span>Author a master agent for your team</span>
          </span>
        </button>
      </div>
    </div>
  );
}

/* Inline template-filter editing — same FilterPanel mechanics as the agent
   detail editor, scoped to this template. */
function startEditingTemplateFilters(tpl) {
  state.tplFilterEdit = { scope: 'template', id: tpl.id };
  window.activeFilterPanel = {
    state: {
      entity: tpl.entity || 'signals',
      filters: (tpl.filters || []).map(f => ({ id: uid(), fieldId: f.fieldId, op: f.op, value: deepClone(f.value) })),
      openFieldId: null,
      editorAnchor: null,
    },
    opts: { hideField: (f) => f.entity === 'contacts' },
    afterMutation() {},
  };
  notify();
}
function saveTplFilterEdit() {
  const ed = state.tplFilterEdit;
  const panel = window.activeFilterPanel;
  if (ed && ed.scope === 'template' && panel) {
    const tpl = templateById(ed.id);
    if (tpl) {
      tpl.filters = panel.state.filters.filter(isFilterComplete)
        .map(f => ({ id: _fid(), fieldId: f.fieldId, op: f.op, value: deepClone(f.value) }));
    }
  }
  window.activeFilterPanel = null;
  state.tplFilterEdit = null;
  notify();
}
function cancelTplFilterEdit() {
  window.activeFilterPanel = null;
  state.tplFilterEdit = null;
  notify();
}

function TemplateEditor({ tpl }) {
  useAppState();
  const setup = agentSetupState(tpl);
  const insts = instancesForTemplate(tpl.id);
  const editing = !!(state.tplFilterEdit && state.tplFilterEdit.scope === 'template' && state.tplFilterEdit.id === tpl.id);
  const propagate = () => {
    if (tpl.draft) return;
    showToast({ message: `Master saved — ${propagationNote(tpl).replace(/\.$/, '')}.`, icon: 'git-branch-plus' });
  };
  const panel = editing ? window.activeFilterPanel : null;
  return (
    <div className="agent-work">
      <div className="detail-head">
        <div className="detail-head-text">
          <div className="detail-record-name-row">
            <h1 className="detail-record-name" contentEditable spellCheck={false} suppressContentEditableWarning
              onBlur={(e) => {
                const next = e.currentTarget.textContent.trim();
                if (!next) { e.currentTarget.textContent = tpl.name; return; }
                tpl.name = next;
                notify();
              }}
              onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); e.currentTarget.blur(); } }}
            >{tpl.name}</h1>
          </div>
          <div className="dv-facts-grid">
            <div className="dv-fact">
              <div className="dv-fact-label"><Icon name="users" className="dv-fact-icon" size={14} />Instances</div>
              <div className="dv-fact-value">{insts.length} inherit this master</div>
            </div>
          </div>
        </div>
        <div className="detail-head-actions">
          {setup.isDraft ? (
            <button className="btn-primary-cta" type="button" disabled={!setup.canSave}
              onClick={() => {
                if (!agentSetupState(tpl).canSave) return;
                tpl.draft = false;
                notify();
                showToast({ message: `Template "${tpl.name}" saved`, icon: 'check', actionLabel: 'Assign', onAction: () => openAssignModal(tpl) });
              }}>
              <span className="icon-frame"><Icon name="check" size={16} /></span>
              Save template
            </button>
          ) : (
            <button className="btn-secondary-cta" type="button" onClick={() => openAssignModal(tpl)}>
              <span className="icon-frame"><Icon name="user-plus" size={16} /></span>
              Assign
            </button>
          )}
        </div>
      </div>

      <div className="agent-cols">
        <div className={cx('agent-cfg-col', editing && 'editing')}>
          <div className="agent-cfg-stack">
            {editing && panel ? (
              <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={cancelTplFilterEdit}>Cancel</button>
                    <button className="btn-secondary-cta" type="button" onClick={saveTplFilterEdit}>
                      <span className="icon-frame"><Icon name="check" size={16} /></span>
                      Save filters
                    </button>
                  </div>
                </div>
                <div className="qs-meta" style={{ padding: '0 18px 8px' }}>Reps inherit these filters and cannot change them. But they can add filters related to their territory.</div>
                <div className="afe-body">
                  {panel.state.filters.filter(isFilterComplete).length ? (
                    <div className="chip-rail" style={{ padding: '8px 12px 0' }}>
                      {panel.state.filters.filter(isFilterComplete).map(f => <FilterChip f={f} key={f.id} />)}
                    </div>
                  ) : null}
                  <div className="afe-field-list-slot"><FieldList panel={panel} /></div>
                </div>
              </section>
            ) : null}
            <AgentCardSection icon="filter" title="Filters"
              action={!editing ? (
                <button className="btn-toolbar" type="button" onClick={() => startEditingTemplateFilters(tpl)}>
                  <Icon name="pencil" className="toolbar-icon" size={16} />
                  Edit filters
                </button>
              ) : null}>
              <div className="qs-meta" style={{ padding: '2px 2px 10px' }}>Reps inherit these filters and cannot change them. <strong>But they can add filters related to their territory.</strong></div>
              <AgentFiltersSummary agent={tpl} />
            </AgentCardSection>
            <AgentCardSection icon="target" title="Scoring criteria"
              locked={!setup.scoring}
              lockedMsg="Add at least one filter to define scoring"
              action={setup.scoring ? (
                <button className="btn-toolbar" type="button" onClick={() => openCriterionEditor(tpl, null)}>
                  <Icon name="plus" className="toolbar-icon" size={16} />
                  Add criterion
                </button>
              ) : null}>
              <CriteriaTable agent={tpl} />
              <div className="fl-section">Match threshold</div>
              <div className="thr-row">
                <input type="range" className="thr-slider" min="0" max="100" step="1" value={tpl.threshold}
                  onChange={(e) => { tpl.threshold = parseInt(e.target.value, 10); notify(); }} />
                <span className="thr-val">{tpl.threshold}</span>
              </div>
            </AgentCardSection>
            <AgentPlaysCard agent={tpl} setup={setup} />
          </div>
        </div>
        <div className="agent-cfg-col agent-preview-col">
          <div className="agent-cfg-stack">
            <AgentCardSection icon="users-round" title="Assignees"
              locked={setup.isDraft}
              lockedIcon="user-plus"
              lockedMsg="Save the template to assign it"
              action={!setup.isDraft ? (
                <button className="btn-toolbar" type="button" onClick={() => openAssignModal(tpl)}>
                  <Icon name="user-plus" className="toolbar-icon" size={16} />
                  Assign
                </button>
              ) : null}>
              {insts.length ? (
                <div className="sub-list">
                  {insts.map(inst => {
                    const m = memberById(inst.userId);
                    const terr = (inst.openFilters || []).map(f => formatValue(FIELD_BY_ID[f.fieldId], f.op, f.value)).filter(Boolean).join(' · ');
                    return (
                      <div className="sub-row" key={inst.id}>
                        <span className="sub-meta">
                          <span className="sub-name">{m ? m.name : 'Unknown'}</span>
                          <span className="sub-detail">{m ? m.title : ''} · territory: <span className="terr">{terr || 'not set'}</span></span>
                        </span>
                        <button className="sub-remove" type="button" title="Remove from template"
                          onClick={() => {
                            const idx = INSTANCES.indexOf(inst);
                            if (idx >= 0) INSTANCES.splice(idx, 1);
                            notify();
                            showToast({ message: `Removed ${m ? m.name : 'member'} from "${tpl.name}"`, icon: 'user-minus' });
                          }}><Icon name="x" size={15} /></button>
                      </div>
                    );
                  })}
                </div>
              ) : (
                <div className="sub-empty">No one's on this template yet.<br />Use <strong>Assign</strong> to push it to reps.</div>
              )}
            </AgentCardSection>
            <AgentCardSection icon="zap" title="Master preview"
              titleExtra={<span className="aix-deliveries" style={{ marginLeft: 8 }}>no territory applied</span>}
              bodyRaw={
                <div className="fw-items" style={{ padding: 0 }}>
                  <div className="agent-res-list"><AgentResultsList agent={tpl} /></div>
                </div>
              } />
          </div>
        </div>
      </div>
    </div>
  );
}

function TemplatesPage() {
  useAppState();
  if (!isAdmin()) {
    // Members have no catalog — route back to their agents.
    React.useEffect(() => { switchPage('agents'); }, []);
    return null;
  }
  const tpl = state.templateId ? templateById(state.templateId) : null;
  return (
    <div className="body">
      <div className="content-panel">
        <div id="work-area">
          <div data-role="agent">
            {tpl ? <TemplateEditor tpl={tpl} key={tpl.id} /> : <TemplatesIndex />}
          </div>
        </div>
      </div>
    </div>
  );
}
function TemplatesBreadcrumbs() {
  useAppState();
  const tpl = state.templateId ? templateById(state.templateId) : 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} />
      <span className="breadcrumb-item">Settings</span>
      <Icon name="chevron-right" className="breadcrumb-sep" size={14} />
      {tpl ? (
        <React.Fragment>
          <button className="breadcrumb-link" type="button" onClick={() => { state.templateId = null; notify(); }}>Agent Templates</button>
          <Icon name="chevron-right" className="breadcrumb-sep" size={14} />
          <span className="breadcrumb-item current">{tpl.name}</span>
        </React.Fragment>
      ) : (
        <span className="breadcrumb-item current">Agent Templates</span>
      )}
    </div>
  );
}

/* Template-editor header action: Save & propagate (saved templates only).
   Composes with the worksheets header slot already registered. */
const __WsHeaderTplActions = window.HeaderTplActions || null;
function CombinedHeaderTplActions() {
  useAppState();
  return (
    <React.Fragment>
      {__WsHeaderTplActions ? <__WsHeaderTplActions /> : null}
      {(state.page === 'templates' && state.templateId) ? (() => {
        const tpl = templateById(state.templateId);
        if (!tpl || tpl.draft) return null;
        return (
          <button className="btn-primary-cta" type="button"
            onClick={() => showToast({ message: `Master saved — ${propagationNote(tpl).replace(/\.$/, '')}.`, icon: 'git-branch-plus' })}>
            <span className="icon-frame"><Icon name="git-branch-plus" size={16} /></span>
            Save &amp; propagate
          </button>
        );
      })() : null}
    </React.Fragment>
  );
}

/* ---- member instance detail ------------------------------------------------------ */
function startEditingInstanceFilters(inst) {
  const locked = lockedFieldIds(instanceTemplate(inst) || { filters: [] });
  openFilterEditorModal({
    title: 'Set your territory',
    subtitle: 'Pick the fields that define your patch. The template\u2019s locked fields aren\u2019t shown — you can\u2019t change those.',
    saveLabel: 'Save territory',
    entity: (instanceTemplate(inst) || {}).entity || 'signals',
    filters: inst.openFilters || [],
    hideField: (f) => f.entity === 'contacts' || f.id === 'account.territory' || locked.has(f.id),
    onSave: (filters) => {
      inst.openFilters = filters
        .filter(f => !locked.has(f.fieldId))
        .map(f => ({ id: _fid(), fieldId: f.fieldId, op: f.op, value: deepClone(f.value) }));
      notify();
    },
  });
}

function InstanceDetail({ inst }) {
  useAppState();
  const tpl = instanceTemplate(inst);
  if (!tpl) return null;
  const terr = inst.openFilters || [];
  return (
    <div className="agent-work">
      <div className="detail-head">
        <div className="detail-head-text">
          <div className="detail-status-row">
            <AgentStatusPill status={inst.paused ? 'disabled' : 'enabled'} />
            <span className="aix-managed assigned"><Icon name="shield-check" size={12} />Assigned to you</span>
          </div>
          <div className="detail-record-name-row">
            <h1 className="detail-record-name">{tpl.name}</h1>
          </div>
          <div className="dv-facts-grid">
            <div className="dv-fact">
              <div className="dv-fact-label"><Icon name="calendar-plus" className="dv-fact-icon" size={14} />Since</div>
              <div className="dv-fact-value">{inst.meta.since}</div>
            </div>
          </div>
        </div>
      </div>
      <div className="agent-cols agent-cols--single">
        <div className="agent-cfg-col">
          <div className="agent-cfg-stack">
            <AgentCardSection icon="map-pin" title="Your territory" cardClass="open-filter-card"
              action={
                <button className="btn-toolbar" type="button" onClick={() => startEditingInstanceFilters(inst)}>
                  <Icon name="pencil" className="toolbar-icon" size={16} />
                  {terr.length ? 'Edit territory' : 'Set territory'}
                </button>
              }>
              <div className="qs-meta" style={{ padding: '2px 2px 10px' }}>The one part of this agent that's yours: scope it to the accounts and regions you own.</div>
              {terr.length ? (
                <div className="qs-chips" style={{ gap: 8 }}>
                  {terr.map((f, i) => <AgentFilterChip f={f} key={i} />)}
                </div>
              ) : (
                <div className="qs-meta" style={{ padding: '4px 2px' }}>No territory set yet — this agent currently matches the template's full scope.</div>
              )}
            </AgentCardSection>
            <AgentCardSection icon="filter" title="Filters" cardClass="cfg-locked-card"
              lockChip={<span className="cfg-lock-chip"><Icon name="lock" size={12} />Locked by template</span>}>
              <AgentFiltersSummary agent={tpl} />
            </AgentCardSection>
            <AgentCardSection icon="target" title="Scoring criteria" cardClass="cfg-locked-card"
              lockChip={<span className="cfg-lock-chip"><Icon name="lock" size={12} />Locked by template</span>}>
              {(tpl.criteria && tpl.criteria.length) ? <CriteriaTable agent={tpl} readonly /> : <div className="cfg-empty">No scoring criteria.</div>}
            </AgentCardSection>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---- territory banner (floating prompt for members w/o a territory) ----- */
function TerritoryBannerLayer() {
  useAppState();
  if (isAdmin()) return null;
  const me = currentMember();
  seedAccountFromIdentity();
  const hasPersonal = !!(state.account && state.account.territory && state.account.territory.length);
  const hasAssigned = territoriesForUser(me.id).length > 0;
  const show = instancesForUser(me.id).length > 0 && !hasPersonal && !hasAssigned && !state.territoryBannerDismissed;
  if (!show) return null;
  return (
    <div className="territory-banner" id="territory-banner">
      <span className="tb-icon"><Icon name="map-pin" size={16} /></span>
      <span className="tb-text"><strong>Set your territory</strong> so your assigned agents focus on the accounts &amp; regions you own.</span>
      <button className="tb-cta" type="button" onClick={() => startEditingAccountTerritory()}>
        <Icon name="map-pin" size={15} />Set My Territory
      </button>
      <button className="tb-dismiss" type="button" aria-label="Dismiss"
        onClick={() => { state.territoryBannerDismissed = true; notify(); }}>
        <Icon name="x" size={16} />
      </button>
    </div>
  );
}

window.PAGES.account = AccountPage;
window.PAGES.templates = TemplatesPage;
window.PAGE_BREADCRUMBS = window.PAGE_BREADCRUMBS || {};
window.PAGE_BREADCRUMBS.account = AccountBreadcrumbs;
window.PAGE_BREADCRUMBS.templates = TemplatesBreadcrumbs;
window.HeaderTplActions = CombinedHeaderTplActions;
Object.assign(window, {
  RoleSwitch, AccountPage, TemplatesPage, TemplateEditor, InstanceDetail,
  AssignModal, FilterEditorModal, openFilterEditorModal, closeFilterEditorModal,
  openAssignModal, startEditingAccountTerritory, startEditingInstanceFilters,
  HeaderAccountActions, TerritoryBannerLayer,
});
