// ─────────────────────────────────────────────────────────────
// Section 1 - Personal Details
// ─────────────────────────────────────────────────────────────

// True when an address has been entered but we can't find a street/unit
// number in it (no detected parts number, no manual number, and the address
// doesn't start with a digit). Drives a required manual street-number field.
function addrNeedsNumber(person) {
  const a = String((person && person.address) || '').trim();
  if (!a) return false;
  if (person.streetNo && String(person.streetNo).trim()) return false;
  if (person.addressParts && person.addressParts.streetNumber) return false;
  return !/^\d/.test(a);
}

function SectionPersonal({ data, set, saveCode, ensureSaveCode }) {
  const d = data.personal || {};
  // Functional setState ensures that two updates fired in the same React
  // batch (e.g. selecting "No" on the couple-advice question, which both
  // toggles primary.coupleAdvice and resets the section-level activeTab)
  // don't overwrite each other. Each patch is applied against the most
  // recent state, not a stale closure snapshot.
  const update = (patch) => set(prev => {
    const prevPersonal = prev.personal || {};
    return { ...prev, personal: { ...prevPersonal, ...patch } };
  });
  const primary = d.primary || {};
  const updatePrimary = (patch) => set(prev => {
    const prevPersonal = prev.personal || {};
    const prevPrimary = prevPersonal.primary || {};
    return { ...prev, personal: { ...prevPersonal, primary: { ...prevPrimary, ...patch } } };
  });
  const partner = d.partner || {};
  const updatePartner = (patch) => set(prev => {
    const prevPersonal = prev.personal || {};
    const prevPartner = prevPersonal.partner || {};
    return { ...prev, personal: { ...prevPersonal, partner: { ...prevPartner, ...patch } } };
  });

  // Was this couple set up by the adviser at invite time? If so, the client
  // can't opt out of completing partner details (the adviser deliberately
  // paired them). If the client added the partner themselves, they can back
  // out in case it was an accidental selection.
  const partnerInvited = d.partnerInvited === true;
  const removePartner = () => set(prev => {
    const prevPersonal = prev.personal || {};
    const prevPrimary = prevPersonal.primary || {};
    return { ...prev, personal: {
      ...prevPersonal,
      primary: { ...prevPrimary, coupleAdvice: false },
      partner: {},
      includePartner: false,
      partnerCompletion: undefined,
      preferredContact: undefined,
      activeTab: 'primary',
    } };
  });

  const age = primary.dob ? Math.floor((new Date() - new Date(primary.dob)) / (365.25*24*3600*1000)) : '';

  // Partner panel only shows for Married / De facto AND only when the client
  // confirms they're receiving advice as a couple. If they're not, the partner
  // tab is hidden and its fields aren't validated.
  const isCouple = ['Married', 'De facto'].includes(primary.relStatus);
  const showPartnerFields = (isCouple && primary.coupleAdvice === true) || d.includePartner;

  return (
    <div className="section-body">
      <PersonTabs
        showPartner={showPartnerFields}
        activeTab={d.activeTab || 'primary'}
        primaryName={[primary.firstName, primary.lastName].filter(Boolean).join(' ').trim() || null}
        partnerName={[partner.firstName, partner.lastName].filter(Boolean).join(' ').trim() || null}
        onTab={(t) => update({ activeTab: t })}
        onAddPartner={() => update({ includePartner: true, activeTab: 'partner' })}
      />

      {(d.activeTab || 'primary') === 'primary' && (
        <PrimaryPanel primary={primary} update={updatePrimary} age={age}
          sectionUpdate={update}
          partner={partner} showPartner={showPartnerFields}
          preferredContact={d.preferredContact} />
      )}
      {d.activeTab === 'partner' && (
        <PartnerCompletionGate
          partner={partner}
          partnerCompletion={d.partnerCompletion}
          canRemove={!partnerInvited}
          onRemovePartner={removePartner}
          saveCode={saveCode}
          ensureSaveCode={ensureSaveCode}
          onPick={(v) => update({ partnerCompletion: v })}>
          <PartnerPanel partner={partner} primary={primary} update={updatePartner} />
        </PartnerCompletionGate>
      )}
    </div>
  );
}

