// ─────────────────────────────────────────────────────────────
// Section 2 - Assets & Liabilities
// ─────────────────────────────────────────────────────────────

// Common Australian super funds. The client can pick from the dropdown
// or type their own (the underlying input is a regular text input
// backed by a native <datalist>, so free-text always works). Kept
// alphabetical for quick scanning.
const AU_SUPER_FUNDS = [
  'Active Super',
  'AMP Super',
  'Aware Super',
  'Australian Catholic Superannuation (ACS)',
  'AustralianSuper',
  'AvSuper',
  'BT Super',
  'BUSSQ',
  'Care Super',
  'Cbus',
  'CFS (Colonial First State)',
  'Christian Super (now Australian Ethical)',
  'EISS Super',
  'EquipSuper',
  'ESSSuper',
  'First Super',
  'GESB',
  'Hostplus',
  'HESTA',
  'HUB24',
  'IOOF (now Insignia)',
  'legalsuper',
  'LUCRF (now AustralianSuper)',
  'MLC Super',
  'Maritime Super',
  'Mercer Super',
  'Mine Super',
  'NGS Super',
  'Netwealth',
  'OnePath',
  'Plum Super',
  'Prime Super',
  'Qantas Super',
  'QSuper (now Australian Retirement Trust)',
  'REI Super',
  'Rest Super',
  'Russell Investments Master Trust',
  'Smartsave',
  'Spirit Super',
  'Statewide Super',
  'Suncorp Super',
  'SuperSA',
  'TelstraSuper',
  'TWUSUPER',
  'UniSuper',
  'Vanguard Super',
  'Verve Super',
  'Vision Super',
  'WA Super',
  // SMSF catch-all so trustees can pick the right concept without
  // typing.
  'Self-managed super fund (SMSF)',
];

// Common Australian banks and ADIs. Same pattern as super funds -
// dropdown for quick pick, free-text fallback for anything missing.
const AU_BANKS = [
  'AMP Bank',
  'ANZ',
  'Australian Military Bank',
  'Australian Unity Bank',
  'Bank Australia',
  'Bank First',
  'Bank of Melbourne',
  'Bank of Queensland (BOQ)',
  'Bank of Sydney',
  'BankSA',
  'BankVic',
  'Bankwest',
  'Bendigo Bank',
  'Beyond Bank',
  'Citi Australia',
  'Commonwealth Bank (CBA)',
  'Community First Bank',
  'Defence Bank',
  'Endeavour Mutual Bank',
  'Family First Credit Union',
  'Firefighters Mutual Bank',
  'G&C Mutual Bank',
  'Gateway Bank',
  'Great Southern Bank',
  'Greater Bank',
  'Heritage Bank',
  'HSBC Australia',
  'Hume Bank',
  'IMB Bank',
  'ING Australia',
  'Judo Bank',
  'Macquarie Bank',
  'ME Bank',
  'MyState Bank',
  'NAB',
  'Newcastle Permanent',
  'P&N Bank',
  'People\'s Choice Credit Union',
  'Police Bank',
  'Qudos Bank',
  'RACQ Bank',
  'Rabobank Australia',
  'Regional Australia Bank',
  'St.George Bank',
  'Suncorp Bank',
  'Teachers Mutual Bank',
  'Tyro',
  'UBank',
  'Up',
  'Westpac',
];

// Common AU credit-card issuers + Buy-Now-Pay-Later providers for the
// "Provider" typeahead on credit facilities. Free text is still accepted.
const AU_CARD_PROVIDERS = [
  'AMEX (American Express)',
  'ANZ',
  'Afterpay',
  'Bankwest',
  'Bendigo Bank',
  'Citi',
  'Coles Mastercard',
  'CommBank (CBA)',
  'Humm',
  'Klarna',
  'Latitude',
  'Macquarie',
  'NAB',
  'Qantas Money',
  'St.George Bank',
  'Suncorp Bank',
  'Virgin Money',
  'Westpac',
  'Woolworths Money',
  'Zip Pay / Zip Money',
];

