/* Task 1 — Notify Key Family Members workflow.
   Tiered, AI-suggests-coordinator-commits, with script support + Tier 3 draft
   + who-was-told tracking. Single-Day Rule: opens at Tier 1 only. */

const { useState: useStateNF, useMemo: useMemoNF } = React;

/* ---- mock contacts (would come from phone import) ---- */
const SEED_CONTACTS = [
  // AI-suggested Tier 1
  { id: 'margaret', name: 'Margaret Chen', label: 'Mom', phone: '(415) 555-0142', tierAI: 1, reason: 'Saved as "Mom" · daily contact', avatar: '#E89B7E' },
  { id: 'jamie',    name: 'Jamie Chen',    label: 'Brother', phone: '(415) 555-0188', tierAI: 1, reason: 'Saved as "Bro" · weekly contact', avatar: '#A893C2' },
  { id: 'karen',    name: 'Karen Lin',     label: 'Aunt', phone: '(510) 555-0133', tierAI: 1, reason: 'Saved as "Aunt Karen" · weekly contact', avatar: '#D4B591' },
  { id: 'patrick',  name: 'Patrick Chen',  label: 'Uncle', phone: '(415) 555-0211', tierAI: 1, reason: 'Saved as "Uncle Patrick" · close family', avatar: '#9CA88C' },

  // AI-suggested Tier 2
  { id: 'david',    name: 'David Chen',    label: 'Cousin', phone: '(206) 555-0177', tierAI: 2, reason: 'Cousin · last contact 6 weeks', avatar: '#B8A4C9' },
  { id: 'mei',      name: 'Mei Chen-Rivera', label: 'Cousin', phone: '(415) 555-0265', tierAI: 2, reason: 'Family thread member', avatar: '#C9B8A4' },
  { id: 'lila',     name: 'Lila Park',     label: 'Family friend', phone: '(415) 555-0312', tierAI: 2, reason: 'Henry\'s 50-year friendship', avatar: '#E8C8B0' },
  { id: 'frank',    name: 'Frank Wu',      label: 'Cousin (HK)', phone: '+852 9XXX 4421', tierAI: 2, reason: 'International family branch', avatar: '#A8C9B8' },
  { id: 'pastor',   name: 'Pastor Tom Reeves', label: 'Faith community', phone: '(415) 555-0455', tierAI: 2, reason: 'Saved as "Pastor"', avatar: '#B5A89B' },

  // AI-suggested Tier 3
  { id: 'bob',      name: 'Bob Halloran',  label: 'Henry\'s coworker', phone: '(415) 555-0599', tierAI: 3, reason: 'Work contact', avatar: '#C0B0A0' },
  { id: 'linda',    name: 'Linda Marchetti', label: 'Neighbor', phone: '(415) 555-0671', tierAI: 3, reason: 'Saved as "Linda next door"', avatar: '#D0BFAF' },
  { id: 'reggie',   name: 'Reggie Park',   label: 'Old friend', phone: '(415) 555-0703', tierAI: 3, reason: 'Last contact 1y+', avatar: '#B0BFCF' },
  { id: 'janelle',  name: 'Janelle Adetokunbo', label: 'Book club', phone: '(415) 555-0822', tierAI: 3, reason: 'Group: "Tuesday Books"', avatar: '#BFAFCF' },
  { id: 'ray',      name: 'Ray Domínguez', label: 'Fishing buddy', phone: '(707) 555-0944', tierAI: 3, reason: 'Group: "Boat trip 2024"', avatar: '#A0B0CF' },
];

/* ---- script variants ---- */
const SCRIPTS = {
  default: {
    label: 'For someone close',
    body: 'Hi {name}, this is Sarah. I\'m calling because I have hard news. Dad died yesterday morning. I\'m so sorry to be the one telling you.',
  },
  voicemail: {
    label: 'For voicemail',
    body: 'Hi {name}, it\'s Sarah. Could you call me back when you can? I have something I need to tell you in person.',
  },
  distant: {
    label: 'For distant relatives',
    body: 'Hi {name}, this is Sarah Chen — Henry\'s daughter. I\'m calling because I have hard news about Dad. He died yesterday. I wanted you to hear it from family rather than find out another way.',
  },
};

const TIER3_DRAFT_DEFAULT = `I'm sharing hard news. Henry Chen — my dad — died on Monday morning. He went peacefully, with Mom and my brother there.

We're holding a small service this Saturday at 2pm at Mountain View Cemetery. Family and close friends are welcome.

Please don't feel any pressure to respond — I just wanted you to hear this from family.`;

/* ---- main ---- */

function NotifyFamilyWorkflow({ task, family, onBack, onMarkDone, nf, updateNf }) {
  const compact = useIsMobile();
  const { step, contacts } = nf;
  const setStep = (step) => updateNf({ step });
  const setContacts = (next) => updateNf((s) => ({ contacts: typeof next === 'function' ? next(s.contacts) : next }));

  const tier1 = contacts.filter((c) => c.tier === 1);
  const tier2 = contacts.filter((c) => c.tier === 2);
  const tier3 = contacts.filter((c) => c.tier === 3);
  const pendingTier1AI = contacts.filter((c) => c.tierAI === 1 && c.tier === null);
  const tier1Called = tier1.filter((c) => c.status === 'called').length;

  const setTier = (id, tier) => setContacts((cs) => cs.map((c) => c.id === id ? { ...c, tier } : c));
  const setStatus = (id, status, by = 'sarah') => setContacts((cs) => cs.map((c) => c.id === id ? { ...c, status, notifiedBy: by } : c));
  const setInvite = (id, inviteStatus) => setContacts((cs) => cs.map((c) => c.id === id ? { ...c, inviteStatus } : c));
  const claimToFamilyMember = (id, memberId) => setContacts((cs) => cs.map((c) => c.id === id ? { ...c, status: 'claimed', notifiedBy: memberId } : c));
  const addToTier = (entry, tier) => setContacts((cs) => [...cs, { ...entry, id: `m_${Date.now()}_${Math.random().toString(36).slice(2,6)}`, manual: true, tierAI: null, status: 'pending', tier, notifiedBy: null, inviteStatus: 'not_invited' }]);

  return (
    <div className="h-full overflow-y-auto" data-screen-label="Notify Family Workflow">
      <NFHeader compact={compact} onBack={onBack} step={step} contacts={contacts} />

      <div className="px-6 pb-10">
        {step === 'intro' && (
          <NFIntro compact={compact} contacts={contacts} setContacts={setContacts} onContinue={() => setStep('tier1')} />
        )}
        {step === 'tier1' && (
          <NFTierAssign
            compact={compact}
            contacts={contacts}
            setContacts={setContacts}
            setTier={setTier}
            onContinue={() => setStep('calls')}
            onShowMore={() => setStep('tier2')}
            revealed={nf.revealed}
            setRevealed={(revealed) => updateNf({ revealed })}
          />
        )}
        {step === 'calls' && (
          <NFCalls
            compact={compact}
            tier1={tier1}
            setStatus={setStatus}
            setInvite={setInvite}
            onAllDone={() => setStep('tier2')}
            onBack={() => setStep('tier1')}
            onJoin={(contactId) => updateNf({ pendingBackfeed: contactId, step: 'backfeed' })}
            activeId={nf.activeId}
            setActiveId={(activeId) => updateNf({ activeId })}
            scriptKey={nf.scriptKey}
            setScriptKey={(scriptKey) => updateNf({ scriptKey })}
          />
        )}
        {step === 'backfeed' && (
          <NFCollabBackfeed
            compact={compact}
            joinerId={nf.pendingBackfeed}
            contacts={contacts}
            setContacts={setContacts}
            onContinue={() => setStep('calls')}
          />
        )}
        {step === 'tier2' && (
          <NFDistribute
            compact={compact}
            tier2={tier2}
            family={family}
            claim={claimToFamilyMember}
            onAddManual={(e) => addToTier(e, 2)}
            onContinue={() => setStep('tier3')}
            onBack={() => setStep('calls')}
          />
        )}
        {step === 'tier3' && (
          <NFGroupMessage
            compact={compact}
            tier3={tier3}
            setStatus={setStatus}
            onAddManual={(e) => addToTier(e, 3)}
            onContinue={() => setStep('summary')}
            onBack={() => setStep('tier2')}
            draft={nf.draft}
            setDraft={(draft) => updateNf({ draft })}
            sent={nf.sent}
            setSent={(sent) => updateNf({ sent })}
          />
        )}
        {step === 'summary' && (
          <NFSummary
            compact={compact}
            contacts={contacts}
            family={family}
            onMarkDone={() => { onMarkDone(); onBack(); }}
            onBack={() => setStep('tier3')}
          />
        )}
      </div>
    </div>
  );
}

