// People — contact resolution + management screen.
// Two sections: Pending clusters (to resolve) + Confirmed people (to edit/merge).

const RELATIONSHIP_OPTIONS = [
  { value: 'family',    label: 'Family',           emoji: '👨‍👩‍👧' },
  { value: 'partner',   label: 'Partner',           emoji: '💑' },
  { value: 'friend',    label: 'Friend',            emoji: '👥' },
  { value: 'childhood', label: 'Childhood friend',  emoji: '🏫' },
  { value: 'colleague', label: 'Colleague',         emoji: '💼' },
  { value: 'army',      label: 'Army / Reserves',   emoji: '🪖' },
  { value: 'acquaintance', label: 'Acquaintance',   emoji: '🤝' },
  { value: 'pet',       label: 'Pet',               emoji: '🐾' },
  { value: 'unknown',   label: 'Unknown',           emoji: '❓' },
];

const REL_MAP = Object.fromEntries(RELATIONSHIP_OPTIONS.map(r => [r.value, r]));

const REL_COLORS = {
  family:      '#FF2D55',
  partner:     '#AF52DE',
  friend:      '#007AFF',
  childhood:   '#5856D6',
  colleague:   '#FF9500',
  army:        '#34C759',
  acquaintance:'#5AC8FA',
  pet:         '#FF9500',
  unknown:     'rgba(60,60,67,0.45)',
};

const USER = (new URLSearchParams(window.location.search)).get('user') || 'shay';
const API  = '/api';

function api(path, opts = {}) {
  return fetch(API + path, {
    headers: { 'Content-Type': 'application/json' },
    ...opts,
  }).then(r => r.json());
}

// ── Relationship picker sheet ─────────────────────────────────────────────────