function SectionAssets({ data, set }) {
  const d = data.assets || {};
  // Low property-value confirmation prompt. A property under $100k is
  // almost always a typo (e.g. $50 instead of $500,000), so ask the client
  // to confirm the figure when they leave the field. { idx, value } | null.
  const [valuePrompt, setValuePrompt] = React.useState(null);
  // Functional setState so multiple updates in the same handler don't
  // overwrite each other (same pattern as SectionPersonal).
  const update = (patch) => set(prev => {
    const prevAssets = prev.assets || {};
    return { ...prev, assets: { ...prevAssets, ...patch } };
  });

  const listUpdate = (key, idx, patch) => set(prev => {
    const prevAssets = prev.assets || {};
    const arr = [...(prevAssets[key] || [])];
    arr[idx] = { ...arr[idx], ...patch };
    return { ...prev, assets: { ...prevAssets, [key]: arr } };
  });
  const listAdd = (key, init = {}) => set(prev => {
    const prevAssets = prev.assets || {};
    return { ...prev, assets: { ...prevAssets, [key]: [...(prevAssets[key] || []), init] } };
  });
  const listRemove = (key, idx) => set(prev => {
    const prevAssets = prev.assets || {};
    const arr = [...(prevAssets[key] || [])];
    arr.splice(idx, 1);
    return { ...prev, assets: { ...prevAssets, [key]: arr } };
  });

  // One-time migration: vehicles used to be a single "total value" scalar
  // (assets.vehicles). It's now a per-vehicle list (assets.vehiclesList with
  // {value, owner}). Seed the list from the legacy scalar so existing drafts
  // keep their number (owner left blank for the client to pick).
  React.useEffect(() => {
    const a = data.assets || {};
    if ((!Array.isArray(a.vehiclesList) || a.vehiclesList.length === 0) && a.vehicles && a.vehiclesNone !== true) {
      update({ vehiclesList: [{ value: a.vehicles, owner: '' }], vehicles: '' });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Whether a partner is part of this advice. Single clients shouldn't
  // see "Partner" as an ownership option anywhere in this section -
  // rendering it would only invite mis-keys. Joint stays available
  // because joint ownership can exist with a non-partner co-owner
  // (e.g. a sibling on a property title).
  const personalD = data?.personal || {};
  const primaryP = personalD.primary || {};
  const partnerActive =
    (['Married', 'De facto'].includes(primaryP.relStatus) && primaryP.coupleAdvice === true)
    || personalD.includePartner === true;
  // Owner pickers show the clients' actual names. The stored VALUE stays
  // 'Primary' / 'Partner' so downstream attribution (per-property tax
  // lines, cashflow modelling) and existing saved data are unaffected -
  // only the visible label changes.
  const primaryName = [primaryP.firstName, primaryP.lastName].filter(Boolean).join(' ').trim() || 'Primary';
  const partnerP = personalD.partner || {};
  const partnerName = [partnerP.firstName, partnerP.lastName].filter(Boolean).join(' ').trim() || 'Partner';
  const primaryOpt = <option value="Primary">{primaryName}</option>;
  const partnerOpt = partnerActive ? <option value="Partner">{partnerName}</option> : null;

  // Pull the primary applicant's home address so we can offer it as a
  // one-click prefill on real-estate rows. The user can still type a
  // different address - the prefill is just a shortcut.
  const primaryHomeAddress = data?.personal?.primary?.address || '';
  const livesAtOwnHome = (() => {
    const living = data?.personal?.primary?.living || '';
    // Match common "owns" labels from the living-situation chips.
    return /own|owner|mortgage/i.test(living);
  })();
  const showHomeAddressQuickfill = primaryHomeAddress && livesAtOwnHome;

  // Build the list of offset cash accounts for the "Linked offset" loan
  // dropdown. Each option carries a stable id (the account's index) so
  // the loan can persist the reference even if the bank name changes.
  const offsetAccounts = (d.savings || [])
    .map((s, i) => ({ id: `savings-${i}`, label: s.bank ? `${s.bank} - Offset` : `Offset account ${i + 1}` , type: s.type }))
    .filter(s => s.type === 'Offset');

  return (
    <div className="section-body">
      <div className="card" data-ff-name="as.partnerSuper">
        <div className="card-title">Superannuation</div>
        {(d.supers || []).map((s, i) => (
          <RepeatItem key={i} title={`Super fund ${i+1}`}
            onRemove={() => listRemove('supers', i)}>
            <div className="grid-2">
              <Field label="Fund name" required name={`as.super${i}.fund`}
                hint="Pick from the list or type your own if it's not there.">
                <Input list="au-super-funds" value={s.fund || ''}
                  onChange={e => listUpdate('supers', i, { fund: e.target.value })}
                  placeholder="e.g. AustralianSuper" />
              </Field>
              <Field label="Member number" required name={`as.super${i}.member`}>
                <Input value={s.member || ''} onChange={e => listUpdate('supers', i, { member: e.target.value })} />
              </Field>
              <Field label="Balance ($)" required name={`as.super${i}.balance`}>
                <MoneyInput value={s.balance || ''} onChange={e => listUpdate('supers', i, { balance: e.target.value })} />
              </Field>
              <Field label="Owner" required name={`as.super${i}.owner`}>
                <Select value={s.owner || ''} onChange={e => listUpdate('supers', i, { owner: e.target.value })}>
                  <option value="">Select…</option>
                  {/* Super is always individually owned in Australia - no
                      joint super accounts exist - so Joint has been
                      dropped from this picker. */}
                  {primaryOpt}{partnerOpt}
                </Select>
              </Field>
              <Field label="Insurance inside super?" required name={`as.super${i}.hasInsurance`}>
                <ChipGroup
                  options={['Yes','No','Unsure']}
                  value={s.hasInsurance === true ? 'Yes' : s.hasInsurance === false ? 'No' : s.hasInsurance === 'Unsure' ? 'Unsure' : ''}
                  onChange={v => listUpdate('supers', i, {
                    hasInsurance: v === 'Yes' ? true : v === 'No' ? false : v === 'Unsure' ? 'Unsure' : null
                  })} />
              </Field>
              <Field label="Investment option">
                <Input value={s.option || ''} onChange={e => listUpdate('supers', i, { option: e.target.value })}
                  placeholder="e.g. Balanced, High Growth" />
              </Field>
              <Field label={<>Is this superannuation fund a defined benefit? <InfoIcon tip="A defined benefit fund pays a retirement benefit based on a formula (e.g. years of service and final salary) rather than the account balance. They're most common in older public-sector and some corporate funds." /></>}>
                <ChipGroup options={['Yes','No','Unsure']}
                  value={s.definedBenefit || ''}
                  onChange={v => listUpdate('supers', i, { definedBenefit: v })} />
              </Field>
            </div>
          </RepeatItem>
        ))}
        {/* Couple advice: prompt for the partner's super too. Validation
            requires at least one partner-owned super OR the explicit
            "no super" opt-out below, so a partner who genuinely has none
            (e.g. homemaker) isn't blocked. Same none-toggle pattern as
            Real estate / Cash & savings. */}
        {partnerActive && !(d.supers || []).some(s => s.owner === 'Partner') && (
          <>
            {!d.partnerSuperNone && (
              <Callout kind="info">
                You're receiving advice as a couple, so please also add {partnerName}'s superannuation details below, or confirm they have none.
              </Callout>
            )}
            <label className="invite-toggle" style={{ marginTop: 12, marginBottom: 4 }}>
              <input type="checkbox" checked={d.partnerSuperNone === true}
                onChange={e => update({ partnerSuperNone: e.target.checked })} />
              <span>{partnerName} has no superannuation.</span>
              <span className="invite-toggle-hint">Tick this if your partner doesn't have any super.</span>
            </label>
          </>
        )}
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, marginTop: 12 }}>
          <AddBtn onClick={() => listAdd('supers')}>Add super fund</AddBtn>
          {partnerActive && (
            <AddBtn onClick={() => set(prev => {
              const pa = prev.assets || {};
              // Pre-set the owner to the partner and clear the "no super"
              // opt-out so the two can't contradict each other.
              return { ...prev, assets: { ...pa, partnerSuperNone: false, supers: [...(pa.supers || []), { owner: 'Partner' }] } };
            })}>Add {partnerName}'s super fund</AddBtn>
          )}
        </div>
      </div>

      <div className="card" data-ff-name="as.properties">
        <div className="card-title">Real estate</div>
        {/* None-toggle: validation requires either at least one property OR
            this box ticked, so "no property" is an explicit answer rather
            than an empty section. Same pattern as Cash & savings below. */}
        <label className="invite-toggle" style={{ marginBottom: 14 }}>
          <input type="checkbox" checked={d.propertiesNone === true}
            onChange={e => update({
              propertiesNone: e.target.checked,
              ...(e.target.checked ? { properties: [] } : {}),
            })} />
          <span>I don't own any property.</span>
          <span className="invite-toggle-hint">Tick this if you don't own any real estate.</span>
        </label>
        {!d.propertiesNone && (<>
        {(d.properties || []).map((p, i) => (
          <RepeatItem key={i} title={`Property ${i+1}`}
            onRemove={() => listRemove('properties', i)}>
            <div className="grid-2">
              <Field label="Address" span={2} required name={`as.prop${i}.address`}
                hint={showHomeAddressQuickfill
                  ? "Tip - your home address is filled in by default. Edit if this is a different property."
                  : null}>
                <AddressInput value={p.address || ''} onChange={e => listUpdate('properties', i, { address: e.target.value })}
                  placeholder="Start typing - Australian suggestions will appear" />
                {showHomeAddressQuickfill && p.address !== primaryHomeAddress && (
                  <button type="button"
                    className="add-btn"
                    style={{ marginTop: 8, fontSize: 12, padding: '8px 12px' }}
                    onClick={() => listUpdate('properties', i, { address: primaryHomeAddress })}>
                    <span className="add-btn-plus">↻</span>Use my home address ({primaryHomeAddress})
                  </button>
                )}
              </Field>
              <Field label="Use" required name={`as.prop${i}.use`}>
                <Select value={p.use || ''} onChange={e => listUpdate('properties', i, { use: e.target.value })}>
                  <option value="">Select…</option>
                  <option>Primary residence</option><option>Investment</option><option>Holiday home</option>
                </Select>
              </Field>
              <Field label="Ownership" required name={`as.prop${i}.ownership`}>
                <Select value={p.ownership || ''} onChange={e => listUpdate('properties', i, { ownership: e.target.value })}>
                  <option value="">Select…</option>
                  {primaryOpt}{partnerOpt}<option>Joint</option><option>Trust / Company</option>
                </Select>
              </Field>
              <Field label="Estimated value ($)" required name={`as.prop${i}.value`}>
                <div onBlur={() => { const n = Number(p.value); if (n > 0 && n < 100000 && !p.valueConfirmed) setValuePrompt({ idx: i, value: n }); }}>
                  <MoneyInput value={p.value || ''} onChange={e => listUpdate('properties', i, { value: e.target.value, valueConfirmed: false })} />
                </div>
              </Field>
              <Field label="Purchase price ($)" required name={`as.prop${i}.purchase`}>
                <MoneyInput value={p.purchase || ''} onChange={e => listUpdate('properties', i, { purchase: e.target.value })} />
              </Field>
              <Field label="Year acquired" required name={`as.prop${i}.yearAcquired`}>
                <Input type="number" value={p.yearAcquired || ''} onChange={e => listUpdate('properties', i, { yearAcquired: e.target.value })} placeholder="e.g. 2019" />
              </Field>
              <Field label="Has a loan against it?" required name={`as.prop${i}.hasLoan`}
                hint={p.hasLoan === true
                  ? "We've added a loan in the \"Home & investment loans\" section below - please complete its details there."
                  : null}>
                <YesNo value={p.hasLoan} onChange={v => set(prev => {
                  // Answering Yes auto-creates a linked loan row in the
                  // Loans card below (pre-set to the right purpose) so
                  // the client is walked straight into providing the
                  // loan details rather than having to find the card
                  // themselves. One functional update covers both keys
                  // so rapid clicks can't race.
                  const pa = prev.assets || {};
                  const props = [...(pa.properties || [])];
                  props[i] = { ...props[i], hasLoan: v };
                  let loans = pa.loans || [];
                  if (v === true && !loans.some(ln => ln && ln.forProperty === i)) {
                    const purpose = props[i].use === 'Investment'
                      ? 'Investment property'
                      : 'Home - owner occupied';
                    loans = [...loans, { forProperty: i, purpose }];
                  }
                  return { ...prev, assets: { ...pa, properties: props, loans } };
                })} />
              </Field>
            </div>
          </RepeatItem>
        ))}
        <AddBtn onClick={() => listAdd('properties',
          // Pre-fill the first property's address with the home address if the
          // client lives in a home they own - saves them retyping it.
          showHomeAddressQuickfill && (d.properties || []).length === 0
            ? { address: primaryHomeAddress, use: 'Primary residence' }
            : {}
        )}>Add property</AddBtn>
        </>)}
      </div>

      <div className="card" data-ff-name="as.savings">
        <div className="card-title">Cash & savings</div>
        {/* None-toggle: required by validation that either at least one
            account is added OR the client confirms none. Same UX pattern
            as the medical-history banner so it's familiar. */}
        <label className="invite-toggle" style={{ marginBottom: 14 }}>
          <input type="checkbox" checked={d.savingsNone === true}
            onChange={e => update({
              savingsNone: e.target.checked,
              // Don't blow away rows on tick - just hide them. Untick to
              // bring them back. This mirrors how the conditions banner
              // retains conditions when None is ticked.
              ...(e.target.checked ? { savings: [] } : {}),
            })} />
          <span>I have no cash or savings accounts.</span>
          <span className="invite-toggle-hint">Tick this box if you have no savings.</span>
        </label>
        {!d.savingsNone && (
          <>
            {(d.savings || []).map((s, i) => (
              <RepeatItem key={i} title={`Account ${i+1}`} onRemove={() => listRemove('savings', i)}>
                <div className="grid-2">
                  <Field label="Bank / institution" required name={`as.cash${i}.bank`}
                    hint="Pick from the list or type your own if it's not there.">
                    <Input list="au-banks" value={s.bank || ''}
                      onChange={e => listUpdate('savings', i, { bank: e.target.value })} />
                  </Field>
                  <Field label="Account type" required name={`as.cash${i}.type`}
                    hint={s.type === 'Offset'
                      ? "Heads up - when you add a loan below, you'll be able to link this offset account to it."
                      : null}>
                    <Select value={s.type || ''} onChange={e => listUpdate('savings', i, { type: e.target.value })}>
                      <option value="">Select…</option>
                      <option>Transaction</option><option>Savings</option><option>Term deposit</option><option>Offset</option><option>Redraw</option>
                    </Select>
                  </Field>
                  <Field label="Balance ($)" required name={`as.cash${i}.balance`}>
                    <MoneyInput value={s.balance || ''} onChange={e => listUpdate('savings', i, { balance: e.target.value })} />
                  </Field>
                  <Field label="Ownership" required name={`as.cash${i}.ownership`}>
                    <Select value={s.ownership || ''} onChange={e => listUpdate('savings', i, { ownership: e.target.value })}>
                      <option value="">Select…</option>
                      <option>Sole owner</option><option>Joint</option>
                    </Select>
                  </Field>
                  <Field label="Interest rate (%)">
                    <PercentInput value={s.rate || ''} onChange={e => listUpdate('savings', i, { rate: e.target.value })} />
                  </Field>
                  {/* Optional - lets the client tell us what the account is FOR
                      (emergency fund, house deposit, tax set-aside) or the
                      nickname they use for it. Not validated. */}
                  <Field label="Does this account have a specific purpose or name?"
                    name={`as.cash${i}.purpose`}
                    hint="Optional - e.g. Emergency fund, House deposit, Tax savings.">
                    <Input value={s.purpose || ''}
                      onChange={e => listUpdate('savings', i, { purpose: e.target.value })}
                      placeholder="e.g. Emergency fund" />
                  </Field>
                </div>
              </RepeatItem>
            ))}
            <AddBtn onClick={() => listAdd('savings')}>Add account</AddBtn>
          </>
        )}
      </div>

      <div className="card" data-ff-name="as.investments">
        <div className="card-title">Investments</div>
        <label className="invite-toggle" style={{ marginBottom: 14 }}>
          <input type="checkbox" checked={d.investmentsNone === true}
            onChange={e => update({
              investmentsNone: e.target.checked,
              ...(e.target.checked ? { investments: [] } : {}),
            })} />
          <span>I have no investments.</span>
          <span className="invite-toggle-hint">Tick this box if you have no existing investments.</span>
        </label>
        {!d.investmentsNone && (
          <>
        {(d.investments || []).map((inv, i) => (
          <RepeatItem key={i} title={`Investment ${i+1}`} onRemove={() => listRemove('investments', i)}>
            <div className="grid-2">
              <Field label="Type" required name={`as.inv${i}.type`}>
                <Select value={inv.type || ''} onChange={e => listUpdate('investments', i, { type: e.target.value, typeOther: e.target.value === 'Other' ? (inv.typeOther || '') : '' })}>
                  <option value="">Select…</option>
                  <option>Shares</option><option>ETFs</option><option>Managed fund</option><option>Crypto</option><option>Investment bond</option><option>Funeral bond</option><option>Private equity</option><option>Other</option>
                </Select>
                {inv.type === 'Other' && (
                  <Field label="Please specify" required name={`as.inv${i}.typeOther`}>
                    <Input style={{ marginTop: 8 }} required
                      value={inv.typeOther || ''}
                      onChange={e => listUpdate('investments', i, { typeOther: e.target.value })}
                      placeholder="Please describe - e.g. unlisted property, art, derivatives" />
                  </Field>
                )}
              </Field>
              {/* For "Other" the typeOther description already covers
                  what the holding is, so the separate holding field
                  drops its required flag. */}
              <Field label="Holding / description" required={inv.type !== 'Other'} name={`as.inv${i}.holding`}>
                <Input value={inv.holding || ''} onChange={e => listUpdate('investments', i, { holding: e.target.value })}
                  placeholder="e.g. VAS, VGS" />
              </Field>
              {['Shares','ETFs','Managed fund','Crypto'].includes(inv.type) && (
                <Field label="What platform is it held on?" required name={`as.inv${i}.platform`}
                  hint="The broker, fund manager, app or exchange where it's held.">
                  <Select value={inv.platform || ''} onChange={e => listUpdate('investments', i, { platform: e.target.value, platformOther: e.target.value === 'Other' ? (inv.platformOther || '') : '' })}>
                    <option value="">Select…</option>
                    {['CommSec','CommSec Pocket','Stake','SelfWealth','Pearler','CMC Markets','nabtrade','Vanguard (Personal Investor)','Raiz','Sharesies','Superhero','Westpac Share Trading','ANZ Share Investing','Interactive Brokers','BetaShares Direct','CoinSpot','Swyftx','Binance','Coinbase','Other'].map(o => <option key={o}>{o}</option>)}
                  </Select>
                  {inv.platform === 'Other' && (
                    <Field label="Platform name" required name={`as.inv${i}.platformOther`}>
                      <Input style={{ marginTop: 8 }} required
                        value={inv.platformOther || ''}
                        onChange={e => listUpdate('investments', i, { platformOther: e.target.value })}
                        placeholder="Name the platform / broker / wallet" />
                    </Field>
                  )}
                </Field>
              )}
              {['Shares','ETFs','Managed fund','Crypto'].includes(inv.type) && (
                <Field label="Units held" hint="Optional - number of units / shares / coins held, if known.">
                  <Input value={inv.units || ''} onChange={e => listUpdate('investments', i, { units: e.target.value })}
                    placeholder="e.g. 1,250" />
                </Field>
              )}
              <Field label="Current value ($)" required name={`as.inv${i}.value`}>
                <MoneyInput value={inv.value || ''} onChange={e => listUpdate('investments', i, { value: e.target.value })} />
              </Field>
              <Field label="Owner" required name={`as.inv${i}.owner`}>
                <Select value={inv.owner || ''} onChange={e => listUpdate('investments', i, { owner: e.target.value })}>
                  <option value="">Select…</option>
                  {primaryOpt}{partnerOpt}<option>Joint</option><option>Trust / Company</option>
                </Select>
              </Field>
            </div>
          </RepeatItem>
        ))}
        <AddBtn onClick={() => listAdd('investments')}>Add investment</AddBtn>
          </>
        )}
      </div>

      <div className="card">
        <div className="card-title">Personal assets</div>
        {/* Vehicles - one row per vehicle (value + owner), or "no vehicles". */}
        <div className="sub-heading">Vehicles</div>
        <label className="invite-toggle" style={{ marginBottom: 10 }}>
          <input type="checkbox" checked={d.vehiclesNone === true}
            onChange={e => update({ vehiclesNone: e.target.checked, ...(e.target.checked ? { vehiclesList: [] } : {}) })} />
          <span>I have no vehicles.</span>
        </label>
        {!d.vehiclesNone && (
          <>
            {(d.vehiclesList || []).map((v, i) => (
              <RepeatItem key={i} title={`Vehicle ${i + 1}`} onRemove={() => listRemove('vehiclesList', i)}>
                <div className="grid-2">
                  <Field label="Value ($)" required name={`as.veh${i}.value`}>
                    <MoneyInput value={v.value || ''} onChange={e => listUpdate('vehiclesList', i, { value: e.target.value })} />
                  </Field>
                  <Field label="Owner" required name={`as.veh${i}.owner`}>
                    <Select value={v.owner || ''} onChange={e => listUpdate('vehiclesList', i, { owner: e.target.value })}>
                      <option value="">Select…</option>
                      {primaryOpt}{partnerOpt}<option>Joint</option>
                    </Select>
                  </Field>
                </div>
              </RepeatItem>
            ))}
            <AddBtn onClick={() => listAdd('vehiclesList')}>Add vehicle</AddBtn>
          </>
        )}
        <hr className="divider" />
        <div className="grid-2">
          <Field label="Home contents ($)" required name="as.contents">
            <MoneyInput value={d.contents || ''} onChange={e => update({ contents: e.target.value })} />
          </Field>
          <Field label="Jewellery / collectables ($)" required name="as.jewellery">
            <MoneyInput value={d.jewellery || ''} onChange={e => update({ jewellery: e.target.value })} />
          </Field>
          <Field label="Other personal assets ($)" hint="Optional - anything not captured above.">
            <MoneyInput value={d.otherAssets || ''} onChange={e => update({ otherAssets: e.target.value })} />
          </Field>
        </div>
      </div>

      {/* data-ff-name anchors so the error banner's "missing home loan"
          link lands on this card (validator emits name='as.loans.homeloan').
          Without this the fuzzy-label fallback used to drop the user on
          the ATO debt question because of token overlap on "loan". */}
      <div className="card" data-ff-name="as.loans" id="as-loans-card">
        <div className="card-title" data-ff-name="as.loans.homeloan">Home & investment loans</div>
        {(d.loans || []).map((ln, i) => (
          <RepeatItem key={i} title={`Loan ${i+1}`} onRemove={() => listRemove('loans', i)}>
            <div className="grid-2">
              <Field label="Lender" required name={`as.loan${i}.lender`}
                hint="Pick from the list or type your own if it's not there.">
                <Input list="au-banks" value={ln.lender || ''}
                  onChange={e => listUpdate('loans', i, { lender: e.target.value })} />
              </Field>
              <Field label="Owner" required name={`as.loan${i}.owner`}>
                <Select value={ln.owner || ''} onChange={e => listUpdate('loans', i, { owner: e.target.value })}>
                  <option value="">Select…</option>
                  {primaryOpt}{partnerOpt}<option>Joint</option>
                </Select>
              </Field>
              <Field label="Loan purpose" required name={`as.loan${i}.purpose`}>
                <Select value={ln.purpose || ''} onChange={e => listUpdate('loans', i, { purpose: e.target.value })}>
                  <option value="">Select…</option>
                  <option>Home - owner occupied</option><option>Investment property</option><option>Personal</option><option>Margin loan</option><option>Novated lease</option>
                </Select>
              </Field>
              <Field label="Balance remaining ($)" required name={`as.loan${i}.balance`}>
                <MoneyInput value={ln.balance || ''} onChange={e => listUpdate('loans', i, { balance: e.target.value })} />
              </Field>
              <Field label="Minimum repayment ($)" required name={`as.loan${i}.repayment`}>
                <MoneyInput value={ln.repayment || ''} onChange={e => listUpdate('loans', i, { repayment: e.target.value })} />
              </Field>
              <Field label="Repayment frequency" required name={`as.loan${i}.repaymentFreq`}>
                <Select value={ln.repaymentFreq || ''} onChange={e => listUpdate('loans', i, { repaymentFreq: e.target.value })}>
                  <option value="">Select…</option>
                  <option>Weekly</option><option>Fortnightly</option><option>Monthly</option>
                </Select>
              </Field>
              <Field label="Are you paying extra on top of the minimum repayments?" required span={2} name={`as.loan${i}.extraRepayYn`}>
                <YesNo value={ln.extraRepayYn} onChange={v => listUpdate('loans', i, { extraRepayYn: v, ...(v === false ? { extraRepayAmount: '', extraRepayFreq: '' } : {}) })} />
              </Field>
              {ln.extraRepayYn === true && (
                <>
                  <Field label="How much extra are you paying? ($)" required name={`as.loan${i}.extraRepayAmount`}
                    hint="If the repayment amount above already includes the extra, enter $0.">
                    <MoneyInput value={ln.extraRepayAmount || ''} onChange={e => listUpdate('loans', i, { extraRepayAmount: e.target.value })} />
                  </Field>
                  <Field label="Extra repayment frequency" required={Number(String(ln.extraRepayAmount || '').replace(/[^0-9.]/g, '')) > 0} name={`as.loan${i}.extraRepayFreq`}>
                    <Select value={ln.extraRepayFreq || ''} onChange={e => listUpdate('loans', i, { extraRepayFreq: e.target.value })}>
                      <option value="">Select…</option>
                      <option>Weekly</option><option>Fortnightly</option><option>Monthly</option>
                    </Select>
                  </Field>
                </>
              )}
              <Field label="Repayment type" required name={`as.loan${i}.repaymentType`}>
                <Select value={ln.repaymentType || ''} onChange={e => listUpdate('loans', i, { repaymentType: e.target.value, ioEnd: e.target.value === 'Interest only' ? (ln.ioEnd || '') : '' })}>
                  <option value="">Select…</option>
                  <option>Principal and interest</option><option>Interest only</option>
                </Select>
              </Field>
              {ln.repaymentType === 'Interest only' && (
                <Field label="When does the interest-only period end?" required name={`as.loan${i}.ioEnd`}
                  hint="Pick roughly when the loan reverts to principal & interest.">
                  <Input type="date" value={ln.ioEnd || ''} onChange={e => listUpdate('loans', i, { ioEnd: e.target.value })} />
                </Field>
              )}
              <Field label="Interest rate (%)" required name={`as.loan${i}.rate`}>
                <PercentInput value={ln.rate || ''} onChange={e => listUpdate('loans', i, { rate: e.target.value })} />
              </Field>
              <Field label="Rate type" required name={`as.loan${i}.rateType`}>
                <Select value={ln.rateType || ''} onChange={e => listUpdate('loans', i, { rateType: e.target.value, fixedEnd: e.target.value === 'Fixed' ? (ln.fixedEnd || '') : '' })}>
                  <option value="">Select…</option>
                  <option>Variable</option><option>Fixed</option><option>Split</option>
                </Select>
              </Field>
              {ln.rateType === 'Fixed' && (
                <Field label="When does the fixed rate end?" required name={`as.loan${i}.fixedEnd`}
                  hint="Pick the month the fixed-rate period rolls off.">
                  <Input type="date" value={ln.fixedEnd || ''} onChange={e => listUpdate('loans', i, { fixedEnd: e.target.value })} />
                </Field>
              )}
              {ln.rateType === 'Split' && (
                <>
                  <Field label="How much of the loan is fixed? ($)" required name={`as.loan${i}.splitFixedAmount`}
                    hint="The fixed-rate portion of this split loan (the rest is variable).">
                    <MoneyInput value={ln.splitFixedAmount || ''} onChange={e => listUpdate('loans', i, { splitFixedAmount: e.target.value })} />
                  </Field>
                  <Field label="When does the fixed portion end?" required name={`as.loan${i}.splitFixedEnd`}
                    hint="Pick the month the fixed-rate portion rolls off.">
                    <Input type="date" value={ln.splitFixedEnd || ''} onChange={e => listUpdate('loans', i, { splitFixedEnd: e.target.value })} />
                  </Field>
                  <Field label="Fixed interest rate (%)" required name={`as.loan${i}.splitFixedRate`}>
                    <PercentInput value={ln.splitFixedRate || ''} onChange={e => listUpdate('loans', i, { splitFixedRate: e.target.value })} />
                  </Field>
                </>
              )}
              {offsetAccounts.length > 0 && (
                <Field label="Linked offset account" span={2}
                  hint="Optional - link an offset account from your Cash & savings section above.">
                  <Select value={ln.linkedOffsetId || ''} onChange={e => listUpdate('loans', i, { linkedOffsetId: e.target.value })}>
                    <option value="">None</option>
                    {offsetAccounts.map(acc => (
                      <option key={acc.id} value={acc.id}>{acc.label}</option>
                    ))}
                  </Select>
                </Field>
              )}
              {ln.purpose === 'Novated lease' && (
                <>
                  <Field label="Is there a balloon / residual payment?" required span={2} name={`as.loan${i}.balloonYn`}>
                    <YesNo value={ln.balloonYn} onChange={v => listUpdate('loans', i, { balloonYn: v, ...(v === false ? { balloonWhen: '', balloonAmount: '' } : {}) })} />
                  </Field>
                  {ln.balloonYn === true && (
                    <>
                      <Field label="When is the balloon payment due?" required name={`as.loan${i}.balloonWhen`}>
                        <Input type="date" value={ln.balloonWhen || ''} onChange={e => listUpdate('loans', i, { balloonWhen: e.target.value })} />
                      </Field>
                      <Field label="How much is the balloon payment ($)?" required name={`as.loan${i}.balloonAmount`}>
                        <MoneyInput value={ln.balloonAmount || ''} onChange={e => listUpdate('loans', i, { balloonAmount: e.target.value })} />
                      </Field>
                    </>
                  )}
                </>
              )}
            </div>
          </RepeatItem>
        ))}
        <AddBtn onClick={() => listAdd('loans')}>Add loan</AddBtn>
      </div>

      <div className="card">
        <div className="card-title">Credit cards & BNPL</div>
        {(d.credit || []).map((c, i) => (
          <RepeatItem key={i} title={`Credit facility ${i+1}`} onRemove={() => listRemove('credit', i)}>
            <div className="grid-2">
              <Field label="Provider" required name={`as.credit${i}.provider`}
                hint="Pick from the list or type your own if it's not there.">
                <Input list="au-card-providers" value={c.provider || ''} onChange={e => listUpdate('credit', i, { provider: e.target.value })} />
              </Field>
              <Field label="Owner" required name={`as.credit${i}.owner`}>
                <Select value={c.owner || ''} onChange={e => listUpdate('credit', i, { owner: e.target.value })}>
                  <option value="">Select…</option>
                  {primaryOpt}{partnerOpt}<option>Joint</option>
                </Select>
              </Field>
              <Field label="Type" required name={`as.credit${i}.type`}>
                <Select value={c.type || ''} onChange={e => listUpdate('credit', i, { type: e.target.value })}>
                  <option value="">Select…</option>
                  <option>Credit card</option><option>BNPL (Afterpay, Zip etc.)</option><option>Personal loan</option>
                </Select>
              </Field>
              <Field label="Credit limit ($)" required name={`as.credit${i}.limit`}>
                <MoneyInput value={c.limit || ''} onChange={e => listUpdate('credit', i, { limit: e.target.value })} />
              </Field>
              <Field label="Current balance ($)" required name={`as.credit${i}.balance`}>
                <MoneyInput value={c.balance || ''} onChange={e => listUpdate('credit', i, { balance: e.target.value })} />
              </Field>
              {c.type === 'Credit card' && Number(String(c.balance).replace(/[^0-9.]/g, '')) > 0 && (
                <Field label="Do you pay this off in full each month?" required name={`as.credit${i}.payFull`} span={2}>
                  <YesNo value={c.payFull} onChange={v => listUpdate('credit', i, { payFull: v })} />
                </Field>
              )}
            </div>
          </RepeatItem>
        ))}
        <AddBtn onClick={() => listAdd('credit')}>Add facility</AddBtn>
      </div>

      <div className="card">
        <div className="card-title">Other liabilities</div>
        <Field label="Do you have an ATO tax debt?">
          <YesNo value={d.atoDebt} onChange={v => update({ atoDebt: v })} />
        </Field>
        {d.atoDebt && (
          <div className="grid-2" style={{ marginTop: 14 }}>
            <Field label="ATO debt amount ($)" required name="as.atoAmount">
              <MoneyInput value={d.atoAmount || ''} onChange={e => update({ atoAmount: e.target.value })} />
            </Field>
            <Field label="Payment plan in place?" required name="as.atoPlan">
              <YesNo value={d.atoPlan} onChange={v => update({ atoPlan: v })} />
            </Field>
            <Field label="ATO debt owner" required name="as.atoOwner">
              <Select value={d.atoOwner || ''} onChange={e => update({ atoOwner: e.target.value })}>
                <option value="">Select…</option>
                {primaryOpt}{partnerOpt}<option>Joint</option>
              </Select>
            </Field>
          </div>
        )}
        <hr className="divider" />
        {/* HELP/HECS is held in one person's name only (never joint), but a
            couple may have one each - so this is a repeatable list with a
            single-person owner picker. Legacy single-HELP data
            (hecsBalance/hecsOwner) is migrated into the list on first "Yes". */}
        <Field label="HELP / HECS debt?">
          <YesNo value={d.hecs} onChange={v => set(prev => {
            const pa = prev.assets || {};
            let helpDebts = pa.helpDebts;
            if (v === true && (!helpDebts || helpDebts.length === 0)) {
              helpDebts = (pa.hecsBalance || pa.hecsOwner)
                ? [{ balance: pa.hecsBalance || '', owner: pa.hecsOwner || '' }]
                : [{}];
            }
            return { ...prev, assets: { ...pa, hecs: v, ...(helpDebts ? { helpDebts } : {}) } };
          })} />
        </Field>
        {d.hecs && (
          <div style={{ marginTop: 14 }}>
            {(d.helpDebts || []).map((h, i) => (
              <RepeatItem key={i} title={`HELP debt ${i+1}`} onRemove={() => listRemove('helpDebts', i)}>
                <div className="grid-2">
                  <Field label="Estimated HELP balance ($)" required name={`as.help${i}.balance`}>
                    <MoneyInput value={h.balance || ''} onChange={e => listUpdate('helpDebts', i, { balance: e.target.value })} />
                  </Field>
                  <Field label="HELP owner" required name={`as.help${i}.owner`}>
                    <Select value={h.owner || ''} onChange={e => listUpdate('helpDebts', i, { owner: e.target.value })}>
                      <option value="">Select…</option>
                      {primaryOpt}{partnerOpt}
                    </Select>
                  </Field>
                </div>
              </RepeatItem>
            ))}
            <AddBtn onClick={() => listAdd('helpDebts')}>Add HELP debt</AddBtn>
          </div>
        )}
        <hr className="divider" />
        <Field label="Other liabilities (description & amount)">
          <Textarea value={d.otherLiab || ''} onChange={e => update({ otherLiab: e.target.value })}
            placeholder="e.g. Personal loan with Westpac $8,000 remaining…" />
        </Field>
      </div>

      {/* Hidden datalists rendered once per section so the
          fund-name + bank-name <Input list="..."> fields above can
          offer a typeahead-style dropdown of common values while
          still accepting any free-text the user types. */}
      <datalist id="au-super-funds">
        {AU_SUPER_FUNDS.map(name => <option key={name} value={name} />)}
      </datalist>
      <datalist id="au-banks">
        {AU_BANKS.map(name => <option key={name} value={name} />)}
      </datalist>
      <datalist id="au-card-providers">
        {AU_CARD_PROVIDERS.map(name => <option key={name} value={name} />)}
      </datalist>

      {valuePrompt && (
        <div className="ff-modal-backdrop" onClick={() => setValuePrompt(null)}>
          <div className="ff-modal" style={{ maxWidth: 460 }} onClick={(e) => e.stopPropagation()}>
            <div className="modal-title">Please confirm the value</div>
            <div style={{ color: '#4A4A46', fontSize: 14, lineHeight: 1.55, marginBottom: 18 }}>
              You have stated your property is worth <strong>${Number(valuePrompt.value).toLocaleString('en-AU')}</strong>, please confirm this is correct.
            </div>
            <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
              <button type="button" className="btn" onClick={() => setValuePrompt(null)}>Let me change it</button>
              <button type="button" className="btn btn-primary"
                onClick={() => { listUpdate('properties', valuePrompt.idx, { valueConfirmed: true }); setValuePrompt(null); }}>
                Yes, that's correct
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { SectionAssets });