/* ---- header ---- */

function NFHeader({ compact, onBack, step, contacts }) {
  const stepInfo = {
    intro:   { n: 0, label: 'A way to do this together' },
    tier1:   { n: 1, label: 'Who hears it from you' },
    calls:   { n: 2, label: 'The hardest calls' },
    tier2:   { n: 3, label: 'Share the load' },
    tier3:   { n: 4, label: 'A wider note' },
    summary: { n: 5, label: 'Where things stand' },
  }[step];
  const totalCommitted = contacts.filter((c) => c.tier !== null).length;
  return (
    <div className="px-6 pt-6 pb-5 border-b border-[#3D2B3C]/10 bg-[#F8F2E7] sticky top-0 z-10">
      <button onClick={onBack} className="flex items-center gap-1.5 text-[12px] text-[#5A4459] hover:text-[#3D2B3C] mb-3">
        <span>←</span> Back to Today
      </button>
      <div className="flex items-start justify-between gap-4">
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <span className="ff-mono text-[10px] text-[#5A4459]">§ 01</span>
            <span className="text-[10px] uppercase tracking-[.18em] text-[#5A4459]">Notifying key family</span>
          </div>
          <h1 className="ff-serif text-[#3D2B3C] leading-[1.1] mt-1.5 text-[22px] lg:text-[28px]" style={{ fontWeight: 400 }}>
            {stepInfo.label}
          </h1>
        </div>
        <div className="ff-mono text-[10px] text-[#5A4459] flex-shrink-0 pt-1">
          step {stepInfo.n}/5
        </div>
      </div>
      <div className="mt-4 flex gap-1">
        {[0,1,2,3,4,5].map((i) => (
          <div key={i} className="h-[3px] flex-1 rounded-full"
            style={{ background: i <= stepInfo.n ? '#3D2B3C' : 'rgba(61,43,60,0.12)' }} />
        ))}
      </div>
    </div>
  );
}

/* ---- step 0: intro / contact import ---- */