function RelPicker({ current, onPick, onClose }) {
  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 200,
      display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
      background: 'rgba(0,0,0,0.4)',
    }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{
        background: T.bg2, borderRadius: '18px 18px 0 0',
        padding: '16px 16px 32px',
      }}>
        <div style={{ width: 36, height: 4, background: T.sep, borderRadius: 2, margin: '0 auto 16px' }} />
        <div style={{ fontSize: 13, fontWeight: 600, color: T.label2, textTransform: 'uppercase', letterSpacing: 0.4, paddingBottom: 10 }}>
          Relationship
        </div>
        {RELATIONSHIP_OPTIONS.map(r => (
          <div key={r.value} onClick={() => onPick(r.value)} style={{
            display: 'flex', alignItems: 'center', gap: 12,
            padding: '11px 0',
            borderBottom: `1px solid ${T.sep}`,
            cursor: 'pointer',
          }}>
            <span style={{ fontSize: 20 }}>{r.emoji}</span>
            <span style={{ fontSize: 16, color: T.label }}>{r.label}</span>
            {current === r.value && (
              <span style={{ marginLeft: 'auto', color: T.blue, fontSize: 17 }}>✓</span>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

// ── Confirmed person card ─────────────────────────────────────────────────────

function PersonCard({ person, mergeSelected, onMergeSelect, onUpdate }) {
  const [editing, setEditing]       = React.useState(false);
  const [name, setName]             = React.useState(person.canonical_name);
  const [showRelPicker, setShowRelPicker] = React.useState(false);
  const [notes, setNotes]           = React.useState(person.notes || '');
  const [showNotes, setShowNotes]   = React.useState(!!(person.notes));
  const [busy, setBusy]             = React.useState(false);

  const rel      = REL_MAP[person.relationship_type] || REL_MAP.unknown;
  const relColor = REL_COLORS[person.relationship_type] || REL_COLORS.unknown;
  const isSelected = mergeSelected && mergeSelected.some(p => p.id === person.id);
  const mergeMode  = mergeSelected !== null;

  const saveName = async () => {
    setEditing(false);
    if (name.trim() === person.canonical_name) return;
    setBusy(true);
    await api(`/people/${person.id}`, {
      method: 'PATCH',
      body: JSON.stringify({ user: USER, canonical_name: name.trim() }),
    });
    onUpdate();
    setBusy(false);
  };

  const saveRel = async (val) => {
    setShowRelPicker(false);
    setBusy(true);
    await api(`/people/${person.id}`, {
      method: 'PATCH',
      body: JSON.stringify({ user: USER, relationship_type: val }),
    });
    onUpdate();
    setBusy(false);
  };

  const saveNotes = async () => {
    await api(`/people/${person.id}`, {
      method: 'PATCH',
      body: JSON.stringify({ user: USER, notes: notes }),
    });
  };

  const doSplitAlias = async (alias) => {
    if (!confirm(`Split "${alias}" into a separate person?`)) return;
    setBusy(true);
    await api(`/people/${person.id}/split`, {
      method: 'POST',
      body: JSON.stringify({ user: USER, alias }),
    });
    onUpdate();
    setBusy(false);
  };

  return (
    <>
      {showRelPicker && (
        <RelPicker current={person.relationship_type} onPick={saveRel} onClose={() => setShowRelPicker(false)} />
      )}
      <div
        onClick={mergeMode ? () => onMergeSelect(person) : undefined}
        style={{
          background: T.bg2,
          borderRadius: 14,
          padding: '12px 14px',
          marginBottom: 8,
          opacity: busy ? 0.6 : 1,
          border: isSelected ? `2px solid ${T.blue}` : mergeMode ? `2px solid ${T.sep}` : '2px solid transparent',
          cursor: mergeMode ? 'pointer' : 'default',
          transition: 'border 0.15s',
        }}
      >
        {/* Header row */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
          {mergeMode && (
            <div style={{
              width: 20, height: 20, borderRadius: '50%', flexShrink: 0,
              border: `2px solid ${isSelected ? T.blue : T.sep}`,
              background: isSelected ? T.blue : 'transparent',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              {isSelected && <span style={{ color: '#fff', fontSize: 12 }}>✓</span>}
            </div>
          )}
          {editing ? (
            <input
              autoFocus
              value={name}
              onChange={e => setName(e.target.value)}
              onBlur={saveName}
              onKeyDown={e => e.key === 'Enter' && saveName()}
              style={{
                flex: 1, fontSize: 16, fontWeight: 600, border: 'none', outline: 'none',
                background: 'transparent', color: T.label,
              }}
            />
          ) : (
            <div
              onClick={e => { e.stopPropagation(); if (!mergeMode) setEditing(true); }}
              style={{ flex: 1, fontSize: 16, fontWeight: 600, color: T.label, cursor: mergeMode ? 'default' : 'text' }}
            >
              {person.canonical_name}
            </div>
          )}

          {/* Relationship badge */}
          <div
            onClick={e => { e.stopPropagation(); if (!mergeMode) setShowRelPicker(true); }}
            style={{
              display: 'flex', alignItems: 'center', gap: 4,
              background: relColor + '18', borderRadius: 999,
              padding: '3px 8px',
              cursor: mergeMode ? 'default' : 'pointer',
            }}
          >
            <span style={{ fontSize: 13 }}>{rel.emoji}</span>
            <span style={{ fontSize: 12, fontWeight: 600, color: relColor }}>{rel.label}</span>
          </div>
        </div>

        {/* Aliases */}
        {person.aliases && person.aliases.length > 0 && (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginBottom: 6 }}>
            {person.aliases.slice(0, 12).map(a => (
              <div key={a} style={{
                display: 'flex', alignItems: 'center', gap: 3,
                background: T.bg3, borderRadius: 6,
                padding: '2px 7px', fontSize: 12, color: T.label2,
              }}>
                {a}
                {!mergeMode && (
                  <span
                    onClick={e => { e.stopPropagation(); doSplitAlias(a); }}
                    style={{ cursor: 'pointer', color: T.label3, marginLeft: 2, fontSize: 11 }}
                  >✕</span>
                )}
              </div>
            ))}
            {person.aliases.length > 12 && (
              <div style={{ fontSize: 12, color: T.label3, padding: '2px 4px' }}>
                +{person.aliases.length - 12}
              </div>
            )}
          </div>
        )}

        {/* Notes area */}
        {!mergeMode && showNotes && (
          <textarea
            placeholder="Notes about this person… (saved automatically)"
            value={notes}
            onChange={e => setNotes(e.target.value)}
            onBlur={saveNotes}
            onClick={e => e.stopPropagation()}
            rows={2}
            style={{
              width: '100%', boxSizing: 'border-box',
              background: T.bg3, border: 'none', borderRadius: 8,
              padding: '7px 10px', fontSize: 13, color: T.label,
              resize: 'vertical', outline: 'none',
              marginBottom: 6, fontFamily: 'inherit',
            }}
          />
        )}

        {/* Stats row */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 12, color: T.label3 }}>
          <span>{person.msg_count} msgs</span>
          {person.last_msg && (
            <span>· last {person.last_msg.slice(0, 10)}</span>
          )}
          {!mergeMode && (
            <div style={{ marginLeft: 'auto', display: 'flex', gap: 10, alignItems: 'center' }}>
              <span
                onClick={e => { e.stopPropagation(); setShowNotes(v => !v); }}
                style={{ color: showNotes ? T.blue : T.label3, cursor: 'pointer', fontWeight: 500 }}
              >
                {showNotes ? 'Notes ▴' : (notes ? 'Notes ●' : 'Notes +')}
              </span>
              <span
                onClick={e => { e.stopPropagation(); onMergeSelect(person); }}
                style={{ color: T.blue, cursor: 'pointer', fontWeight: 500 }}
              >
                Select
              </span>
            </div>
          )}
        </div>
      </div>
    </>
  );
}

// ── Pending cluster card ───────────────────────────────────────────────────────

function PendingCard({ cluster, confirmedPeople, onDone }) {
  const [canonical, setCanonical] = React.useState(cluster.canonical);
  const [rel, setRel] = React.useState('unknown');
  const [showRelPicker, setShowRelPicker] = React.useState(false);
  const [showMergeList, setShowMergeList] = React.useState(false);
  const [busy, setBusy] = React.useState(false);
  const [done, setDone] = React.useState(false);
  const [suggesting, setSuggesting] = React.useState(false);

  // Auto-apply Ollama suggestion if present
  React.useEffect(() => {
    if (cluster.suggestion && cluster.suggestion !== 'unknown') {
      setRel(cluster.suggestion);
    }
  }, [cluster.suggestion]);

  if (done) return null;

  const confirm_ = async () => {
    if (!rel || rel === 'unknown') { setShowRelPicker(true); return; }
    setBusy(true);
    await api('/people/pending/confirm', {
      method: 'POST',
      body: JSON.stringify({
        user: USER,
        cand_ids: cluster.cand_ids,
        names: cluster.members,
        canonical_name: canonical.trim() || cluster.canonical,
        relationship_type: rel,
      }),
    });
    setDone(true);
    onDone();
    setBusy(false);
  };

  const skip = async () => {
    setBusy(true);
    await api('/people/pending/skip', {
      method: 'POST',
      body: JSON.stringify({ user: USER, cand_ids: cluster.cand_ids }),
    });
    setDone(true);
    onDone();
    setBusy(false);
  };

  const mergeInto = async (person) => {
    setBusy(true);
    await api('/people/pending/merge-into', {
      method: 'POST',
      body: JSON.stringify({
        user: USER,
        cand_ids: cluster.cand_ids,
        names: cluster.members,
        person_id: person.id,
      }),
    });
    setDone(true);
    onDone();
    setBusy(false);
  };

  const relInfo = REL_MAP[rel] || REL_MAP.unknown;
  const relColor = REL_COLORS[rel] || REL_COLORS.unknown;

  return (
    <>
      {showRelPicker && (
        <RelPicker current={rel} onPick={v => { setRel(v); setShowRelPicker(false); }} onClose={() => setShowRelPicker(false)} />
      )}
      <div style={{
        background: T.bg2, borderRadius: 14, padding: '12px 14px', marginBottom: 8,
        opacity: busy ? 0.6 : 1,
        border: `1px solid ${T.orange}30`,
      }}>
        {/* Editable name */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
          <input
            value={canonical}
            onChange={e => setCanonical(e.target.value)}
            style={{
              flex: 1, fontSize: 16, fontWeight: 600,
              border: 'none', borderBottom: `1px solid ${T.sep}`,
              outline: 'none', background: 'transparent',
              color: T.label, padding: '2px 0',
            }}
          />
          {/* Rel badge */}
          <div
            onClick={() => setShowRelPicker(true)}
            style={{
              display: 'flex', alignItems: 'center', gap: 4,
              background: relColor + '18', borderRadius: 999,
              padding: '3px 8px', cursor: 'pointer',
            }}
          >
            <span style={{ fontSize: 13 }}>{relInfo.emoji}</span>
            <span style={{ fontSize: 12, fontWeight: 600, color: relColor }}>{relInfo.label}</span>
          </div>
        </div>

        {/* Context: chat + message count */}
        {(cluster.conversations?.length > 0 || cluster.msg_count > 0) && (
          <div style={{ fontSize: 12, color: T.label3, marginBottom: 6 }}>
            💬 {cluster.msg_count} msgs
            {cluster.conversations?.[0] ? ` · ${cluster.conversations[0]}` : ''}
          </div>
        )}

        {/* Sample messages */}
        {cluster.samples?.length > 0 && (
          <div style={{ marginBottom: 8 }}>
            {cluster.samples.slice(0, 2).map((s, i) => (
              <div key={i} style={{
                fontSize: 12, color: T.label2, fontStyle: 'italic',
                padding: '3px 0', borderLeft: `2px solid ${T.sep}`, paddingLeft: 8, marginBottom: 3,
              }}>
                "{s.length > 70 ? s.slice(0, 70) + '…' : s}"
              </div>
            ))}
          </div>
        )}

        {/* Members */}
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginBottom: 10 }}>
          {cluster.members.slice(0, 12).map(m => (
            <div key={m} style={{
              background: T.bg3, borderRadius: 6, padding: '2px 7px',
              fontSize: 12, color: T.label2,
            }}>{m}</div>
          ))}
          {cluster.members.length > 12 && (
            <div style={{ fontSize: 12, color: T.label3, padding: '2px 4px' }}>
              +{cluster.members.length - 12} more
            </div>
          )}
        </div>

        {/* Actions */}
        <div style={{ display: 'flex', gap: 6 }}>
          <button onClick={confirm_} disabled={busy} style={btnStyle(T.blue)}>
            ✓ Confirm
          </button>
          <button onClick={skip} disabled={busy} style={btnStyle('rgba(60,60,67,0.25)', T.label3)}>
            Skip
          </button>
          <button onClick={() => setShowMergeList(v => !v)} disabled={busy} style={btnStyle(T.purple)}>
            ↪ Merge
          </button>
        </div>

        {/* Merge into list */}
        {showMergeList && (
          <div style={{
            marginTop: 10, maxHeight: 180, overflowY: 'auto',
            border: `1px solid ${T.sep}`, borderRadius: 10,
          }}>
            {confirmedPeople.length === 0 && (
              <div style={{ padding: 12, fontSize: 13, color: T.label3 }}>No confirmed people yet</div>
            )}
            {confirmedPeople.map(p => (
              <div key={p.id} onClick={() => mergeInto(p)} style={{
                padding: '9px 12px', fontSize: 14, cursor: 'pointer',
                borderBottom: `1px solid ${T.sep}`,
                display: 'flex', alignItems: 'center', gap: 8,
              }}>
                <span>{REL_MAP[p.relationship_type]?.emoji || '❓'}</span>
                <span>{p.canonical_name}</span>
              </div>
            ))}
          </div>
        )}
      </div>
    </>
  );
}

function btnStyle(bg, color = '#fff', _unused) {
  return {
    flex: 1, padding: '8px 0', borderRadius: 10, border: 'none',
    background: bg, color, fontSize: 13, fontWeight: 600,
    cursor: 'pointer',
  };
}

// ── Search bar ────────────────────────────────────────────────────────────────

function SearchBar({ value, onChange }) {
  return (
    <div style={{
      margin: '0 16px 12px',
      background: 'rgba(120,120,128,0.12)',
      borderRadius: 12, padding: '8px 12px',
      display: 'flex', alignItems: 'center', gap: 8,
    }}>
      <span style={{ fontSize: 14, color: T.label3 }}>🔍</span>
      <input
        placeholder="Search people…"
        value={value}
        onChange={e => onChange(e.target.value)}
        style={{
          flex: 1, border: 'none', outline: 'none',
          background: 'transparent', fontSize: 15, color: T.label,
        }}
      />
      {value && (
        <span onClick={() => onChange('')} style={{ cursor: 'pointer', color: T.label3 }}>✕</span>
      )}
    </div>
  );
}

// ── Main screen ───────────────────────────────────────────────────────────────

function PeopleScreen({ go }) {
  const [people, setPeople]         = React.useState([]);
  const [pending, setPending]       = React.useState([]);
  const [singlesCount, setSinglesCount] = React.useState(0);
  const [skippedCount, setSkippedCount] = React.useState(0);
  const [loading, setLoading]       = React.useState(true);
  const [search, setSearch]         = React.useState('');
  const [mergeSelected, setMergeSelected] = React.useState(null); // null = not in merge mode, [] = mode active
  const [tab, setTab]               = React.useState('pending');
  const [skipping, setSkipping]     = React.useState(false);
  const [showSkipped, setShowSkipped] = React.useState(false);
  const [merging, setMerging]       = React.useState(false);

  const load = async (includeSkipped = showSkipped) => {
    setLoading(true);
    const [ppl, pnd] = await Promise.all([
      api(`/people?user=${USER}`),
      api(`/people/pending?user=${USER}&include_skipped=${includeSkipped}`),
    ]);
    setPeople(ppl.people || []);
    setSinglesCount(pnd.singles_count || 0);
    setSkippedCount(pnd.skipped_count || 0);

    const clusters = pnd.clusters || [];
    setPending(clusters);
    setLoading(false);

    // Fire Ollama suggestions for visible clusters without blocking render
    clusters.slice(0, 10).forEach(async (cl, i) => {
      if (cl.samples?.length || cl.conversations?.length) {
        try {
          const res = await api('/people/pending/suggest', {
            method: 'POST',
            body: JSON.stringify({
              user: USER,
              canonical: cl.canonical,
              samples: cl.samples || [],
              conversations: cl.conversations || [],
            }),
          });
          if (res.suggestion && res.suggestion !== 'unknown') {
            setPending(prev => prev.map((c, j) =>
              j === i ? { ...c, suggestion: res.suggestion } : c
            ));
          }
        } catch {}
      }
    });
  };

  const skipSingles = async () => {
    setSkipping(true);
    await api(`/people/pending/skip-singles?user=${USER}`, { method: 'POST' });
    await load();
    setSkipping(false);
  };

  const toggleShowSkipped = async () => {
    const next = !showSkipped;
    setShowSkipped(next);
    await load(next);
  };

  React.useEffect(() => { load(); }, []);

  // Multi-merge: mergeSelected is null (not in mode) or an array of selected people
  const handleMergeSelect = (person) => {
    if (mergeSelected === null) {
      setMergeSelected([person]);
      return;
    }
    const already = mergeSelected.some(p => p.id === person.id);
    if (already) {
      const next = mergeSelected.filter(p => p.id !== person.id);
      setMergeSelected(next.length === 0 ? [] : next);
    } else {
      setMergeSelected([...mergeSelected, person]);
    }
  };

  const executeMerge = async () => {
    if (!mergeSelected || mergeSelected.length < 2) return;
    const keep = mergeSelected[0];
    const discards = mergeSelected.slice(1);
    const names = discards.map(p => p.canonical_name).join(', ');
    if (!confirm(`Merge ${discards.length} person(s) into "${keep.canonical_name}"?\n\n${names} will be absorbed — their aliases and messages will be kept under "${keep.canonical_name}".`)) return;
    setMerging(true);
    for (const discard of discards) {
      await api('/people/merge', {
        method: 'POST',
        body: JSON.stringify({ user: USER, keep_id: keep.id, discard_id: discard.id }),
      });
    }
    setMergeSelected(null);
    setMerging(false);
    load();
  };

  const filtered = search.trim()
    ? people.filter(p =>
        p.canonical_name.toLowerCase().includes(search.toLowerCase()) ||
        (p.aliases || []).some(a => a.toLowerCase().includes(search.toLowerCase()))
      )
    : people;

  const relGroups = {};
  for (const p of filtered) {
    const r = p.relationship_type || 'unknown';
    if (!relGroups[r]) relGroups[r] = [];
    relGroups[r].push(p);
  }

  const relOrder = RELATIONSHIP_OPTIONS.map(r => r.value);

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: T.bg }}>
      {/* Header */}
      <div style={{
        padding: '56px 20px 12px',
        background: T.bg,
        position: 'sticky', top: 0, zIndex: 10,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
          <div style={{ fontSize: 28, fontWeight: 700, color: T.label }}>People</div>
          <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
            {mergeSelected !== null && (
              <>
                <div style={{
                  background: T.blue + '15', color: T.blue,
                  fontSize: 12, fontWeight: 600, padding: '4px 10px', borderRadius: 999,
                }}>
                  {mergeSelected.length === 0 ? 'Tap to select' : `${mergeSelected.length} selected`}
                </div>
                {mergeSelected.length >= 2 && (
                  <button
                    onClick={executeMerge}
                    disabled={merging}
                    style={{
                      background: T.blue, color: '#fff', border: 'none',
                      borderRadius: 8, padding: '5px 12px',
                      fontSize: 12, fontWeight: 600, cursor: 'pointer',
                    }}
                  >
                    {merging ? 'Merging…' : `Merge ${mergeSelected.length}`}
                  </button>
                )}
                <span
                  onClick={() => setMergeSelected(null)}
                  style={{ cursor: 'pointer', color: T.label3, fontSize: 18, lineHeight: 1 }}
                >✕</span>
              </>
            )}
          </div>
        </div>

        {/* Tabs */}
        <div style={{ display: 'flex', gap: 0, background: 'rgba(120,120,128,0.12)', borderRadius: 10, padding: 2 }}>
          {[
            { key: 'pending', label: `Pending${pending.length ? ` (${pending.length})` : ''}` },
            { key: 'confirmed', label: `Confirmed (${people.length})` },
          ].map(t => (
            <div key={t.key} onClick={() => setTab(t.key)} style={{
              flex: 1, textAlign: 'center', padding: '7px 0',
              borderRadius: 8, fontSize: 13, fontWeight: 600,
              background: tab === t.key ? T.bg2 : 'transparent',
              color: tab === t.key ? T.label : T.label2,
              cursor: 'pointer',
              boxShadow: tab === t.key ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
              transition: 'all 0.15s',
            }}>
              {t.label}
            </div>
          ))}
        </div>
      </div>

      {/* Body */}
      <div style={{ flex: 1, overflowY: 'auto', padding: '0 16px 32px' }}>
        {loading ? (
          <div style={{ padding: 40, textAlign: 'center', color: T.label3 }}>Loading…</div>
        ) : tab === 'pending' ? (
          <>
            {singlesCount > 0 && (
              <div style={{
                margin: '0 0 10px', padding: '10px 14px', borderRadius: 12,
                background: T.orange + '18',
                display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              }}>
                <div style={{ fontSize: 13, color: T.label2 }}>
                  {singlesCount} one-time contacts (noise)
                </div>
                <button
                  onClick={skipSingles}
                  disabled={skipping}
                  style={{
                    background: T.orange, color: '#fff', border: 'none',
                    borderRadius: 8, padding: '5px 12px',
                    fontSize: 12, fontWeight: 600, cursor: 'pointer',
                  }}
                >
                  {skipping ? 'Skipping…' : 'Skip all'}
                </button>
              </div>
            )}
            {skippedCount > 0 && (
              <div style={{
                margin: '0 0 10px', padding: '10px 14px', borderRadius: 12,
                background: T.sep,
                display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              }}>
                <div style={{ fontSize: 13, color: T.label2 }}>
                  {skippedCount} skipped with 2+ messages
                </div>
                <button
                  onClick={toggleShowSkipped}
                  style={{
                    background: showSkipped ? T.label3 : T.blue, color: '#fff', border: 'none',
                    borderRadius: 8, padding: '5px 12px',
                    fontSize: 12, fontWeight: 600, cursor: 'pointer',
                  }}
                >
                  {showSkipped ? 'Hide' : 'Review'}
                </button>
              </div>
            )}
            {pending.length === 0 ? (
              <div style={{ padding: 40, textAlign: 'center', color: T.label3 }}>
                {showSkipped ? 'No skipped contacts with 2+ messages' : 'All new contacts resolved ✓'}
              </div>
            ) : (
              pending.map((cl, i) => (
                <PendingCard
                  key={`${cl.canonical}-${i}`}
                  cluster={cl}
                  confirmedPeople={people}
                  onDone={load}
                />
              ))
            )}
          </>
        ) : (
          <>
            <SearchBar value={search} onChange={setSearch} />
            {mergeSelected === null && (
              <button
                onClick={() => setMergeSelected([])}
                style={{
                  width: '100%', marginBottom: 10, padding: '9px 0',
                  background: T.bg2, border: `1px solid ${T.sep}`,
                  borderRadius: 10, fontSize: 13, fontWeight: 600,
                  color: T.blue, cursor: 'pointer',
                }}
              >
                Select people to merge
              </button>
            )}
            {mergeSelected !== null && mergeSelected.length > 0 && (
              <div style={{
                margin: '0 0 10px', padding: '10px 14px', borderRadius: 12,
                background: T.blue + '15', color: T.blue, fontSize: 13,
              }}>
                <strong>{mergeSelected[0].canonical_name}</strong> will keep all aliases.
                {mergeSelected.length > 1 && ` Tap "Merge ${mergeSelected.length}" to absorb the rest.`}
              </div>
            )}
            {filtered.length === 0 && (
              <div style={{ padding: 40, textAlign: 'center', color: T.label3 }}>No people yet</div>
            )}
            {relOrder.map(relKey => {
              const group = relGroups[relKey];
              if (!group || group.length === 0) return null;
              const relInfo = REL_MAP[relKey];
              return (
                <div key={relKey} style={{ marginBottom: 4 }}>
                  <div style={{
                    fontSize: 12, fontWeight: 600, color: T.label2,
                    textTransform: 'uppercase', letterSpacing: 0.5,
                    padding: '10px 2px 6px',
                  }}>
                    {relInfo.emoji} {relInfo.label} ({group.length})
                  </div>
                  {group.map(p => (
                    <PersonCard
                      key={p.id}
                      person={p}
                      mergeSelected={mergeSelected}
                      onMergeSelect={handleMergeSelect}
                      onUpdate={load}
                    />
                  ))}
                </div>
              );
            })}
          </>
        )}
      </div>
    </div>
  );
}