// Wrapper around the Partner panel that surfaces the two-choice picker:
//   - 'self'   : primary fills in the partner data themselves (current
//                model) - the wrapped <PartnerPanel> renders below.
//   - 'remind' : partner will sign in to their OWN invite + complete
//                their half. The panel is replaced with a banner that
//                offers to send the reminder email immediately. Submit
//                is gated server-side until the partner's own
//                fact-find is `status='submitted'`.
function PartnerCompletionGate({ partner, partnerCompletion, canRemove, onRemovePartner, saveCode, ensureSaveCode, onPick, children }) {
  const partnerName = [partner?.firstName, partner?.lastName].filter(Boolean).join(' ').trim() || 'your partner';
  const partnerEmail = partner?.email || '';
  const [sending, setSending] = useState(false);
  // Modal state: shown after every send attempt (success OR failure)
  // so the user always sees a clear "yes/no" beat. The kind drives
  // copy + colour inside the modal.
  const [modal, setModal] = useState(null); // null | { kind: 'ok'|'fail', sentTo?, msg? }
  // Confirm step before removing the partner entirely (clears the choice +
  // any partner details and hides this tab). Only offered when the partner
  // wasn't invited as a couple by the adviser.
  const [confirmRemove, setConfirmRemove] = useState(false);

  async function sendReminder() {
    if (sending) return;
    setSending(true);
    let next;
    try {
      // The Send-reminder endpoint needs a server-side fact-find row.
      // If the client hasn't typed enough to trigger autosave yet,
      // create one now so the reminder doesn't silently no-op.
      let code = saveCode;
      if (!code && typeof ensureSaveCode === 'function') {
        try { code = await ensureSaveCode(); } catch (_e) { /* fall through */ }
      }
      if (!code) {
        next = { kind: 'fail', msg: 'We could not start a save record for you. Please type a few details first, then try again.' };
      } else {
        const r = await fetch(`/api/factfind/${encodeURIComponent(code)}/remind-partner`, {
          method: 'POST', credentials: 'same-origin',
          headers: { 'Content-Type': 'application/json' }, body: '{}',
        });
        const j = await r.json().catch(() => ({}));
        if (!r.ok) {
          // Translate the most common server errors into copy the user
          // can actually act on, rather than the raw error code.
          const code = j?.error || ('HTTP ' + r.status);
          const friendly = code === 'no_partner'
            ? 'Your invite is not linked to a partner yet. Please ask your adviser to update the invite so we can email your partner.'
            : code === 'partner_no_email'
              ? 'We do not have an email address on file for your partner. Please ask your adviser to add it.'
              : code === 'no_linked_client'
                ? 'Your account is not yet linked to a fact-find we can use. Please refresh and try again.'
                : `We could not send the reminder (${code}). Please try again or contact your adviser.`;
          next = { kind: 'fail', msg: friendly };
        } else if (j.emailDelivered === false) {
          next = { kind: 'fail', msg: j.emailError || 'The reminder could not be delivered. Please try again or contact your adviser.' };
        } else {
          next = { kind: 'ok', sentTo: j.sentTo || j.partner?.email || partnerEmail || '' };
        }
      }
    } catch (e) {
      next = { kind: 'fail', msg: e.message || 'Could not send the reminder.' };
    } finally {
      setSending(false);
    }
    setModal(next);
  }

  return (
    <>
      <div className="card" style={{ background: 'var(--surface, #f6f7f9)' }}>
        <div className="card-title">How will you handle {partnerName}'s details?<span className="req">*</span></div>
        <div className="goals-sub" style={{ marginBottom: 14 }}>
          You can either fill these in on their behalf, or send them a reminder so they complete their own half via the link they were emailed.
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}
          className="goals-mode-picker">
          <button type="button"
            className={cx('chip goals-mode-chip', partnerCompletion === 'self' && 'on')}
            style={{ flexDirection: 'column', alignItems: 'flex-start', padding: '16px 18px', minHeight: 96, textAlign: 'left', gap: 4 }}
            onClick={() => onPick('self')}>
            <strong style={{ fontSize: 15 }}>I will complete this on behalf of my partner</strong>
            <span style={{ fontSize: 12, color: 'var(--mute)' }}>I have all their details to hand. Answer the questions below for them.</span>
          </button>
          <button type="button"
            className={cx('chip goals-mode-chip', partnerCompletion === 'remind' && 'on')}
            style={{ flexDirection: 'column', alignItems: 'flex-start', padding: '16px 18px', minHeight: 96, textAlign: 'left', gap: 4 }}
            onClick={() => onPick('remind')}>
            <strong style={{ fontSize: 15 }}>Send reminder for my partner to complete</strong>
            <span style={{ fontSize: 12, color: 'var(--mute)' }}>They'll get an email asking them to sign in and fill their half. You can carry on with the other sections.</span>
          </button>
        </div>
        {canRemove && (
          <div style={{ marginTop: 16, paddingTop: 14, borderTop: '1px dashed var(--line, #d9dce3)' }}>
            <div style={{ fontSize: 13, color: 'var(--navy)', fontWeight: 700, marginBottom: 2 }}>
              Don't have a partner, or added one by mistake?
            </div>
            <div style={{ fontSize: 12, color: 'var(--mute)', marginBottom: 10 }}>
              You can remove the partner and complete this fact find on your own. We won't ask for any partner details.
            </div>
            <button type="button"
              onClick={() => setConfirmRemove(true)}
              className="btn btn-ghost btn-sm"
              style={{ borderColor: '#A6412F', color: '#A6412F', fontWeight: 700 }}>
              ✕ Remove partner (I'm completing this on my own)
            </button>
          </div>
        )}
      </div>

      {partnerCompletion === 'remind' && (
        <div className="card" style={{ background: '#F7F5EC', borderColor: '#1B3058' }}>
          <div className="card-title" style={{ color: '#1B3058' }}>
            {partnerName} will complete their own half
          </div>
          <p style={{ margin: '0 0 10px', color: '#4A4A46', fontSize: 14, lineHeight: 1.55 }}>
            We'll skip the partner panel here, and the rest of your questionnaire is unblocked. <strong>You won't be able to submit until {partnerName} has finished their fact-find</strong> - we'll prompt you with a "Send reminder" button when you reach the submit page if they haven't started yet.
          </p>
          {/* Show the partner's listed email so the primary knows
              exactly where the reminder will land before they click. */}
          {partnerEmail ? (
            <div style={{ margin: '0 0 14px', padding: '10px 12px', background: 'var(--white)', border: '1px solid #DDD8C6', borderRadius: 6, fontSize: 13, color: 'var(--navy)' }}>
              <span style={{ color: 'var(--mute)', marginRight: 6 }}>Reminder will be sent to:</span>
              <strong>{partnerEmail}</strong>
            </div>
          ) : (
            <div style={{ margin: '0 0 14px', padding: '10px 12px', background: '#FFF4D1', border: '1px solid #C49A00', borderRadius: 6, fontSize: 13, color: '#7a5b00' }}>
              We don't have an email address on file for {partnerName} yet - ask your adviser to update the invite before sending.
            </div>
          )}
          <button type="button" className="btn btn-primary btn-sm"
            onClick={sendReminder} disabled={sending || !partnerEmail}>
            {sending ? 'Sending…' : `Send ${partnerName} a reminder now →`}
          </button>
        </div>
      )}

      {partnerCompletion === 'self' && children}

      {modal && (
        <div className="ff-modal-backdrop" onClick={() => setModal(null)}>
          <div className="ff-modal" style={{ maxWidth: 460 }} onClick={(e) => e.stopPropagation()}>
            {modal.kind === 'ok' ? (
              <>
                <div className="modal-title">Reminder sent</div>
                <div style={{ color: '#4A4A46', fontSize: 14, lineHeight: 1.55, marginBottom: 14 }}>
                  We've sent {partnerName} an email
                  {modal.sentTo ? <> at <strong>{modal.sentTo}</strong></> : null}
                  {' '}asking them to complete their part of the Fact Find.
                </div>
                <div style={{ color: 'var(--mute)', fontSize: 12, lineHeight: 1.55, marginBottom: 18 }}>
                  You can carry on with the rest of your sections. When you reach the submit page, we'll let you know if they haven't finished yet.
                </div>
              </>
            ) : (
              <>
                <div className="modal-title" style={{ color: '#A6412F' }}>Reminder couldn't be sent</div>
                <div style={{ color: '#4A4A46', fontSize: 14, lineHeight: 1.55, marginBottom: 18 }}>
                  {modal.msg}
                </div>
              </>
            )}
            <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
              <button type="button" className="btn btn-primary"
                onClick={() => setModal(null)}>Got it</button>
            </div>
          </div>
        </div>
      )}

      {confirmRemove && (
        <div className="ff-modal-backdrop" onClick={() => setConfirmRemove(false)}>
          <div className="ff-modal" style={{ maxWidth: 460 }} onClick={(e) => e.stopPropagation()}>
            <div className="modal-title">Remove partner details?</div>
            <div style={{ color: '#4A4A46', fontSize: 14, lineHeight: 1.55, marginBottom: 18 }}>
              We'll hide the partner section and you won't be asked to complete {partnerName}'s details. Any partner information entered here will be cleared. You can add a partner again later if you change your mind.
            </div>
            <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
              <button type="button" className="btn"
                onClick={() => setConfirmRemove(false)}>Cancel</button>
              <button type="button" className="btn btn-primary"
                onClick={() => { setConfirmRemove(false); onRemovePartner && onRemovePartner(); }}>
                Yes, remove
              </button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}

function PersonTabs({ showPartner, activeTab, onTab, onAddPartner, partnerName, primaryName }) {
  return (
    <div className="person-tabs">
      <button type="button" className={cx('ptab', activeTab === 'primary' && 'on')} onClick={() => onTab('primary')}>
        {primaryName || 'Primary applicant'}
      </button>
      {showPartner ? (
        <button type="button" className={cx('ptab', activeTab === 'partner' && 'on')} onClick={() => onTab('partner')}>
          {partnerName || 'Partner / spouse'}
        </button>
      ) : (
        <button type="button" className="ptab ptab-add" onClick={onAddPartner}>
          + Add partner
        </button>
      )}
    </div>
  );
}

function PrimaryPanel({ primary, update, age, sectionUpdate, partner, showPartner, preferredContact }) {
  const titleOpts = ['Mr','Mrs','Ms','Miss','Dr','Mx','Prefer not to say'];
  const primaryDisplayName = [primary.firstName, primary.lastName].filter(Boolean).join(' ').trim() || 'Primary applicant';
  const partnerDisplayName = [partner?.firstName, partner?.lastName].filter(Boolean).join(' ').trim() || 'Partner';
  // Confirmation popup when the client says "No" to "Are you receiving
  // advice as a couple?". Without this it's easy to fat-finger No when
  // they actually do want couple advice - and that silently strips the
  // partner panel + downstream partner-required fields. The popup
  // forces a second click before we commit.
  const [confirmSoloAdvice, setConfirmSoloAdvice] = useState(false);

  return (
    <>
      <div className="card">
        <div className="card-title">Identity</div>
        <div className="grid-2">
          <Field label="Title">
            <Select value={primary.title || ''} onChange={e => update({ title: e.target.value })}>
              <option value="">Select…</option>
              {titleOpts.map(t => <option key={t}>{t}</option>)}
            </Select>
          </Field>
          <Field label="Preferred name">
            <Input value={primary.preferred || ''} onChange={e => update({ preferred: e.target.value })}
              placeholder="What should we call you?" />
          </Field>
          <Field label="Legal first name" required name="p.firstName">
            <Input value={primary.firstName || ''} onChange={e => update({ firstName: e.target.value })} />
          </Field>
          <Field label="Middle name(s)">
            <Input value={primary.middleName || ''} onChange={e => update({ middleName: e.target.value })} />
          </Field>
          <Field label="Legal surname" required span={2} name="p.lastName">
            <Input value={primary.lastName || ''} onChange={e => update({ lastName: e.target.value })} />
          </Field>
          <Field label="Previous name (if applicable)" span={2} name="p.previousName"
            hint="Maiden name or any former legal name. Helps us match records held under a different name.">
            <Input value={primary.previousName || ''} onChange={e => update({ previousName: e.target.value })} />
          </Field>
          <Field label="Date of birth" required name="p.dob">
            <Input type="date" value={primary.dob || ''} onChange={e => update({ dob: e.target.value })} />
          </Field>
          <Field label="Age" hint="Auto-calculated">
            <Input value={age} readOnly placeholder="-" />
          </Field>
          <Field label="Gender" required name="p.gender">
            <Select value={primary.gender || ''} onChange={e => update({ gender: e.target.value })}>
              <option value="">Select…</option>
              {['Male','Female','Non-binary','Prefer not to say'].map(g => <option key={g}>{g}</option>)}
            </Select>
          </Field>
          <Field label="Citizenship" required name="p.citizenship">
            <Select value={primary.citizenship || ''} onChange={e => update({ citizenship: e.target.value, citizenshipOther: e.target.value === 'Other' ? (primary.citizenshipOther || '') : '' })}>
              <option value="">Select…</option>
              {['Australian Citizen','Australian Permanent Resident','New Zealand Citizen','Temporary Visa Holder','Other'].map(o => <option key={o}>{o}</option>)}
            </Select>
            {primary.citizenship === 'Other' && (
              <Input style={{ marginTop: 8 }} required
                value={primary.citizenshipOther || ''}
                onChange={e => update({ citizenshipOther: e.target.value })}
                placeholder="Please describe - e.g. specific visa type, dual citizenship" />
            )}
          </Field>
          {primary.citizenship === 'Temporary Visa Holder' && (
            <Field label="Which visa are you on?" required span={2} name="p.visaType"
              hint="e.g. subclass 482, 485, 500, 820, or a bridging visa.">
              <Input value={primary.visaType || ''} onChange={e => update({ visaType: e.target.value })}
                placeholder="State your visa type or subclass" />
            </Field>
          )}
        </div>
      </div>

      <div className="card">
        <div className="card-title">Contact</div>
        <div className="grid-2">
          <Field label="Mobile" required name="p.mobile">
            <Input type="tel" value={primary.mobile || ''} onChange={e => update({ mobile: e.target.value })}
              placeholder="04XX XXX XXX" />
          </Field>
          <Field label="Home phone">
            <Input type="tel" value={primary.homePhone || ''} onChange={e => update({ homePhone: e.target.value })} />
          </Field>
          <Field label="Email address" required span={2} name="p.email">
            <Input type="email" value={primary.email || ''} onChange={e => update({ email: e.target.value })} />
          </Field>
          <Field label="Residential address" required span={2} name="p.address">
            <AddressInput value={primary.address || ''}
              onChange={e => update({ address: e.target.value, streetNo: '' })}
              onPick={(label, parts) => update({ address: label, addressParts: parts, streetNo: '' })}
              placeholder="Start typing your address - Australian suggestions will appear" />
            <AddressPartsSummary parts={primary.addressParts} />
          </Field>
          {addrNeedsNumber(primary) && (
            <Field label="Street / unit number" required span={2} name="p.streetNo"
              hint="We couldn't detect a street number in that address. Please add it.">
              <Input value={primary.streetNo || ''} onChange={e => update({ streetNo: e.target.value })}
                placeholder="e.g. 12 or 5/120" />
            </Field>
          )}
          <Field label="Postal address" span={2} required={primary.postalSame === false} name="p.postalAddress">
            <div className="chip-group" style={{ marginBottom: 10 }}>
              <button type="button" className={cx('chip', primary.postalSame === true && 'on')}
                onClick={() => update({ postalSame: true })}>Same as residential</button>
              <button type="button" className={cx('chip', primary.postalSame === false && 'on')}
                onClick={() => update({ postalSame: false })}>Different</button>
            </div>
            {primary.postalSame === false && (
              <>
                <AddressInput value={primary.postalAddress || ''}
                  onChange={e => update({ postalAddress: e.target.value })}
                  onPick={(label, parts) => update({ postalAddress: label, postalAddressParts: parts })}
                  placeholder="Postal address" />
                <AddressPartsSummary parts={primary.postalAddressParts} />
              </>
            )}
          </Field>
          {showPartner && (
            <Field label="Who is the preferred contact?" span={2}
              hint="We'll use this person as the main point of contact for your household.">
              <Select value={preferredContact || ''} onChange={e => sectionUpdate({ preferredContact: e.target.value })}>
                <option value="">Select…</option>
                <option value="primary">{primaryDisplayName}</option>
                <option value="partner">{partnerDisplayName}</option>
              </Select>
            </Field>
          )}
        </div>
      </div>

      <div className="card">
        <div className="card-title">Relationship & family</div>
        <Field label="Relationship status" required name="p.relStatus">
          <ChipGroup
            options={['Single','Married','De facto','Separated','Divorced','Widowed']}
            value={primary.relStatus}
            onChange={v => update({ relStatus: v })}
          />
        </Field>

        {primary.relStatus === 'Divorced' && (
          <Field label="Are you financially separated?" required name="p.financiallySeparated"
            hint="i.e. your finances (accounts, assets, liabilities) are fully divided from your former partner.">
            <YesNo value={primary.financiallySeparated}
              onChange={v => update({ financiallySeparated: v })} />
          </Field>
        )}

        {['Married','De facto'].includes(primary.relStatus) && (
          <Field label="Are you receiving advice as a couple?" required name="p.coupleAdvice"
            hint="If yes, we'll collect a few details for your partner. If no, you can complete this on your own.">
            <YesNo
              value={primary.coupleAdvice}
              onChange={(v) => {
                if (v === false) {
                  // Don't commit "No" immediately - confirm with a popup
                  // first so the user explicitly acknowledges that only
                  // they will be receiving advice. The popup commits the
                  // change (and clears the partner panel) once confirmed.
                  setConfirmSoloAdvice(true);
                } else {
                  update({ coupleAdvice: v });
                }
              }}
            />
          </Field>
        )}
        {confirmSoloAdvice && (
          <CoupleAdviceConfirm
            onYes={() => {
              update({ coupleAdvice: false });
              if (sectionUpdate) sectionUpdate({ includePartner: false, activeTab: 'primary' });
              setConfirmSoloAdvice(false);
            }}
            onNo={() => setConfirmSoloAdvice(false)}
          />
        )}
        {['Married','De facto'].includes(primary.relStatus) && primary.coupleAdvice === true && (
          <Callout kind="info">
            A <strong>Partner / spouse</strong> tab has been added up top - we'll need a few details for them too.
          </Callout>
        )}

        <hr className="divider" />

        <Field label="Do you have any dependants?" required name="p.hasDeps">
          <YesNo
            value={primary.hasDeps}
            onChange={v => update({ hasDeps: v, deps: v ? (primary.deps || [{}]) : [] })}
          />
        </Field>

        {primary.hasDeps && (
          <div style={{ marginTop: 14 }}>
            {(primary.deps || []).map((dep, i) => (
              <RepeatItem
                key={i}
                title={`Dependant ${i+1}`}
                onRemove={(primary.deps || []).length > 1 ? () => {
                  const next = [...primary.deps]; next.splice(i,1); update({ deps: next });
                } : null}
              >
                <div className="grid-2">
                  <Field label="Full name" required name={`p.dep${i}.name`}>
                    <Input value={dep.name || ''} onChange={e => {
                      const next = [...primary.deps]; next[i] = { ...dep, name: e.target.value }; update({ deps: next });
                    }} />
                  </Field>
                  <Field label="Relationship" required name={`p.dep${i}.rel`}>
                    <Select value={dep.relationship || ''} onChange={e => {
                      const next = [...primary.deps]; next[i] = { ...dep, relationship: e.target.value, relationshipOther: e.target.value === 'Other' ? (dep.relationshipOther || '') : '' }; update({ deps: next });
                    }}>
                      <option value="">Select…</option>
                      {['Child','Step-child','Grandchild','Parent','Other'].map(o => <option key={o}>{o}</option>)}
                    </Select>
                    {dep.relationship === 'Other' && (
                      <Input style={{ marginTop: 8 }} required
                        value={dep.relationshipOther || ''}
                        onChange={e => {
                          const next = [...primary.deps]; next[i] = { ...dep, relationshipOther: e.target.value }; update({ deps: next });
                        }}
                        placeholder="Please describe the relationship" />
                    )}
                  </Field>
                  <Field label="Date of birth" required name={`p.dep${i}.dob`}>
                    <Input type="date" value={dep.dob || ''} onChange={e => {
                      const next = [...primary.deps]; next[i] = { ...dep, dob: e.target.value }; update({ deps: next });
                    }} />
                  </Field>
                  <Field label="Gender" required name={`p.dep${i}.gender`}>
                    <Select value={dep.gender || ''} onChange={e => {
                      const next = [...primary.deps]; next[i] = { ...dep, gender: e.target.value }; update({ deps: next });
                    }}>
                      <option value="">Select…</option>
                      {['Male','Female','Non-binary','Prefer not to say'].map(g => <option key={g}>{g}</option>)}
                    </Select>
                  </Field>
                  <Field label="Financially dependent until">
                    <Select value={dep.until || ''} onChange={e => {
                      const next = [...primary.deps]; next[i] = { ...dep, until: e.target.value }; update({ deps: next });
                    }}>
                      <option value="">Select…</option>
                      {['Age 18','Age 21','Age 25','Ongoing / Lifelong'].map(o => <option key={o}>{o}</option>)}
                    </Select>
                  </Field>
                </div>
              </RepeatItem>
            ))}
            <AddBtn onClick={() => update({ deps: [...(primary.deps || []), {}] })}>Add another dependant</AddBtn>
          </div>
        )}
      </div>

      <div className="card">
        <div className="card-title">Living situation</div>
        <Field label="Current living situation" required name="p.living">
          <ChipGroup
            options={['Owner - no mortgage','Owner - with mortgage','Renting','Living with family','Other']}
            value={primary.living}
            onChange={v => update({ living: v, livingOther: v === 'Other' ? (primary.livingOther || '') : '' })}
          />
          {primary.living === 'Other' && (
            <Input style={{ marginTop: 10 }} required
              value={primary.livingOther || ''}
              onChange={e => update({ livingOther: e.target.value })}
              placeholder="Please describe - e.g. boarding, share house, defence housing" />
          )}
        </Field>
        <div className="grid-2" style={{ marginTop: 18 }}>
          <Field label="Years at current address">
            <Input type="number" value={primary.yearsAtAddress || ''} onChange={e => update({ yearsAtAddress: e.target.value })} />
          </Field>
          <Field label="Previous suburb / state (if under 3 years)">
            <Input value={primary.prevAddress || ''} onChange={e => update({ prevAddress: e.target.value })} />
          </Field>
        </div>
      </div>

      <div className="card">
        <div className="card-title">Employment</div>
        <Field label="On what basis are you currently working?" required name="p.empBasis">
          <Select value={primary.empBasis || ''} onChange={e => update({ empBasis: e.target.value })}>
            <option value="">Select…</option>
            {['Full-time employee','Part-time employee','Casual employee','Fixed term contract','Self-employed','Business owner','Contractor','Recently made redundant','Retired','Not currently working','Homemaker / Maternity leave'].map(o => <option key={o}>{o}</option>)}
          </Select>
        </Field>

        {primary.empBasis === 'Homemaker / Maternity leave' && (
          <div style={{ marginTop: 14 }}>
            <Field label="Do you intend to return to the workforce?" required name="p.intendReturn">
              <YesNo value={primary.intendReturn} onChange={v => update({ intendReturn: v, ...(v === false ? { returnWhen: '' } : {}) })} />
            </Field>
            {primary.intendReturn === true && (
              <Field label="When do you intend to return to work?" required name="p.returnWhen"
                hint="A rough date or timeframe is fine, e.g. March 2027, or in about 18 months.">
                <Input value={primary.returnWhen || ''} onChange={e => update({ returnWhen: e.target.value })}
                  placeholder="e.g. March 2027" />
              </Field>
            )}
          </div>
        )}

        {(primary.empBasis !== 'Homemaker / Maternity leave' || primary.intendReturn === true) && (
        <>
        <div className="grid-2" style={{ marginTop: 18 }}>
          <Field label="Current occupation / job title" required name="p.occupation">
            <Input value={primary.occupation || ''} onChange={e => update({ occupation: e.target.value })}
              placeholder="e.g. Registered Nurse, Civil Engineer" />
          </Field>
          <Field label="Employer / business name" required name="p.employer">
            <Input value={primary.employer || ''} onChange={e => update({ employer: e.target.value })} />
          </Field>
          <Field label="Industry" required name="p.industry">
            <Input value={primary.industry || ''} onChange={e => update({ industry: e.target.value })}
              placeholder="e.g. Healthcare, Mining, Finance" />
          </Field>
          <Field label="Time in current role" required name="p.tenure">
            <Select value={primary.tenure || ''} onChange={e => update({ tenure: e.target.value })}>
              <option value="">Select…</option>
              {['Less than 1 year','1–2 years','2–5 years','5–10 years','10+ years'].map(o => <option key={o}>{o}</option>)}
            </Select>
          </Field>
          <Field label="Years in this industry" required name="p.industryYears"
            hint="Total time you've worked in this industry, across all employers.">
            <Select value={primary.industryYears || ''} onChange={e => update({ industryYears: e.target.value })}>
              <option value="">Select…</option>
              {['Less than 1 year','1–2 years','2–5 years','5–10 years','10–20 years','20+ years'].map(o => <option key={o}>{o}</option>)}
            </Select>
          </Field>
          <Field label="Do you have any degree or qualifications for your role?" required name="p.hasQualifications">
            <YesNo value={primary.hasQualifications} onChange={v => update({ hasQualifications: v, ...(v === false ? { qualifications: '' } : {}) })} />
          </Field>
          {primary.hasQualifications === true && (
            <Field label="Please state your qualification" span={2} required name="p.qualifications">
              <Input value={primary.qualifications || ''} onChange={e => update({ qualifications: e.target.value })}
                placeholder="e.g. Bachelor of Nursing; CPA; Certificate III in Carpentry" />
            </Field>
          )}
        </div>
        {/* Tenure < 1 year: ask about the previous role for income-protection
            underwriting (insurers require continuity of similar work). */}
        {primary.tenure === 'Less than 1 year' && (
          <div style={{ marginTop: 14 }}>
            <Field label="Was your previous job in a similar role?" required name="p.prevRoleSimilar">
              <YesNo value={primary.prevRoleSimilar} onChange={v => update({
                prevRoleSimilar: v,
                ...(v === true ? { prevRoleDetail: '' } : {}),
              })} />
            </Field>
            {primary.prevRoleSimilar === false && (
              <Field label="What were you doing before this role?" required name="p.prevRoleDetail"
                hint="A short description of your previous role and industry helps the insurer assess continuity.">
                <Textarea rows={2} value={primary.prevRoleDetail || ''} onChange={e => update({ prevRoleDetail: e.target.value })}
                  placeholder="e.g. Customer service in retail for 3 years before moving into nursing." />
              </Field>
            )}
          </div>
        )}

        <hr className="divider" />

        <Field label="Do any of the following apply to your occupation?"
          hint="select all that apply - these may affect income protection and TPD underwriting.">
          <ChipGroup multi
            options={[
              'Trade, construction or industrial work',
              'FIFO / DIDO',
              'Working at heights or in confined spaces',
              'Operating heavy machinery',
              'Driving as part of work duties',
              'Handling hazardous materials',
              'None of the above',
            ]}
            value={primary.occDuties}
            onChange={v => update({ occDuties: v })}
          />
        </Field>
        </>
        )}
      </div>

      <div className="card">
        <div className="card-title">Tax file number</div>
        <div className="grid-2">
          <Field label="Tax file number" required name="p.tfn" hint="Must be 9 digits">
            <TfnInput value={primary.tfn || ''} onChange={e => update({ tfn: e.target.value })}
              placeholder="XXX XXX XXX" />
          </Field>
          <Field label="Tax residency">
            <Select value={primary.taxRes || ''} onChange={e => update({ taxRes: e.target.value })}>
              <option value="">Select…</option>
              {['Australian resident for tax purposes','Foreign resident','Working holiday maker','Unsure - please advise'].map(o => <option key={o}>{o}</option>)}
            </Select>
          </Field>
        </div>
      </div>

      <div className="card">
        <div className="card-title">Estate planning</div>
        <Field
          label={<>Do you have a current will? <InfoIcon tip="A will is a legal document that names an Executor (the person responsible for distributing your estate) and Beneficiaries (the people or charities who inherit). Without a will, your assets are distributed under your state's intestacy laws." /></>}
          required name="p.hasWill">
          <YesNo value={primary.hasWill} onChange={v => update({ hasWill: v })} />
        </Field>
        {primary.hasWill === true && (
          <div className="grid-2" style={{ marginTop: 14 }}>
            <Field label="Year last updated" required name="p.willYear">
              <Input type="number" value={primary.willYear || ''} onChange={e => update({ willYear: e.target.value })}
                placeholder="e.g. 2023" />
            </Field>
            <Field label={<>Includes a testamentary trust? <InfoIcon tip="A testamentary trust is created by your will after you die. A Trustee (named in the will) holds and manages assets on behalf of Beneficiaries - often used to protect inheritances for minor children, manage tax outcomes, or shield assets from divorce or bankruptcy claims." /></>}
              required name="p.willTrust">
              <ChipGroup options={['Yes','No','Unsure']} value={primary.willTrust} onChange={v => update({ willTrust: v })} />
            </Field>
          </div>
        )}
        <hr className="divider" />

        <Field label={<>Enduring power of attorney? <InfoIcon tip="An Enduring Power of Attorney (EPOA) appoints someone (the Attorney) to make financial / legal decisions on your behalf if you lose capacity. It 'endures' beyond loss of capacity, unlike a general POA. Some states also recognise a separate Enduring Guardian for medical / lifestyle decisions." /></>}
          required name="p.epoa">
          <ChipGroup
            options={['Yes','In progress','No']}
            value={primary.epoa}
            onChange={v => update({ epoa: v })}
          />
        </Field>

        <hr className="divider" />

        <Field
          label={<>Super beneficiary nomination <InfoIcon tip="Super doesn't automatically form part of your estate. A Binding nomination directs your fund to pay your benefit to your nominated dependants on death (legally binding for up to 3 years unless non-lapsing). Non-binding is a guide only - the trustee chooses. None means the trustee decides. Reversionary applies for pension accounts." /></>}
          required name="p.superNom"
          hint="Super doesn't automatically form part of your estate.">
          <ChipGroup
            options={['Binding','Non-binding','None','Unsure']}
            value={primary.superNom}
            onChange={v => update({ superNom: v })}
          />
        </Field>
      </div>
    </>
  );
}

function PartnerPanel({ partner, primary, update }) {
  const titleOpts = ['Mr','Mrs','Ms','Miss','Dr','Mx','Prefer not to say'];
  // Use the partner's first name in card titles instead of the word "Partner".
  const pFirst = (partner.preferredName || partner.firstName || '').trim();
  const poss = pFirst ? `${pFirst}'s` : 'Partner';
  const primaryFirst = ((primary && (primary.preferredName || primary.firstName)) || '').trim();
  const primaryAddrName = primaryFirst || 'the primary applicant';
  return (
    <>
      <div className="card">
        <div className="card-title">{`${poss} identity`}</div>
        <div className="grid-2">
          <Field label="Title">
            <Select value={partner.title || ''} onChange={e => update({ title: e.target.value })}>
              <option value="">Select…</option>
              {titleOpts.map(t => <option key={t}>{t}</option>)}
            </Select>
          </Field>
          <Field label="Preferred name">
            <Input value={partner.preferred || ''} onChange={e => update({ preferred: e.target.value })} />
          </Field>
          <Field label="Legal first name" required name="pt.firstName">
            <Input value={partner.firstName || ''} onChange={e => update({ firstName: e.target.value })} />
          </Field>
          <Field label="Middle name(s)">
            <Input value={partner.middleName || ''} onChange={e => update({ middleName: e.target.value })} />
          </Field>
          <Field label="Legal surname" required span={2} name="pt.lastName">
            <Input value={partner.lastName || ''} onChange={e => update({ lastName: e.target.value })} />
          </Field>
          <Field label="Previous name (if applicable)" span={2} name="pt.previousName"
            hint="Maiden name or any former legal name.">
            <Input value={partner.previousName || ''} onChange={e => update({ previousName: e.target.value })} />
          </Field>
          <Field label="Date of birth" required name="pt.dob">
            <Input type="date" value={partner.dob || ''} onChange={e => update({ dob: e.target.value })} />
          </Field>
          <Field label="Gender" required name="pt.gender">
            <Select value={partner.gender || ''} onChange={e => update({ gender: e.target.value })}>
              <option value="">Select…</option>
              {['Male','Female','Non-binary','Prefer not to say'].map(g => <option key={g}>{g}</option>)}
            </Select>
          </Field>
          <Field label="Citizenship" required name="pt.citizenship">
            <Select value={partner.citizenship || ''} onChange={e => update({ citizenship: e.target.value, citizenshipOther: e.target.value === 'Other' ? (partner.citizenshipOther || '') : '' })}>
              <option value="">Select…</option>
              {['Australian Citizen','Australian Permanent Resident','New Zealand Citizen','Temporary Visa Holder','Other'].map(o => <option key={o}>{o}</option>)}
            </Select>
            {partner.citizenship === 'Other' && (
              <Input style={{ marginTop: 8 }} required
                value={partner.citizenshipOther || ''}
                onChange={e => update({ citizenshipOther: e.target.value })}
                placeholder="Please describe - e.g. specific visa type, dual citizenship" />
            )}
          </Field>
          {partner.citizenship === 'Temporary Visa Holder' && (
            <Field label="Which visa is your partner on?" required span={2} name="pt.visaType"
              hint="e.g. subclass 482, 485, 500, 820, or a bridging visa.">
              <Input value={partner.visaType || ''} onChange={e => update({ visaType: e.target.value })}
                placeholder="State the visa type or subclass" />
            </Field>
          )}
        </div>
      </div>

      <div className="card">
        <div className="card-title">{`${poss} contact`}</div>
        <div className="grid-2">
          <Field label="Mobile" required name="pt.mobile">
            <Input type="tel" value={partner.mobile || ''} onChange={e => update({ mobile: e.target.value })}
              placeholder="04XX XXX XXX" />
          </Field>
          <Field label="Home phone">
            <Input type="tel" value={partner.homePhone || ''} onChange={e => update({ homePhone: e.target.value })} />
          </Field>
          <Field label="Email address" required span={2} name="pt.email">
            <Input type="email" value={partner.email || ''} onChange={e => update({ email: e.target.value })} />
          </Field>
          <Field label="Residential address" required span={2} name="pt.address"
            hint="Enter your partner's address (often the same as yours).">
            <label className="invite-toggle" style={{ marginBottom: 10 }}>
              <input type="checkbox" checked={partner.sameAddressAsPrimary === true}
                onChange={e => {
                  if (e.target.checked) {
                    update({
                      sameAddressAsPrimary: true,
                      address: (primary && primary.address) || '',
                      addressParts: (primary && primary.addressParts) || null,
                      streetNo: (primary && primary.streetNo) || '',
                    });
                  } else {
                    update({ sameAddressAsPrimary: false });
                  }
                }} />
              <span>{`Same as ${primaryAddrName}'s address`}</span>
            </label>
            <AddressInput value={partner.address || ''}
              onChange={e => update({ address: e.target.value, streetNo: '', sameAddressAsPrimary: false })}
              onPick={(label, parts) => update({ address: label, addressParts: parts, streetNo: '', sameAddressAsPrimary: false })}
              placeholder="Start typing - Australian suggestions will appear" />
            <AddressPartsSummary parts={partner.addressParts} />
          </Field>
          {addrNeedsNumber(partner) && (
            <Field label="Street / unit number" required span={2} name="pt.streetNo"
              hint="We couldn't detect a street number in that address. Please add it.">
              <Input value={partner.streetNo || ''} onChange={e => update({ streetNo: e.target.value })}
                placeholder="e.g. 12 or 5/120" />
            </Field>
          )}
          <Field label="Postal address" span={2}>
            <div className="chip-group" style={{ marginBottom: 10 }}>
              <button type="button" className={cx('chip', partner.postalSame === true && 'on')}
                onClick={() => update({ postalSame: true })}>Same as residential</button>
              <button type="button" className={cx('chip', partner.postalSame === false && 'on')}
                onClick={() => update({ postalSame: false })}>Different</button>
            </div>
            {partner.postalSame === false && (
              <>
                <AddressInput value={partner.postalAddress || ''}
                  onChange={e => update({ postalAddress: e.target.value })}
                  onPick={(label, parts) => update({ postalAddress: label, postalAddressParts: parts })}
                  placeholder="Partner's postal address" />
                <AddressPartsSummary parts={partner.postalAddressParts} />
              </>
            )}
          </Field>
        </div>
      </div>

      <div className="card">
        <div className="card-title">{`${poss} employment`}</div>
        <Field label="On what basis is your partner currently working?" required name="pt.empBasis">
          <Select value={partner.empBasis || ''} onChange={e => update({ empBasis: e.target.value })}>
            <option value="">Select…</option>
            {['Full-time employee','Part-time employee','Casual employee','Fixed term contract','Self-employed','Business owner','Contractor','Recently made redundant','Retired','Not currently working','Homemaker / Maternity leave'].map(o => <option key={o}>{o}</option>)}
          </Select>
        </Field>
        {partner.empBasis === 'Homemaker / Maternity leave' && (
          <div style={{ marginTop: 14 }}>
            <Field label="Does your partner intend to return to the workforce?" required name="pt.intendReturn">
              <YesNo value={partner.intendReturn} onChange={v => update({ intendReturn: v, ...(v === false ? { returnWhen: '' } : {}) })} />
            </Field>
            {partner.intendReturn === true && (
              <Field label="When do they intend to return to work?" required name="pt.returnWhen"
                hint="A rough date or timeframe is fine.">
                <Input value={partner.returnWhen || ''} onChange={e => update({ returnWhen: e.target.value })}
                  placeholder="e.g. March 2027" />
              </Field>
            )}
          </div>
        )}
        {(partner.empBasis !== 'Homemaker / Maternity leave' || partner.intendReturn === true) && (
        <>
        <div className="grid-2" style={{ marginTop: 18 }}>
          <Field label="Current occupation / job title" required name="pt.occupation"
            hint="Enter 'Homemaker' if not in paid work.">
            <Input value={partner.occupation || ''} onChange={e => update({ occupation: e.target.value })}
              placeholder="e.g. Registered Nurse, Civil Engineer" />
          </Field>
          <Field label="Employer / business name" required name="pt.employer">
            <Input value={partner.employer || ''} onChange={e => update({ employer: e.target.value })} />
          </Field>
          <Field label="Industry" required name="pt.industry">
            <Input value={partner.industry || ''} onChange={e => update({ industry: e.target.value })}
              placeholder="e.g. Healthcare, Mining, Finance, N/A" />
          </Field>
          <Field label="Time in current role" required name="pt.tenure">
            <Select value={partner.tenure || ''} onChange={e => update({ tenure: e.target.value })}>
              <option value="">Select…</option>
              {['Less than 1 year','1–2 years','2–5 years','5–10 years','10+ years','N/A'].map(o => <option key={o}>{o}</option>)}
            </Select>
          </Field>
          <Field label="Years in this industry" required name="pt.industryYears"
            hint="Total time they've worked in this industry, across all employers.">
            <Select value={partner.industryYears || ''} onChange={e => update({ industryYears: e.target.value })}>
              <option value="">Select…</option>
              {['Less than 1 year','1–2 years','2–5 years','5–10 years','10–20 years','20+ years','N/A'].map(o => <option key={o}>{o}</option>)}
            </Select>
          </Field>
          <Field label="Does your partner have any degree or qualifications for their role?" required name="pt.hasQualifications">
            <YesNo value={partner.hasQualifications} onChange={v => update({ hasQualifications: v, ...(v === false ? { qualifications: '' } : {}) })} />
          </Field>
          {partner.hasQualifications === true && (
            <Field label="Please state their qualification" span={2} required name="pt.qualifications">
              <Input value={partner.qualifications || ''} onChange={e => update({ qualifications: e.target.value })}
                placeholder="e.g. Bachelor of Nursing; CPA; Certificate III in Carpentry" />
            </Field>
          )}
        </div>
        {/* Partner tenure < 1 year follow-up. Same continuity-of-work
            question the primary panel asks, so income-protection
            underwriting has a complete history for both partners. */}
        {partner.tenure === 'Less than 1 year' && (
          <div style={{ marginTop: 14 }}>
            <Field label="Was your partner's previous job in a similar role?" required name="pt.prevRoleSimilar">
              <YesNo value={partner.prevRoleSimilar} onChange={v => update({
                prevRoleSimilar: v,
                ...(v === true ? { prevRoleDetail: '' } : {}),
              })} />
            </Field>
            {partner.prevRoleSimilar === false && (
              <Field label="What was your partner doing before this role?" required name="pt.prevRoleDetail"
                hint="A short description helps the insurer assess continuity of work.">
                <Textarea rows={2} value={partner.prevRoleDetail || ''} onChange={e => update({ prevRoleDetail: e.target.value })}
                  placeholder="e.g. Hospitality manager for 5 years before transitioning to construction." />
              </Field>
            )}
          </div>
        )}
        <hr className="divider" />
        <Field label="Do any of the following apply to your partner's occupation?"
          hint="select all that apply - these may affect income protection and TPD underwriting.">
          <ChipGroup multi
            options={[
              'Trade, construction or industrial work',
              'FIFO / DIDO',
              'Working at heights or in confined spaces',
              'Operating heavy machinery',
              'Driving as part of work duties',
              'Handling hazardous materials',
              'None of the above',
            ]}
            value={partner.occDuties}
            onChange={v => update({ occDuties: v })}
          />
        </Field>
        </>
        )}
      </div>

      <div className="card">
        <div className="card-title">{`${poss} tax`}</div>
        <div className="grid-2">
          <Field label="Tax file number" required name="pt.tfn" hint="Must be 9 digits">
            <TfnInput value={partner.tfn || ''} onChange={e => update({ tfn: e.target.value })}
              placeholder="XXX XXX XXX" />
          </Field>
          <Field label="Tax residency">
            <Select value={partner.taxRes || ''} onChange={e => update({ taxRes: e.target.value })}>
              <option value="">Select…</option>
              {['Australian resident for tax purposes','Foreign resident','Working holiday maker','Unsure - please advise'].map(o => <option key={o}>{o}</option>)}
            </Select>
          </Field>
        </div>
      </div>

      <div className="card">
        <div className="card-title">{`${poss} estate planning`}</div>
        <Field
          label={<>Does your partner have a current will? <InfoIcon tip="A will is a legal document that names an Executor (the person responsible for distributing the estate) and Beneficiaries (the people who inherit). Without a will, assets are distributed under state intestacy laws." /></>}
          required name="pt.hasWill">
          <YesNo value={partner.hasWill} onChange={v => update({ hasWill: v })} />
        </Field>
        {partner.hasWill === true && (
          <div className="grid-2" style={{ marginTop: 14 }}>
            <Field label="Year last updated">
              <Input type="number" value={partner.willYear || ''} onChange={e => update({ willYear: e.target.value })}
                placeholder="e.g. 2023" />
            </Field>
            <Field label={<>Includes a testamentary trust? <InfoIcon tip="A testamentary trust is created by a will after death. A Trustee manages assets on behalf of Beneficiaries - useful for protecting inheritances for minor children, managing tax, or shielding assets from divorce or bankruptcy." /></>}
              required name="pt.willTrust">
              <ChipGroup options={['Yes','No','Unsure']} value={partner.willTrust} onChange={v => update({ willTrust: v })} />
            </Field>
          </div>
        )}
        <hr className="divider" />
        <Field label={<>Enduring power of attorney? <InfoIcon tip="An Enduring Power of Attorney (EPOA) appoints someone (the Attorney) to make financial / legal decisions on your partner's behalf if they lose capacity. Some states use a separate Enduring Guardian for medical / lifestyle decisions." /></>}
          required name="pt.epoa">
          <ChipGroup options={['Yes','In progress','No']} value={partner.epoa} onChange={v => update({ epoa: v })} />
        </Field>
        <hr className="divider" />
        <Field
          label={<>Super beneficiary nomination <InfoIcon tip="Super doesn't automatically form part of your partner's estate. Binding = legally directs the fund (up to 3 years). Non-binding = guide only, the trustee decides. None = trustee decides. Reversionary applies to pension accounts." /></>}
          required name="pt.superNom"
          hint="Super doesn't automatically form part of your estate.">
          <ChipGroup options={['Binding','Non-binding','None','Unsure']} value={partner.superNom} onChange={v => update({ superNom: v })} />
        </Field>
      </div>
    </>
  );
}

// Couple-advice "No" confirmation modal. Uses the same .ff-modal-* classes
// the insurance section's ConfirmDialog uses for visual consistency.
// Inline confirmation strip that appears under an AddressInput once
// the user picks a suggestion. Surfaces the 5 components the
// autofiller captured (street number, street, suburb, state,
// postcode) so the client can verify the typeahead got it right and
// the adviser can see structured data in the export rather than a
// single mashed string.
function AddressPartsSummary({ parts }) {
  if (!parts) return null;
  const has = parts.streetNumber || parts.streetName || parts.suburb || parts.state || parts.postcode;
  if (!has) return null;
  const rows = [
    { k: 'Street number', v: parts.streetNumber },
    { k: 'Street',        v: parts.streetName  },
    { k: 'Suburb',        v: parts.suburb      },
    // City is shown only when distinct from suburb (e.g. Perth for a
    // Greenwood address). Australian residential addressing keeps the
    // suburb in the address line; city is informational only.
    ...(parts.city ? [{ k: 'City',           v: parts.city     }] : []),
    { k: 'State',         v: parts.state       },
    { k: 'Postcode',      v: parts.postcode    },
  ];
  return (
    <div style={{
      marginTop: 8,
      padding: '10px 12px',
      background: '#F7F5EC',
      border: '1px solid #DDD8C6',
      borderRadius: 6,
      fontSize: 12,
      color: 'var(--navy)',
    }}>
      <div style={{ fontSize: 10, fontWeight: 800, letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--mute)', marginBottom: 6 }}>
        Captured from your selection
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))', gap: '6px 14px' }}>
        {rows.map(r => (
          <div key={r.k}>
            <div style={{ color: 'var(--mute)', fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.04em' }}>{r.k}</div>
            <div style={{ fontWeight: 700 }}>{r.v || <span style={{ color: '#A6412F', fontWeight: 600 }}>(not detected)</span>}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function CoupleAdviceConfirm({ onYes, onNo }) {
  useEffect(() => {
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => { if (e.key === 'Escape') onNo(); };
    document.addEventListener('keydown', onKey);
    return () => {
      document.body.style.overflow = prev;
      document.removeEventListener('keydown', onKey);
    };
  }, [onNo]);
  return (
    <div className="ff-modal-backdrop" onClick={onNo}>
      <div className="ff-modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 460 }}>
        <button type="button" className="ff-modal-close" onClick={onNo} aria-label="Close">×</button>
        <div className="modal-title">Solo advice?</div>
        <p className="modal-body">
          Confirming that only you are receiving financial advice. Your partner's
          details and questionnaires won't be collected. Is this correct?
        </p>
        <div className="modal-actions">
          <button type="button" className="btn-secondary" onClick={onNo}>No, go back</button>
          <button type="button" className="btn-primary" onClick={onYes}>Yes, just me</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { SectionPersonal });