function NFIntro({ compact, contacts, setContacts, onContinue }) {
  const [mode, setMode] = useStateNF('choice'); // choice | imported | manual-only
  const [showManualForm, setShowManualForm] = useStateNF(false);

  const importContacts = () => { setMode('imported'); onContinue(); };
  const startManualOnly = () => { setMode('manual-only'); setShowManualForm(true); };

  // contacts the USER added by hand (no AI tier suggestion)
  const manualContacts = contacts.filter((c) => c.manual);
  const importedReady = mode === 'imported';
  const manualOnlyReady = mode === 'manual-only' && manualContacts.length > 0;

  const addManual = (entry) => {
    setContacts((cs) => [...cs, { ...entry, id: `m_${Date.now()}_${Math.random().toString(36).slice(2,6)}`, manual: true, tierAI: null, status: 'pending', tier: null, notifiedBy: null }]);
  };

  return (
    <div className="pt-6">
      <div className="rounded-[22px] bg-gradient-to-b from-[#F4A88E]/15 to-[#B8A4C9]/15 border border-[#3D2B3C]/8 p-5 mb-6">
        <div className="flex items-start gap-4">
          <MascotCard size={compact ? 56 : 64} />
          <div className="flex-1 pt-0.5">
            <p className="ff-serif text-[#3D2B3C] leading-[1.25] text-[19px] lg:text-[22px]" style={{ fontWeight: 400 }}>
              By the seventh call, you'll be flat. Let's not do this alone.
            </p>
            <p className="text-[#5A4459] text-[13px] leading-relaxed mt-3 max-w-[52ch]">
              I'll help you sort the people in your life into who hears it from you, who can hear it from someone in the family, and who will get a longer note in a few days. <span className="ff-serif italic">You always press send.</span>
            </p>
          </div>
        </div>
      </div>

      {mode === 'choice' && (
        <div className="rounded-2xl bg-white border border-[#3D2B3C]/15 p-5">
          <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459] mb-2">Bring in the people</div>
          <h3 className="ff-serif text-[#3D2B3C]" style={{ fontSize: 20, fontWeight: 400 }}>
            Start with your phone, or add a few names by hand.
          </h3>
          <ul className="mt-4 space-y-2 text-[13px] text-[#5A4459]">
            <li className="flex items-start gap-2"><span className="text-[#3D2B3C] mt-0.5">•</span><span>Stays on your account. Other family members don't see your contact list.</span></li>
            <li className="flex items-start gap-2"><span className="text-[#3D2B3C] mt-0.5">•</span><span>I'll suggest who's likely close based on labels and contact frequency.</span></li>
            <li className="flex items-start gap-2"><span className="text-[#3D2B3C] mt-0.5">•</span><span>You commit every assignment. Nothing gets sent automatically.</span></li>
          </ul>
          <div className="mt-5 flex flex-wrap items-center gap-3">
            <Btn onClick={importContacts} variant="coral">Import from phone</Btn>
            <Btn onClick={startManualOnly} variant="ghost" size="sm">Add by hand instead</Btn>
          </div>
        </div>
      )}

      {(importedReady || mode === 'manual-only') && (
        <div className="rounded-2xl bg-white border border-[#3D2B3C]/15 p-5">
          {importedReady && (
            <div className="flex items-start gap-3">
              <span className="w-8 h-8 rounded-full bg-[#9CA88C]/20 flex items-center justify-center text-[#3D2B3C] text-[14px] flex-shrink-0">✓</span>
              <div className="flex-1">
                <div className="ff-serif text-[#3D2B3C]" style={{ fontSize: 18, fontWeight: 450 }}>
                  {contacts.length} contacts ready.
                </div>
                <div className="text-[#5A4459] text-[13px] leading-relaxed mt-1">
                  I've taken a first pass at tiers. The next screen is yours to confirm — change any of mine, every one of them.
                </div>
              </div>
            </div>
          )}

          {mode === 'manual-only' && (
            <div>
              <div className="ff-serif text-[#3D2B3C]" style={{ fontSize: 18, fontWeight: 450 }}>
                {manualContacts.length === 0 ? 'Add the people who come to mind first.' : `${manualContacts.length} added so far.`}
              </div>
              <div className="text-[#5A4459] text-[13px] leading-relaxed mt-1">
                You can always pull in your phone contacts later from the next screen.
              </div>
            </div>
          )}

          {/* persistent "add by hand" — keeps working even after import */}
          <div className="mt-5 border-t border-[#3D2B3C]/10 pt-4">
            <div className="flex items-center justify-between mb-3">
              <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459]">Added by hand</div>
              <button
                onClick={() => setShowManualForm((v) => !v)}
                className="text-[12px] text-[#3D2B3C] hover:text-[#5A4459] flex items-center gap-1">
                {showManualForm ? '— hide form' : '+ Add someone'}
              </button>
            </div>

            {manualContacts.length > 0 && (
              <ul className="space-y-1.5 mb-3">
                {manualContacts.map((c) => (
                  <li key={c.id} className="flex items-center gap-2 text-[12px] text-[#3D2B3C]">
                    <span className="w-5 h-5 rounded-full flex items-center justify-center text-[10px]" style={{ background: c.avatar }}>
                      {c.name.split(' ').map((p) => p[0]).slice(0,2).join('')}
                    </span>
                    <span className="flex-1 truncate">{c.name}</span>
                    <span className="text-[#5A4459] text-[11px]">{c.label}</span>
                    <button onClick={() => setContacts((cs) => cs.filter((x) => x.id !== c.id))} className="text-[#5A4459] hover:text-[#3D2B3C] text-[11px]">remove</button>
                  </li>
                ))}
              </ul>
            )}

            {showManualForm && <NFManualEntryForm onAdd={addManual} onClose={() => setShowManualForm(false)} />}

            {!showManualForm && manualContacts.length === 0 && (
              <div className="text-[12px] text-[#5A4459]/80 italic ff-serif leading-relaxed">
                Anyone not in your phone — a colleague, a faith leader, a friend you only see in person.
              </div>
            )}
          </div>

          {(importedReady || manualOnlyReady) && (
            <div className="mt-5 flex items-center justify-end">
              <Btn onClick={onContinue} variant="plum">Review and sort →</Btn>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

const MANUAL_AVATARS = ['#E89B7E', '#A893C2', '#D4B591', '#9CA88C', '#B8A4C9', '#C9B8A4', '#E8C8B0', '#A8C9B8'];

function NFManualEntryForm({ onAdd, onClose }) {
  const [name, setName] = useStateNF('');
  const [label, setLabel] = useStateNF('');
  const [phone, setPhone] = useStateNF('');
  const canSubmit = name.trim().length > 1;
  const submit = () => {
    if (!canSubmit) return;
    const avatar = MANUAL_AVATARS[Math.floor(Math.random() * MANUAL_AVATARS.length)];
    onAdd({
      name: name.trim(),
      label: label.trim() || 'Added by hand',
      phone: phone.trim() || '—',
      avatar,
      reason: 'You added them.',
    });
    setName(''); setLabel(''); setPhone('');
  };
  return (
    <div className="rounded-xl bg-[#F8F2E7] border border-[#3D2B3C]/12 p-3 space-y-2">
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
        <input
          value={name}
          onChange={(e) => setName(e.target.value)}
          placeholder="Name"
          className="rounded-lg bg-white border border-[#3D2B3C]/15 px-3 py-2 text-[13px] text-[#3D2B3C] focus:outline-none focus:border-[#3D2B3C]/40"
        />
        <input
          value={label}
          onChange={(e) => setLabel(e.target.value)}
          placeholder="How you know them (e.g. cousin, neighbor)"
          className="rounded-lg bg-white border border-[#3D2B3C]/15 px-3 py-2 text-[13px] text-[#3D2B3C] focus:outline-none focus:border-[#3D2B3C]/40"
        />
      </div>
      <input
        value={phone}
        onChange={(e) => setPhone(e.target.value)}
        placeholder="Phone or email (optional)"
        className="w-full rounded-lg bg-white border border-[#3D2B3C]/15 px-3 py-2 text-[13px] text-[#3D2B3C] focus:outline-none focus:border-[#3D2B3C]/40"
      />
      <div className="flex items-center gap-2 pt-1">
        <Btn onClick={submit} variant="coral" size="sm" disabled={!canSubmit}>Add</Btn>
        <button onClick={onClose} className="text-[12px] text-[#5A4459] hover:text-[#3D2B3C]">Done adding</button>
      </div>
    </div>
  );
}

/* ---- step 1: tier assignment ---- */

const TIER_DESCRIPTIONS = {
  1: { label: 'You call them', sub: 'Today. Personal. Maybe 5–10 people.', dot: '#E89B7E' },
  2: { label: 'Family helps', sub: 'Within 24–48 hours. You or someone else in the workspace calls.', dot: '#B8A4C9' },
  3: { label: 'A note is fine', sub: 'Within a few days. One drafted message, sent by you.', dot: '#9CA88C' },
  4: { label: 'Public · later', sub: 'Wider network. Handled by the memorial site when you\'re ready.', dot: '#C0B0A0' },
};

function NFTierAssign({ compact, contacts, setContacts, setTier, onContinue, onShowMore, revealed, setRevealed }) {
  const addManual = (entry, tier) => {
    setContacts((cs) => [...cs, { ...entry, id: `m_${Date.now()}_${Math.random().toString(36).slice(2,6)}`, manual: true, tierAI: null, status: 'pending', tier, notifiedBy: null, inviteStatus: 'not_invited' }]);
  };

  const pendingByAI = (n) => contacts.filter((c) => c.tierAI === n);
  const inTier = (n) => contacts.filter((c) => c.tier === n && c.manual);
  const committedAt = (n) => contacts.filter((c) => c.tier === n).length;

  return (
    <div className="pt-6">
      <p className="text-[#5A4459] text-[13px] leading-relaxed max-w-[54ch] mb-5">
        I made a guess for each person below — based on how they're saved in your phone and how often you talk. <span className="ff-serif italic">Confirm or change any of them.</span> The list never leaves you until you say so.
      </p>

      <NFTierGroup tier={1} candidates={pendingByAI(1)} manualAdded={inTier(1)} contacts={contacts} setTier={setTier} compact={compact} onAddManual={(e) => addManual(e, 1)} />
      <NFTierGroup tier={2} candidates={pendingByAI(2)} manualAdded={inTier(2)} contacts={contacts} setTier={setTier} compact={compact} onAddManual={(e) => addManual(e, 2)} />
      <NFTierGroup tier={3} candidates={pendingByAI(3)} manualAdded={inTier(3)} contacts={contacts} setTier={setTier} compact={compact} onAddManual={(e) => addManual(e, 3)} />

      <div className="mt-7 flex items-center justify-between">
        <div className="text-[11px] text-[#5A4459]">
          {committedAt(1)} in Tier 1 · {committedAt(2)} in Tier 2 · {committedAt(3)} in Tier 3
        </div>
        <Btn onClick={onContinue} variant="plum" disabled={committedAt(1) === 0}>
          Start with Tier 1 →
        </Btn>
      </div>
    </div>
  );
}

function NFRevealNudge({ label, sub, onClick }) {
  return (
    <button onClick={onClick}
      className="w-full text-left rounded-2xl border border-dashed border-[#3D2B3C]/25 px-4 py-3 text-[#5A4459] hover:border-[#3D2B3C]/50 hover:text-[#3D2B3C] transition flex items-center justify-between mt-4">
      <div>
        <div className="text-[13px] ff-serif" style={{ fontStyle: 'italic', fontWeight: 380 }}>{label}</div>
        <div className="text-[11px] text-[#5A4459]/70 mt-0.5">{sub}</div>
      </div>
      <span className="text-[#5A4459] text-[16px]">↓</span>
    </button>
  );
}

function NFTierGroup({ tier, candidates, manualAdded = [], contacts, setTier, compact, onAddManual }) {
  const desc = TIER_DESCRIPTIONS[tier];
  const [showAdd, setShowAdd] = useStateNF(false);
  // combine: AI-suggested for this tier + manual adds already in this tier
  const allRows = [...candidates, ...manualAdded];
  return (
    <div className="mt-5 first:mt-0">
      <div className="flex items-baseline gap-2 mb-2">
        <span className="w-2 h-2 rounded-full" style={{ background: desc.dot }} />
        <div className="ff-mono text-[10px] text-[#5A4459]">TIER {tier}</div>
        <div className="ff-serif text-[#3D2B3C] text-[15px]" style={{ fontWeight: 500 }}>{desc.label}</div>
      </div>
      <div className="text-[12px] text-[#5A4459] mb-3 leading-relaxed">{desc.sub}</div>
      <div className="rounded-2xl border border-[#3D2B3C]/12 bg-white overflow-hidden">
        {allRows.map((c, i) => {
          const live = contacts.find((x) => x.id === c.id);
          return (
            <NFContactRow
              key={c.id}
              contact={live}
              tier={tier}
              isLast={i === allRows.length - 1 && !onAddManual}
              setTier={setTier}
              compact={compact}
            />
          );
        })}
        {onAddManual && (
          <div className={`px-4 py-2.5 ${allRows.length > 0 ? 'border-t border-[#3D2B3C]/8' : ''} bg-[#F8F2E7]/40`}>
            {!showAdd ? (
              <button onClick={() => setShowAdd(true)} className="text-[12px] text-[#3D2B3C] hover:text-[#5A4459] flex items-center gap-1.5">
                <span>+</span> Add someone to Tier {tier}
              </button>
            ) : (
              <NFManualEntryForm onAdd={(e) => { onAddManual(e); }} onClose={() => setShowAdd(false)} />
            )}
          </div>
        )}
      </div>
    </div>
  );
}

function NFContactRow({ contact, tier, isLast, setTier, compact }) {
  const committed = contact.tier !== null;
  const inThisTier = contact.tier === tier;
  return (
    <div className={`px-4 py-3 flex items-center gap-3 ${!isLast ? 'border-b border-[#3D2B3C]/8' : ''} ${committed && !inThisTier ? 'opacity-40' : ''}`}>
      <span className="w-9 h-9 rounded-full flex items-center justify-center text-[#3D2B3C] text-[12px] flex-shrink-0" style={{ background: contact.avatar, fontWeight: 500 }}>
        {contact.name.split(' ').map((p) => p[0]).slice(0,2).join('')}
      </span>
      <div className="flex-1 min-w-0">
        <div className="text-[14px] text-[#3D2B3C] truncate" style={{ fontWeight: 500 }}>{contact.name}</div>
        <div className="text-[11px] text-[#5A4459] truncate">{contact.label} · {contact.phone}</div>
        <div className="text-[10px] text-[#5A4459]/70 mt-0.5 flex items-center gap-1">
          <span className="ff-serif italic">betty:</span> {contact.reason}
        </div>
      </div>
      {!committed ? (
        <div className="flex items-center gap-1.5 flex-shrink-0">
          <button onClick={() => setTier(contact.id, tier)}
            className="text-[11px] px-2.5 py-1.5 rounded-full bg-[#3D2B3C] text-[#F8F2E7] hover:bg-[#5A4459]">
            Confirm
          </button>
          <select
            value=""
            onChange={(e) => e.target.value && setTier(contact.id, parseInt(e.target.value))}
            className="text-[11px] px-2 py-1.5 rounded-full bg-[#F8F2E7] border border-[#3D2B3C]/15 text-[#3D2B3C]"
          >
            <option value="">Move →</option>
            {[1,2,3].filter((t) => t !== tier).map((t) => <option key={t} value={t}>Tier {t}</option>)}
            <option value="0">Skip</option>
          </select>
        </div>
      ) : inThisTier ? (
        <button onClick={() => setTier(contact.id, null)} className="text-[11px] text-[#5A4459] hover:text-[#3D2B3C] flex-shrink-0 flex items-center gap-1">
          <span className="text-[#9CA88C]">✓</span> in tier {tier} <span className="opacity-60">undo</span>
        </button>
      ) : (
        <span className="text-[11px] text-[#5A4459] flex-shrink-0">→ Tier {contact.tier}</span>
      )}
    </div>
  );
}

/* ---- step 2: the calls (Tier 1) ---- */

function NFCalls({ compact, tier1, setStatus, setInvite, onAllDone, onBack, activeId, setActiveId, scriptKey, setScriptKey, onJoin }) {
  // default to first pending contact if nothing selected
  const effectiveActiveId = activeId || tier1.find((c) => c.status === 'pending')?.id || null;
  const active = tier1.find((c) => c.id === effectiveActiveId);
  const calledCount = tier1.filter((c) => c.status === 'called').length;
  const allCalled = tier1.every((c) => c.status !== 'pending');

  return (
    <div className="pt-6">
      {/* Mascot in QUIET state — moment before a hard call */}
      <div className="rounded-[22px] bg-[#F8F2E7] border border-[#3D2B3C]/12 p-5 mb-5">
        <div className="flex items-start gap-4">
          <MascotCard size={compact ? 48 : 56} state="quiet" />
          <div className="flex-1 pt-0.5">
            <p className="ff-serif text-[#3D2B3C] leading-[1.3] text-[16px] lg:text-[18px]" style={{ fontWeight: 400, fontStyle: 'italic' }}>
              One call at a time. The script's there if you freeze. Take a sip of water between each.
            </p>
          </div>
        </div>
      </div>

      <div className="grid gap-4 lg:grid-cols-[1fr_1.2fr]">
        {/* roster */}
        <div className="rounded-2xl bg-white border border-[#3D2B3C]/12 overflow-hidden">
          <div className="px-4 py-3 border-b border-[#3D2B3C]/10 flex items-center justify-between">
            <div>
              <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459]">Tier 1 · your calls</div>
              <div className="ff-serif text-[#3D2B3C] mt-0.5" style={{ fontSize: 16, fontWeight: 500 }}>
                {calledCount} of {tier1.length} done
              </div>
            </div>
            <div className="ff-mono text-[10px] text-[#5A4459]">private</div>
          </div>
          <ul>
            {tier1.map((c, i) => (
              <li key={c.id}
                onClick={() => setActiveId(c.id)}
                className={`px-4 py-3 flex items-center gap-3 cursor-pointer ${i !== tier1.length - 1 ? 'border-b border-[#3D2B3C]/8' : ''} ${effectiveActiveId === c.id ? 'bg-[#F8F2E7]' : 'hover:bg-[#F8F2E7]/60'}`}>
                <span className="w-8 h-8 rounded-full flex items-center justify-center text-[#3D2B3C] text-[11px] flex-shrink-0" style={{ background: c.avatar, fontWeight: 500 }}>
                  {c.name.split(' ').map((p) => p[0]).slice(0,2).join('')}
                </span>
                <div className="flex-1 min-w-0">
                  <div className="text-[13px] text-[#3D2B3C] truncate" style={{ fontWeight: 500 }}>{c.name}</div>
                  <div className="text-[11px] text-[#5A4459]">{c.label}</div>
                </div>
                {c.status === 'called' && <span className="text-[11px] text-[#9CA88C] flex-shrink-0">✓ called</span>}
                {c.status === 'declined' && <span className="text-[11px] text-[#5A4459]/60 flex-shrink-0">— skipped</span>}
                {c.status === 'pending' && effectiveActiveId === c.id && <span className="text-[11px] text-[#3D2B3C] flex-shrink-0">→</span>}
              </li>
            ))}
          </ul>
        </div>

        {/* script + actions */}
        <div className="rounded-2xl bg-white border border-[#3D2B3C]/12 p-5">
          {active ? (
            <>
              <div className="flex items-center gap-3 mb-3">
                <span className="w-10 h-10 rounded-full flex items-center justify-center text-[#3D2B3C] text-[12px]" style={{ background: active.avatar, fontWeight: 500 }}>
                  {active.name.split(' ').map((p) => p[0]).slice(0,2).join('')}
                </span>
                <div>
                  <div className="ff-serif text-[#3D2B3C]" style={{ fontSize: 18, fontWeight: 500 }}>{active.name}</div>
                  <div className="text-[12px] text-[#5A4459]">{active.label} · {active.phone}</div>
                </div>
              </div>

              <div className="text-[10px] uppercase tracking-[.18em] text-[#5A4459] mb-2">If you freeze, start here</div>

              {/* script variant tabs */}
              <div className="flex gap-1.5 mb-2">
                {Object.entries(SCRIPTS).map(([k, s]) => (
                  <button key={k}
                    onClick={() => setScriptKey(k)}
                    className={`text-[11px] px-2.5 py-1 rounded-full transition ${
                      scriptKey === k
                        ? 'bg-[#3D2B3C] text-[#F8F2E7]'
                        : 'bg-[#F8F2E7] text-[#5A4459] hover:text-[#3D2B3C]'
                    }`}>
                    {s.label}
                  </button>
                ))}
              </div>

              <div className="rounded-xl bg-[#F8F2E7] border border-[#3D2B3C]/8 p-4">
                <p className="ff-serif text-[#3D2B3C] leading-[1.45] text-[15px] lg:text-[16px]" style={{ fontWeight: 400 }}>
                  {SCRIPTS[scriptKey].body.replace('{name}', active.name.split(' ')[0])}
                </p>
              </div>
              <div className="text-[11px] text-[#5A4459]/80 mt-2 leading-relaxed italic ff-serif">
                The "I'm so sorry to be the one telling you" line does work. Don't drop it.
              </div>

              <div className="mt-5 flex flex-wrap gap-2">
                <Btn variant="coral" size="sm" onClick={() => { setStatus(active.id, 'called'); }}>
                  ✓ I called {active.name.split(' ')[0]}
                </Btn>
                <button
                  onClick={() => setStatus(active.id, 'declined')}
                  className="text-[12px] px-3 py-2 rounded-full bg-[#F8F2E7] border border-[#3D2B3C]/15 text-[#5A4459] hover:text-[#3D2B3C]">
                  Skip — they're hearing it another way
                </button>
              </div>

              {/* Post-call invite offer — separate beat, never bundled with the death announcement */}
              {active.status === 'called' && active.inviteStatus === 'not_invited' && active.inviteSuggested && (
                <div className="mt-5 rounded-2xl bg-gradient-to-b from-[#B8A4C9]/15 to-transparent border border-[#3D2B3C]/12 p-4">
                  <div className="flex items-start gap-3">
                    <MascotGlyph size={24} />
                    <div className="flex-1">
                      <div className="ff-serif text-[#3D2B3C]" style={{ fontSize: 15, fontWeight: 500 }}>
                        Now that {active.name.split(' ')[0]} knows — want her in the workspace?
                      </div>
                      <div className="text-[#5A4459] text-[12px] leading-relaxed mt-1">
                        I'll send a separate text with a link — lighter, just an invite. Never bundled with the news you just shared.
                      </div>
                      <div className="text-[10px] text-[#5A4459]/70 mt-1.5 italic ff-serif">
                        betty: {active.inviteReason}
                      </div>
                      <div className="mt-3 flex flex-wrap gap-2">
                        <Btn variant="plum" size="sm" onClick={() => setInvite(active.id, 'invited')}>Send invite</Btn>
                        <button onClick={() => setInvite(active.id, 'deferred')} className="text-[12px] px-3 py-1.5 rounded-full bg-white border border-[#3D2B3C]/15 text-[#5A4459] hover:text-[#3D2B3C]">Not yet — give her a day</button>
                        <button onClick={() => setInvite(active.id, 'declined')} className="text-[12px] text-[#5A4459] hover:text-[#3D2B3C]">She won't want to help with this</button>
                      </div>
                    </div>
                  </div>
                </div>
              )}

              {active.status === 'called' && !active.inviteSuggested && active.inviteStatus === 'not_invited' && (
                <div className="mt-5 text-[11px] text-[#5A4459]/80 italic ff-serif leading-relaxed">
                  When you're ready, you can also <button onClick={() => setInvite(active.id, 'invited')} className="text-[#3D2B3C] underline decoration-dotted underline-offset-2">invite {active.name.split(' ')[0]} to the workspace</button> — separately, in their own beat.
                </div>
              )}

              {active.inviteStatus === 'invited' && (
                <div className="mt-5 rounded-xl bg-[#F8F2E7] border border-[#3D2B3C]/10 p-3">
                  <div className="text-[12px] text-[#9CA88C] flex items-center gap-1.5">
                    <span>✓</span> Invite sent to {active.name.split(' ')[0]} — separate text, separate beat.
                  </div>
                  <div className="mt-2 flex items-center gap-2">
                    <span className="text-[10px] uppercase tracking-[.16em] text-[#5A4459]/70">demo:</span>
                    <button
                      onClick={() => { setInvite(active.id, 'accepted'); setStatus(active.id, 'workspace', active.id); onJoin && onJoin(active.id); }}
                      className="text-[11px] px-2.5 py-1 rounded-full bg-[#3D2B3C] text-[#F8F2E7] hover:bg-[#5A4459]">
                      → simulate {active.name.split(' ')[0]} accepts
                    </button>
                  </div>
                </div>
              )}
              {active.inviteStatus === 'accepted' && (
                <div className="mt-5 text-[12px] text-[#3D2B3C] flex items-center gap-1.5">
                  <span className="w-1.5 h-1.5 rounded-full bg-[#9CA88C]" /> {active.name.split(' ')[0]} joined the workspace · notification auto-marked
                </div>
              )}
              {active.inviteStatus === 'deferred' && (
                <div className="mt-5 text-[12px] text-[#5A4459] italic ff-serif">
                  I'll quietly remind you tomorrow.
                </div>
              )}
            </>
          ) : (
            <div className="ff-serif text-[#3D2B3C]" style={{ fontSize: 18, fontWeight: 400, fontStyle: 'italic' }}>
              All your Tier 1 calls are done.
            </div>
          )}
        </div>
      </div>

      <div className="mt-6 flex items-center justify-between">
        <button onClick={onBack} className="text-[12px] text-[#5A4459] hover:text-[#3D2B3C]">← Back to tiers</button>
        <Btn onClick={onAllDone} variant="plum" disabled={calledCount === 0}>
          {allCalled ? 'Tier 1 done — share the load →' : `Continue with ${calledCount} done →`}
        </Btn>
      </div>
    </div>
  );
}

/* ---- step 3: distribute Tier 2 ---- */

function NFDistribute({ compact, tier2, family, claim, onAddManual, onContinue, onBack }) {
  const joined = family.filter((f) => f.joined && f.id !== 'sarah');
  const unclaimed = tier2.filter((c) => c.status === 'pending');
  const claimed = tier2.filter((c) => c.status === 'claimed');
  const [showAdd, setShowAdd] = useStateNF(false);

  return (
    <div className="pt-6">
      <div className="rounded-[22px] bg-gradient-to-b from-[#B8A4C9]/15 to-[#F4A88E]/10 border border-[#3D2B3C]/8 p-5 mb-6">
        <div className="flex items-start gap-4">
          <MascotCard size={compact ? 48 : 56} />
          <div className="flex-1 pt-0.5">
            <p className="ff-serif text-[#3D2B3C] leading-[1.3] text-[17px] lg:text-[19px]" style={{ fontWeight: 400 }}>
              You don't have to call all of these. Hand any of them to family — they'll claim what they can.
            </p>
            <p className="text-[#5A4459] text-[12px] leading-relaxed mt-2">
              Each name becomes its own little task. Your sister can pick up Aunt Karen; your cousin can do the cousins. Anyone who declines stays private.
            </p>
          </div>
        </div>
      </div>

      <div className="rounded-2xl bg-white border border-[#3D2B3C]/12 overflow-hidden">
        <div className="px-4 py-3 border-b border-[#3D2B3C]/10 flex items-center justify-between">
          <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459]">Tier 2 · open task pool</div>
          <div className="ff-mono text-[10px] text-[#5A4459]">{unclaimed.length} open · {claimed.length} claimed</div>
        </div>
        <ul>
          {tier2.map((c, i) => {
            const claimer = c.notifiedBy ? family.find((f) => f.id === c.notifiedBy) : null;
            return (
              <li key={c.id} className={`px-4 py-3 flex items-center gap-3 ${i !== tier2.length - 1 ? 'border-b border-[#3D2B3C]/8' : ''}`}>
                <span className="w-8 h-8 rounded-full flex items-center justify-center text-[#3D2B3C] text-[11px] flex-shrink-0" style={{ background: c.avatar, fontWeight: 500 }}>
                  {c.name.split(' ').map((p) => p[0]).slice(0,2).join('')}
                </span>
                <div className="flex-1 min-w-0">
                  <div className="text-[13px] text-[#3D2B3C] truncate" style={{ fontWeight: 500 }}>Call {c.name}</div>
                  <div className="text-[11px] text-[#5A4459]">{c.label} · {c.phone}</div>
                </div>
                {c.status === 'claimed' && claimer ? (
                  <div className="flex items-center gap-1.5 flex-shrink-0">
                    <span className="w-4 h-4 rounded-full" style={{ background: claimer.color }} />
                    <span className="text-[11px] text-[#3D2B3C]">{claimer.firstName} took it</span>
                  </div>
                ) : (
                  <select
                    value=""
                    onChange={(e) => e.target.value && claim(c.id, e.target.value)}
                    className="text-[11px] px-2 py-1.5 rounded-full bg-[#F8F2E7] border border-[#3D2B3C]/15 text-[#3D2B3C] flex-shrink-0">
                    <option value="">Open · anyone can claim</option>
                    {joined.length === 0 && <option disabled>No family joined yet</option>}
                    {joined.map((f) => <option key={f.id} value={f.id}>Suggest to {f.firstName}</option>)}
                    <option value="sarah">Keep for myself</option>
                  </select>
                )}
              </li>
            );
          })}
        </ul>
        {onAddManual && (
          <div className="px-4 py-2.5 border-t border-[#3D2B3C]/8 bg-[#F8F2E7]/40">
            {!showAdd ? (
              <button onClick={() => setShowAdd(true)} className="text-[12px] text-[#3D2B3C] hover:text-[#5A4459] flex items-center gap-1.5">
                <span>+</span> Add someone to Tier 2
              </button>
            ) : (
              <NFManualEntryForm onAdd={(e) => { onAddManual(e); }} onClose={() => setShowAdd(false)} />
            )}
          </div>
        )}
      </div>

      <div className="text-[11px] text-[#5A4459]/80 mt-3 leading-relaxed italic ff-serif">
        Calls each family member claims show up on their Today. Suggestions never appear in the public activity feed — declines stay private.
      </div>

      <div className="mt-6 flex items-center justify-between">
        <button onClick={onBack} className="text-[12px] text-[#5A4459] hover:text-[#3D2B3C]">← Back to calls</button>
        <Btn onClick={onContinue} variant="plum">Draft the wider note →</Btn>
      </div>
    </div>
  );
}

/* ---- step 4: Tier 3 group message ---- */

function NFGroupMessage({ compact, tier3, setStatus, onAddManual, onContinue, onBack, draft, setDraft, sent, setSent }) {
  const [showAdd, setShowAdd] = useStateNF(false);
  const handleSend = () => {
    tier3.forEach((c) => setStatus(c.id, 'messaged'));
    setSent(true);
  };

  return (
    <div className="pt-6">
      <div className="rounded-2xl bg-white border border-[#3D2B3C]/12 p-5 mb-5">
        <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459] mb-2">Tier 3 · {tier3.length} people</div>
        <h3 className="ff-serif text-[#3D2B3C]" style={{ fontSize: 20, fontWeight: 400 }}>
          One note. They'll forgive the imperfection.
        </h3>
        <p className="text-[#5A4459] text-[13px] leading-relaxed mt-2 max-w-[58ch]">
          Edit anything. The last line — "please don't feel any pressure to respond" — is doing real work; it releases people from the obligation to perform a perfect reply, which means less inbound for you later.
        </p>

        <textarea
          value={draft}
          onChange={(e) => setDraft(e.target.value)}
          rows={9}
          disabled={sent}
          className="w-full mt-4 rounded-xl bg-[#F8F2E7] border border-[#3D2B3C]/15 p-4 ff-serif text-[#3D2B3C] leading-[1.5] focus:outline-none focus:border-[#3D2B3C]/40 disabled:opacity-60 text-[14px] lg:text-[15px]"
          style={{ fontWeight: 400 }}
        />

        <div className="text-[11px] text-[#5A4459]/80 mt-2 italic ff-serif">
          MissBetty drafts. You press send. Nothing leaves until you do.
        </div>
      </div>

      <div className="rounded-2xl bg-[#F8F2E7] border border-[#3D2B3C]/15 p-4 mb-5">
        <div className="text-[10px] uppercase tracking-[.18em] text-[#5A4459] mb-2 flex items-center justify-between">
          <span>Sending to</span>
          {onAddManual && !sent && (
            <button onClick={() => setShowAdd((v) => !v)} className="text-[11px] text-[#3D2B3C] hover:text-[#5A4459] normal-case tracking-normal">
              {showAdd ? '— hide' : '+ Add someone'}
            </button>
          )}
        </div>
        <div className="flex flex-wrap gap-1.5">
          {tier3.map((c) => (
            <span key={c.id} className="text-[11px] px-2 py-1 rounded-full bg-white border border-[#3D2B3C]/12 text-[#3D2B3C] flex items-center gap-1.5">
              <span className="w-3.5 h-3.5 rounded-full" style={{ background: c.avatar }} />
              {c.name}
            </span>
          ))}
        </div>
        {showAdd && (
          <div className="mt-3">
            <NFManualEntryForm onAdd={(e) => { onAddManual(e); }} onClose={() => setShowAdd(false)} />
          </div>
        )}
      </div>

      <div className="flex items-center justify-between">
        <button onClick={onBack} className="text-[12px] text-[#5A4459] hover:text-[#3D2B3C]">← Back</button>
        <div className="flex items-center gap-2">
          {!sent ? (
            <Btn onClick={handleSend} variant="coral">Send to {tier3.length} people</Btn>
          ) : (
            <span className="text-[12px] text-[#9CA88C] flex items-center gap-1.5">
              <span>✓</span> Sent · {tier3.length} people
            </span>
          )}
          <Btn onClick={onContinue} variant="plum">{sent ? 'See where things stand →' : 'Skip for now →'}</Btn>
        </div>
      </div>
    </div>
  );
}

/* ---- step 5: summary ---- */

function NFSummary({ compact, contacts, family, onMarkDone, onBack }) {
  const total = contacts.filter((c) => c.tier !== null).length;
  const called = contacts.filter((c) => c.status === 'called').length;
  const claimed = contacts.filter((c) => c.status === 'claimed').length;
  const messaged = contacts.filter((c) => c.status === 'messaged').length;
  const pending = total - called - claimed - messaged;
  const reached = called + claimed + messaged;

  return (
    <div className="pt-6">
      <div className="rounded-[22px] bg-gradient-to-b from-[#9CA88C]/15 to-[#F4A88E]/10 border border-[#3D2B3C]/8 p-5 mb-5">
        <div className="flex items-start gap-4">
          <MascotCard size={compact ? 48 : 56} />
          <div className="flex-1 pt-0.5">
            <p className="ff-serif text-[#3D2B3C] leading-[1.25] text-[19px] lg:text-[22px]" style={{ fontWeight: 400 }}>
              {reached} people now know. The rest are in motion.
            </p>
            <p className="text-[#5A4459] text-[13px] leading-relaxed mt-2">
              You did the hardest part. Anything still open will keep — I'll surface it on your Today when the moment is right.
            </p>
          </div>
        </div>
      </div>

      {/* who-was-told roster */}
      <div className="rounded-2xl bg-white border border-[#3D2B3C]/12 overflow-hidden">
        <div className="px-4 py-3 border-b border-[#3D2B3C]/10 flex items-center justify-between">
          <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459]">Who's been told · who's joined</div>
          <div className="ff-mono text-[10px] text-[#5A4459]">{reached} of {total} · {contacts.filter((c) => c.inviteStatus === 'invited' || c.inviteStatus === 'accepted').length} invited</div>
        </div>
        <ul className="max-h-[320px] overflow-y-auto">
          {contacts.filter((c) => c.tier !== null).map((c, i, arr) => {
            const by = c.notifiedBy ? family.find((f) => f.id === c.notifiedBy) : null;
            const verb = c.status === 'called' ? 'called' :
                         c.status === 'messaged' ? 'in group note' :
                         c.status === 'claimed' ? `${by?.firstName || 'Family'} on it` :
                         'not yet';
            const dot = c.status === 'called' ? '#9CA88C' :
                        c.status === 'messaged' ? '#B8A4C9' :
                        c.status === 'claimed' ? '#E89B7E' :
                        'rgba(61,43,60,0.2)';
            return (
              <li key={c.id} className={`px-4 py-2.5 flex items-center gap-3 ${i !== arr.length - 1 ? 'border-b border-[#3D2B3C]/6' : ''}`}>
                <span className="w-6 h-6 rounded-full flex items-center justify-center text-[#3D2B3C] text-[10px] flex-shrink-0" style={{ background: c.avatar, fontWeight: 500 }}>
                  {c.name.split(' ').map((p) => p[0]).slice(0,2).join('')}
                </span>
                <div className="flex-1 min-w-0">
                  <div className="text-[13px] text-[#3D2B3C] truncate">{c.name}</div>
                  <div className="text-[10px] text-[#5A4459]">Tier {c.tier} · {c.label}</div>
                </div>
                <div className="flex items-center gap-1.5 flex-shrink-0">
                  <span className="w-1.5 h-1.5 rounded-full" style={{ background: dot }} />
                  <span className="text-[11px] text-[#5A4459]">{verb}</span>
                  {(c.inviteStatus === 'invited' || c.inviteStatus === 'accepted') && (
                    <span className="ml-1 text-[9px] uppercase tracking-[.12em] px-1.5 py-0.5 rounded-full bg-[#B8A4C9]/25 text-[#3D2B3C]">invited</span>
                  )}
                </div>
              </li>
            );
          })}
        </ul>
      </div>

      <div className="text-[11px] text-[#5A4459]/80 mt-3 leading-relaxed italic ff-serif">
        Family members in the workspace see only the fact of contact — names and status. Phone numbers and addresses stay with whoever imported them.
      </div>

      <div className="mt-6 flex items-center justify-between">
        <button onClick={onBack} className="text-[12px] text-[#5A4459] hover:text-[#3D2B3C]">← Back</button>
        <Btn onClick={onMarkDone} variant="plum">Mark this task done →</Btn>
      </div>
    </div>
  );
}

/* ---- export ---- */
/* ---- collaborator backfeed (3-question intake when an invitee joins) ---- */

function NFCollabBackfeed({ compact, joinerId, contacts, setContacts, onContinue }) {
  const joiner = contacts.find((c) => c.id === joinerId);
  const firstName = joiner ? joiner.name.split(' ')[0] : 'They';

  // mock contacts the joiner would add (in real product, from their phone import)
  const SUGGESTED_ADDS = joinerId === 'jamie' ? [
    { id: `bf_${joinerId}_1`, name: 'Tomás Vega',  label: 'Henry\'s grad-school friend', phone: '(415) 555-0481', avatar: '#B8A4C9', addedBy: joinerId, reason: `${firstName} added them` },
    { id: `bf_${joinerId}_2`, name: 'Alice Wu', label: 'Hospice nurse', phone: '(415) 555-0512', avatar: '#A8C9B8', addedBy: joinerId, reason: `${firstName} added them` },
  ] : [
    { id: `bf_${joinerId}_1`, name: 'Eleanor Chen', label: 'Henry\'s sister-in-law', phone: '(510) 555-0233', avatar: '#D4B591', addedBy: joinerId, reason: `${firstName} added them` },
    { id: `bf_${joinerId}_2`, name: 'Wendy Park',  label: 'Old neighbor',           phone: '(415) 555-0388', avatar: '#E8C8B0', addedBy: joinerId, reason: `${firstName} added them` },
  ];

  const [q1, setQ1] = useStateNF('pending'); // pending | added | declined
  const [alreadyTold, setAlreadyTold] = useStateNF([]); // contact ids
  const [q3, setQ3] = useStateNF(null); // null | 'yes' | 'no'

  const toggleAlreadyTold = (id) => setAlreadyTold((cur) => cur.includes(id) ? cur.filter((x) => x !== id) : [...cur, id]);
  const finishQ1Add = () => {
    setContacts((cs) => [
      ...cs,
      ...SUGGESTED_ADDS.map((s) => ({ ...s, manual: false, tierAI: 2, tier: null, status: 'pending', notifiedBy: null, inviteStatus: 'not_invited', inviteSuggested: false })),
    ]);
    setQ1('added');
  };
  const finishAll = () => {
    if (alreadyTold.length > 0) {
      setContacts((cs) => cs.map((c) => alreadyTold.includes(c.id) ? { ...c, status: 'called', notifiedBy: joinerId } : c));
    }
    onContinue();
  };

  const tier2Suggested = contacts.filter((c) => c.tierAI === 2 && c.status === 'pending').slice(0, 6);

  return (
    <div className="pt-6">
      <div className="rounded-[22px] bg-gradient-to-b from-[#9CA88C]/15 to-[#B8A4C9]/15 border border-[#3D2B3C]/8 p-5 mb-6">
        <div className="flex items-start gap-4">
          <MascotCard size={compact ? 48 : 56} />
          <div className="flex-1 pt-0.5">
            <div className="text-[10px] uppercase tracking-[.18em] text-[#5A4459] mb-1">Showing what {firstName} sees on join</div>
            <p className="ff-serif text-[#3D2B3C] leading-[1.25] text-[19px] lg:text-[22px]" style={{ fontWeight: 400 }}>
              Welcome, {firstName}. Three quick questions — your answers help Sarah.
            </p>
            <p className="text-[#5A4459] text-[12px] leading-relaxed mt-2 italic ff-serif">
              The collaborator self-intake. None of this is shared until {firstName} answers it.
            </p>
          </div>
        </div>
      </div>

      {/* Q1 */}
      <div className="rounded-2xl bg-white border border-[#3D2B3C]/12 p-5 mb-4">
        <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459] mb-1">Question 1</div>
        <h3 className="ff-serif text-[#3D2B3C] text-[17px] lg:text-[19px]" style={{ fontWeight: 400 }}>
          Are there family or friends not yet on the list?
        </h3>
        <p className="text-[#5A4459] text-[12px] leading-relaxed mt-1.5 max-w-[58ch]">
          Sarah's contact list won't be complete. Anyone you have that she might not — Dad's grad-school friends, his hospice nurse, that one cousin in Hong Kong — add them here.
        </p>
        <div className="mt-3 rounded-xl bg-[#F8F2E7] border border-[#3D2B3C]/8 p-3">
          <div className="text-[10px] uppercase tracking-[.16em] text-[#5A4459] mb-2">From {firstName}'s phone</div>
          <div className="space-y-1.5">
            {SUGGESTED_ADDS.map((s) => (
              <div key={s.id} className="flex items-center gap-2 text-[13px]">
                <span className="w-6 h-6 rounded-full flex items-center justify-center text-[10px] text-[#3D2B3C] flex-shrink-0" style={{ background: s.avatar, fontWeight: 500 }}>
                  {s.name.split(' ').map((p) => p[0]).slice(0,2).join('')}
                </span>
                <span className="text-[#3D2B3C] flex-1 truncate">{s.name} <span className="text-[#5A4459] text-[11px]">· {s.label}</span></span>
              </div>
            ))}
          </div>
          <div className="mt-3 flex flex-wrap gap-2">
            {q1 === 'pending' && (
              <>
                <Btn variant="coral" size="sm" onClick={finishQ1Add}>Add these {SUGGESTED_ADDS.length} to the roster</Btn>
                <button onClick={() => setQ1('declined')} className="text-[12px] text-[#5A4459] hover:text-[#3D2B3C]">Skip — keep my contacts private</button>
              </>
            )}
            {q1 === 'added' && (
              <span className="text-[12px] text-[#9CA88C]">✓ Added · they'll show up unassigned for Sarah to tier.</span>
            )}
            {q1 === 'declined' && (
              <span className="text-[12px] text-[#5A4459] italic ff-serif">Skipped — no contacts shared.</span>
            )}
          </div>
        </div>
      </div>

      {/* Q2 */}
      <div className="rounded-2xl bg-white border border-[#3D2B3C]/12 p-5 mb-4">
        <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459] mb-1">Question 2</div>
        <h3 className="ff-serif text-[#3D2B3C] text-[17px] lg:text-[19px]" style={{ fontWeight: 400 }}>
          Have you told anyone yet?
        </h3>
        <p className="text-[#5A4459] text-[12px] leading-relaxed mt-1.5 max-w-[58ch]">
          So we don't double-call. Tap anyone you've already reached.
        </p>
        <div className="mt-3 flex flex-wrap gap-1.5">
          {tier2Suggested.length === 0 ? (
            <span className="text-[11px] text-[#5A4459] italic ff-serif">Nobody in the Tier 2 pool yet.</span>
          ) : tier2Suggested.map((c) => {
            const on = alreadyTold.includes(c.id);
            return (
              <button key={c.id} onClick={() => toggleAlreadyTold(c.id)}
                className={`text-[12px] px-2.5 py-1.5 rounded-full border transition flex items-center gap-1.5 ${
                  on ? 'bg-[#9CA88C]/20 border-[#9CA88C] text-[#3D2B3C]' : 'bg-white border-[#3D2B3C]/15 text-[#5A4459] hover:text-[#3D2B3C]'
                }`}>
                <span className="w-3.5 h-3.5 rounded-full" style={{ background: c.avatar }} />
                {on && <span className="text-[#9CA88C]">✓</span>} {c.name}
              </button>
            );
          })}
        </div>
        {alreadyTold.length > 0 && (
          <div className="text-[11px] text-[#5A4459] mt-2 italic ff-serif">
            {alreadyTold.length} {alreadyTold.length === 1 ? 'person' : 'people'} marked told — Sarah's roster won't ring them again.
          </div>
        )}
      </div>

      {/* Q3 */}
      <div className="rounded-2xl bg-white border border-[#3D2B3C]/12 p-5 mb-5">
        <div className="text-[11px] uppercase tracking-[.18em] text-[#5A4459] mb-1">Question 3</div>
        <h3 className="ff-serif text-[#3D2B3C] text-[17px] lg:text-[19px]" style={{ fontWeight: 400 }}>
          Want to help with notifications?
        </h3>
        <p className="text-[#5A4459] text-[12px] leading-relaxed mt-1.5 max-w-[58ch]">
          If yes, the Tier 2 calls open up to you in the shared task pool. Pick what you can carry. Skip what you can't.
        </p>
        <div className="mt-3 flex gap-2">
          <button onClick={() => setQ3('yes')}
            className={`text-[12px] px-3 py-1.5 rounded-full border transition ${q3 === 'yes' ? 'bg-[#3D2B3C] text-[#F8F2E7] border-[#3D2B3C]' : 'bg-white border-[#3D2B3C]/15 text-[#3D2B3C] hover:bg-[#F8F2E7]'}`}>
            Yes, I can help
          </button>
          <button onClick={() => setQ3('no')}
            className={`text-[12px] px-3 py-1.5 rounded-full border transition ${q3 === 'no' ? 'bg-[#3D2B3C] text-[#F8F2E7] border-[#3D2B3C]' : 'bg-white border-[#3D2B3C]/15 text-[#5A4459] hover:text-[#3D2B3C]'}`}>
            Not right now
          </button>
        </div>
      </div>

      <div className="rounded-xl bg-[#F8F2E7] border border-[#3D2B3C]/10 px-4 py-3 mb-5">
        <div className="text-[10px] uppercase tracking-[.16em] text-[#5A4459]">Privacy</div>
        <div className="text-[12px] text-[#3D2B3C] mt-1 leading-relaxed">
          Other workspace members see <span className="ff-serif italic">names and statuses</span> — never the underlying phone numbers or addresses {firstName} imported.
        </div>
      </div>

      <div className="flex items-center justify-end">
        <Btn onClick={finishAll} variant="plum" disabled={q3 === null}>
          Finish join — back to Sarah's flow →
        </Btn>
      </div>
    </div>
  );
}
Object.assign(window, { NotifyFamilyWorkflow });
