// Opportunity engine mock data — per-user, structured to be swappable for real
// API responses later. Everything keyed off OPP_PROFILE (Layla Haddad persona,
// consistent with USER / LIABILITIES in data.jsx).

const OPP_PROFILE = {
  userId: 'layla',
  fullName: 'Layla Haddad',
  emiratesId: '784-1993-•••••••-•',
  monthlyIncome: 24_800,
  employer: 'Meraki Media FZ-LLC',
  employmentType: 'Salaried',
  salaryBank: 'Emirates NBD',
  residency: 'UAE resident',
  ownsProperty: true,
  dependants: 1,
};

// Aggregator partner (placeholder branding — swap when the partnership lands)
const OPP_PARTNER = {
  name: 'Bridgeline',
  legal: 'Bridgeline Financial Services (placeholder)',
  blurb: 'Applications are handled by our aggregator partner across all listed providers.',
};

// What gets shared with the partner at the consent step
const OPP_CONSENT_ITEMS = [
  'Full name and masked Emirates ID',
  'Monthly income and employer name',
  'Employment type and residency status',
  'A summary of the data behind this recommendation (no transaction details)',
  'The product you selected',
];

const OPP_DISCLAIMER =
  'This is educational information based on your linked-account data, not financial advice. Figures are estimates. Final eligibility, pricing and approval are determined by the provider.';

// ── Card rewards ──────────────────────────────────────────────────────────────
// Last 12 months of categorized card spend (mocked from linked accounts).
const CARD_SPEND_12M = [
  { key: 'dining',    label: 'Dining',    spend: 27_600 },
  { key: 'groceries', label: 'Groceries', spend: 21_600 },
  { key: 'travel',    label: 'Travel',    spend: 18_000 },
  { key: 'online',    label: 'Online',    spend: 14_400 },
  { key: 'utilities', label: 'Utilities', spend: 12_000 },
  { key: 'fuel',      label: 'Fuel',      spend: 9_000 },
];
const CARD_SPEND_TOTAL = CARD_SPEND_12M.reduce((s, c) => s + c.spend, 0); // 102,600

// Earn for a card on a category: category rate if present, else `other` rate.
function cardEarnOn(card, catKey, spend) {
  const rate = card.rates[catKey] != null ? card.rates[catKey] : (card.rates.other || 0);
  return Math.round(spend * rate / 100);
}

// Cards marketplace catalog. Realistic-feeling UAE names, easily swappable.
const CARDS_CATALOG = [
  {
    id: 'fab-cashback-plus', provider: 'FAB', name: 'FAB Cashback Plus',
    rates: { dining: 5, groceries: 3, other: 1 },
    rateSummary: '5% dining · 3% groceries · 1% other',
    annualFee: 315, minSalary: 15_000, salaryTransfer: false,
    perks: ['Cinema 2-for-1', 'Valet 2x/month'],
    lounge: false, aiScore: 94,
  },
  {
    id: 'mashreq-travel-world', provider: 'Mashreq', name: 'Mashreq Travel Rewards World',
    rates: { travel: 4, online: 2, other: 1 },
    rateSummary: '4% travel · 2% online · 1% other',
    annualFee: 525, minSalary: 20_000, salaryTransfer: false,
    perks: ['4 lounge visits/yr', '0% FX markup weeks'],
    lounge: true, aiScore: 88,
  },
  {
    id: 'enbd-lite', provider: 'Emirates NBD', name: 'ENBD Lite Cashback',
    rates: { other: 1 },
    rateSummary: '1% flat on everything',
    annualFee: 0, minSalary: 12_000, salaryTransfer: false,
    perks: ['Instant digital issuance'],
    lounge: false, aiScore: 61, isCurrent: true,
  },
  {
    id: 'adcb-touchpoints', provider: 'ADCB', name: 'ADCB TouchPoints Platinum',
    rates: { groceries: 2.5, fuel: 3, other: 1 },
    rateSummary: '3% fuel · 2.5% groceries · 1% other',
    annualFee: 420, minSalary: 15_000, salaryTransfer: false,
    perks: ['Free parking app credits'],
    lounge: false, aiScore: 72,
  },
  {
    id: 'adib-smart', provider: 'ADIB', name: 'ADIB Smart Cashback',
    rates: { dining: 2, groceries: 2, other: 0.5 },
    rateSummary: '2% dining & groceries · 0.5% other',
    annualFee: 0, minSalary: 10_000, salaryTransfer: true,
    perks: ['Sharia compliant'],
    lounge: false, aiScore: 64,
  },
  {
    id: 'dib-prime', provider: 'DIB', name: 'DIB Prime Rewards',
    rates: { other: 1.2 },
    rateSummary: '1.2% flat on everything',
    annualFee: 99, minSalary: 12_000, salaryTransfer: false,
    perks: ['Salaam points transfer'],
    lounge: false, aiScore: 58,
  },
  {
    id: 'enbd-skywards-infinite', provider: 'Emirates NBD', name: 'ENBD Skywards Infinite',
    rates: { travel: 5, dining: 3, other: 1.5 },
    rateSummary: '5% travel · 3% dining · 1.5% other',
    annualFee: 1_575, minSalary: 30_000, salaryTransfer: false,
    perks: ['Unlimited lounge', 'Skywards Silver'],
    lounge: true, aiScore: 81,
  },
  {
    id: 'hsbc-premier', provider: 'HSBC', name: 'HSBC Premier Select',
    rates: { travel: 4, online: 3, other: 1.5 },
    rateSummary: '4% travel · 3% online · 1.5% other',
    annualFee: 0, minSalary: 40_000, salaryTransfer: true,
    perks: ['Unlimited lounge', 'Global Premier status'],
    lounge: true, aiScore: 76,
  },
];

// The user's current setup: everything on the flat 1% ENBD card.
const CARD_REWARDS_CURRENT = {
  cards: [
    { issuer: 'Emirates NBD', name: 'ENBD Lite Cashback', last: '•• 4821', rateSummary: '1% flat', annualFee: 0 },
    { issuer: 'ADCB', name: 'ADCB Classic', last: '•• 9102', rateSummary: 'No rewards programme', annualFee: 0 },
  ],
  // 12-month earn: all categorized spend at 1% flat
  earn12m: Math.round(CARD_SPEND_TOTAL * 0.01), // 1,026
  fees12m: 0,
};

// AI-recommended combo (constrained to cards Layla is eligible for):
// dining + groceries → FAB Cashback Plus; travel + online → Mashreq Travel
// Rewards World; utilities + fuel stay on the existing no-fee ENBD card.
const CARD_REWARDS_RECO = {
  combo: [
    {
      cardId: 'fab-cashback-plus',
      useFor: ['dining', 'groceries'],
      why: 'Dining and groceries are your two biggest card categories (AED 49,200/yr). The 5% and 3% category rates beat every other card you qualify for.',
    },
    {
      cardId: 'mashreq-travel-world',
      useFor: ['travel', 'online'],
      why: 'You spent AED 32,400 on travel and online in 12 months. 4% on travel plus 2% online out-earns the annual fee about 2x over.',
    },
    {
      cardId: 'enbd-lite',
      useFor: ['utilities', 'fuel'],
      why: 'Keep your existing no-fee card for the categories no eligible card boosts. Nothing to apply for.',
      keep: true,
    },
  ],
};

// Backtest: per-category earn for current setup vs the recommended combo,
// computed against the actual 12-month spend above.
function getCardRewardsBacktest() {
  const comboByCat = {};
  CARD_REWARDS_RECO.combo.forEach((slot) => {
    const card = CARDS_CATALOG.find((c) => c.id === slot.cardId);
    slot.useFor.forEach((k) => { comboByCat[k] = card; });
  });
  const rows = CARD_SPEND_12M.map((cat) => {
    const card = comboByCat[cat.key];
    const reco = cardEarnOn(card, cat.key, cat.spend);
    const current = Math.round(cat.spend * 0.01);
    return { ...cat, cardName: card.name, current, reco };
  });
  const recoGross = rows.reduce((s, r) => s + r.reco, 0);
  const recoFees = CARD_REWARDS_RECO.combo.reduce((s, slot) => {
    const card = CARDS_CATALOG.find((c) => c.id === slot.cardId);
    return s + (slot.keep ? 0 : card.annualFee);
  }, 0);
  const currentNet = CARD_REWARDS_CURRENT.earn12m - CARD_REWARDS_CURRENT.fees12m;
  const recoNet = recoGross - recoFees;
  return { rows, recoGross, recoFees, currentNet, recoNet, delta: recoNet - currentNet };
}

const CARD_REWARDS_ASSUMPTIONS = [
  'Spend is your last 12 months of categorized card transactions across linked accounts.',
  'Current earn assumes your ENBD card’s flat 1% on all categorized spend.',
  'Recommended earn applies each card’s advertised category rates to your actual spend, with annual fees deducted.',
  'Only cards whose minimum salary you meet (AED 24,800/mo) are considered in the recommendation.',
  'Earn caps, welcome bonuses and promotional rates are excluded.',
];

// ── Mortgage reprice ──────────────────────────────────────────────────────────
// Current mortgage mirrors LIABILITIES.mortgages (Mashreq, JVC Studio).
function oppPmt(principal, annualRate, months) {
  const r = annualRate / 100 / 12;
  return Math.round(principal * r * Math.pow(1 + r, months) / (Math.pow(1 + r, months) - 1));
}

const MORTGAGE_CURRENT = {
  lender: 'Mashreq', property: 'JVC Studio',
  balance: 460_000, rate: 4.5, monthly: 2_840, remainingMonths: 276, remainingLabel: '23 years',
};

// Switching costs: early settlement capped at the lower of 1% or AED 10,000.
const MORTGAGE_SWITCH_COSTS = (() => {
  const earlySettlement = Math.min(Math.round(MORTGAGE_CURRENT.balance * 0.01), 10_000); // 4,600
  const valuation = 3_150;
  const processing = 1_500;
  return { earlySettlement, valuation, processing, total: earlySettlement + valuation + processing }; // 9,250
})();

function getMortgageReprice(rate) {
  const monthly = oppPmt(MORTGAGE_CURRENT.balance, rate, MORTGAGE_CURRENT.remainingMonths);
  const savedMonthly = MORTGAGE_CURRENT.monthly - monthly;
  const breakEvenMonths = savedMonthly > 0 ? Math.ceil(MORTGAGE_SWITCH_COSTS.total / savedMonthly) : null;
  const totalSaved = savedMonthly * MORTGAGE_CURRENT.remainingMonths - MORTGAGE_SWITCH_COSTS.total;
  return { monthly, savedMonthly, breakEvenMonths, totalSaved };
}

const MORTGAGE_BEST = getMortgageReprice(3.74); // FAB fixed offer

// ── Loan costs ────────────────────────────────────────────────────────────────
// Mirrors LIABILITIES: personal loan, auto loan (flat rate), 2 revolving cards.
const LOANS_OPP_DATA = {
  debts: [
    { name: 'Mashreq Personal Loan', sub: 'AED 18,400 balance · 6.8%', monthly: 920, interestToMaturity: 1_095 },
    { name: 'Credit cards (2)', sub: 'AED 7,280 balance · 33 to 36% APR', monthly: 365, interestToMaturity: 4_700, note: 'paying minimums' },
    { name: 'ADCB Auto Finance', sub: 'AED 24,800 balance · 5.9% flat', monthly: 1_240, interestToMaturity: 2_410 },
  ],
  // Consolidate personal loan + cards (AED 25,680) into 36 months at 5.49%
  // reducing. Auto loan stays: its early-settlement penalty eats the gain.
  consolidation: {
    amount: 25_680, months: 36, rate: 5.49,
    newMonthly: 775, oldMonthly: 1_285,
    newInterest: 2_220, oldInterest: 5_795,
  },
};
const LOANS_SAVING = LOANS_OPP_DATA.consolidation.oldInterest - LOANS_OPP_DATA.consolidation.newInterest; // 3,575

// ── FX fees ───────────────────────────────────────────────────────────────────
const FX_CORRIDORS = [
  { corridor: 'AED → GBP', use: 'Transfers to London', volume: 28_000, via: 'ENBD bank wire', paidPct: 2.1, paid: 588, bestProvider: 'Atlas Remit', bestPct: 0.45, best: 126 },
  { corridor: 'AED → EUR', use: 'Card spend abroad', volume: 22_000, via: 'Card FX markup', paidPct: 3.5, paid: 770, bestProvider: 'Wio multi-currency', bestPct: 0.2, best: 44 },
  { corridor: 'AED → INR', use: 'Transfers to family', volume: 14_400, via: 'Exchange house', paidPct: 1.3, paid: 187, bestProvider: 'QuickRemit', bestPct: 0.4, best: 58 },
];
const FX_PAID = FX_CORRIDORS.reduce((s, c) => s + c.paid, 0);       // 1,545
const FX_BEST = FX_CORRIDORS.reduce((s, c) => s + c.best, 0);       // 228
const FX_SAVING = FX_PAID - FX_BEST;                                 // 1,317

// ── Insurance: shared inputs ──────────────────────────────────────────────────
// Liabilities reused from the mortgage + loans data above.
const INSURANCE_INPUTS = {
  monthlyIncome: OPP_PROFILE.monthlyIncome,
  dependants: OPP_PROFILE.dependants,
  outstandingLiabilities: 510_000, // mortgage 460K + loans 43K + cards 7K
  liquidAssets: 400_000,
};

// Life: 5 years of income + liabilities − liquid assets ≈ 1.6M
const LIFE_NEED =
  INSURANCE_INPUTS.monthlyIncome * 60 + INSURANCE_INPUTS.outstandingLiabilities - INSURANCE_INPUTS.liquidAssets; // 1,598,000

// ── Marketplace registry ──────────────────────────────────────────────────────
// One config per category; the shared MarketplaceScreen reads from here.
const OPP_MARKETPLACES = {
  cards: {
    title: 'Rewards cards',
    navLabel: 'Cards marketplace',
    products: CARDS_CATALOG.map((c) => {
      // 12-month earn if all categorized spend went on this one card
      const est = CARD_SPEND_12M.reduce((s, cat) => s + cardEarnOn(c, cat.key, cat.spend), 0);
      return {
        ...c,
        est12m: est,
        net12m: est - c.annualFee,
        eligible: OPP_PROFILE.monthlyIncome >= c.minSalary,
        eligibilityNote: `Requires AED ${(c.minSalary / 1000).toFixed(0)}K+ monthly salary${c.salaryTransfer ? ' · salary transfer' : ''}`,
        keyTerms: [
          ['Earn rates', c.rateSummary],
          ['Annual fee', c.annualFee === 0 ? 'Free' : `AED ${c.annualFee.toLocaleString()}/yr`],
          ['Minimum salary', `AED ${c.minSalary.toLocaleString()}/mo`],
          ['Salary transfer', c.salaryTransfer ? 'Required' : 'Not required'],
        ],
      };
    }),
  },

  mortgage: {
    title: 'Mortgage offers',
    navLabel: 'Mortgage marketplace',
    products: [
      { id: 'fab-home-fix', provider: 'FAB', name: 'FAB Home Flex Fixed', rate: 3.74, fixedFor: 'Fixed 3 years', fee: 4_650, minSalary: 20_000, aiScore: 93 },
      { id: 'enbd-eibor', provider: 'Emirates NBD', name: 'ENBD EIBOR Smart', rate: 3.99, fixedFor: '3M EIBOR + 0.6%', fee: 4_400, minSalary: 15_000, aiScore: 84 },
      { id: 'mashreq-reprice', provider: 'Mashreq', name: 'Mashreq rate reprice', rate: 4.15, fixedFor: 'Stay with your lender', fee: 1_050, minSalary: 0, aiScore: 81, isCurrent: true, currentTag: 'Your lender', applyable: true },
      { id: 'dib-home', provider: 'DIB', name: 'DIB Islamic Home Finance', rate: 4.05, fixedFor: 'Profit rate, 3 years', fee: 5_150, minSalary: 15_000, aiScore: 78 },
      { id: 'adcb-fix5', provider: 'ADCB', name: 'ADCB Fixed Five', rate: 4.19, fixedFor: 'Fixed 5 years', fee: 4_650, minSalary: 18_000, aiScore: 70 },
      { id: 'hsbc-home', provider: 'HSBC', name: 'HSBC Premier Home', rate: 3.65, fixedFor: 'Fixed 3 years', fee: 4_150, minSalary: 40_000, aiScore: 88 },
    ].map((m) => {
      const calc = getMortgageReprice(m.rate);
      const reprice = m.isCurrent;
      const fees = reprice ? m.fee : m.fee + MORTGAGE_SWITCH_COSTS.earlySettlement;
      return {
        ...m,
        sub: `${m.rate}% · ${m.fixedFor}`,
        metricValue: `AED ${calc.monthly.toLocaleString()}/mo`,
        metricLabel: `saves AED ${calc.savedMonthly.toLocaleString()}/mo`,
        chips: [`Upfront · AED ${fees.toLocaleString()}`, reprice ? 'No early settlement fee' : 'Break-even in months shown at apply'],
        sortSavings: calc.savedMonthly, sortFees: fees,
        eligible: OPP_PROFILE.monthlyIncome >= m.minSalary,
        eligibilityNote: `Requires AED ${(m.minSalary / 1000).toFixed(0)}K+ monthly salary`,
        keyTerms: [
          ['Rate', `${m.rate}% · ${m.fixedFor}`],
          ['New monthly payment', `AED ${calc.monthly.toLocaleString()} (now AED ${MORTGAGE_CURRENT.monthly.toLocaleString()})`],
          ['Upfront costs', `AED ${fees.toLocaleString()}`],
          ['Break-even', calc.breakEvenMonths ? `${Math.ceil(fees / calc.savedMonthly)} months` : 'n/a'],
          ['Saved over term', `AED ${(calc.savedMonthly * MORTGAGE_CURRENT.remainingMonths - fees).toLocaleString()}`],
        ],
      };
    }),
  },

  loans: {
    title: 'Consolidation loans',
    navLabel: 'Loans marketplace',
    products: [
      { id: 'fab-consol', provider: 'FAB', name: 'FAB Consolidation Loan', rate: 5.49, monthly: 775, totalInterest: 2_220, fee: 257, minSalary: 15_000, salaryTransfer: false, aiScore: 92 },
      { id: 'rak-debtone', provider: 'RAKBank', name: 'RAKBank Debt One', rate: 5.79, monthly: 779, totalInterest: 2_345, fee: 250, minSalary: 12_000, salaryTransfer: false, aiScore: 85 },
      { id: 'enbd-smartloan', provider: 'Emirates NBD', name: 'ENBD Smart Loan', rate: 5.99, monthly: 781, totalInterest: 2_430, fee: 260, minSalary: 12_000, salaryTransfer: true, aiScore: 80 },
      { id: 'adib-finance', provider: 'ADIB', name: 'ADIB Personal Finance', rate: 6.2, monthly: 784, totalInterest: 2_515, fee: 265, minSalary: 10_000, salaryTransfer: true, aiScore: 72 },
      { id: 'hsbc-select-loan', provider: 'HSBC', name: 'HSBC Select Loan', rate: 4.99, monthly: 769, totalInterest: 2_015, fee: 250, minSalary: 40_000, salaryTransfer: true, aiScore: 90 },
    ].map((l) => ({
      ...l,
      sub: `${l.rate}% reducing · 36 months · AED ${LOANS_OPP_DATA.consolidation.amount.toLocaleString()}`,
      metricValue: `AED ${l.monthly.toLocaleString()}/mo`,
      metricLabel: `vs AED ${LOANS_OPP_DATA.consolidation.oldMonthly.toLocaleString()} today`,
      chips: [`Total interest · AED ${l.totalInterest.toLocaleString()}`, l.salaryTransfer ? 'Salary transfer required' : 'No salary transfer'],
      sortSavings: LOANS_OPP_DATA.consolidation.oldInterest - l.totalInterest, sortFees: l.fee,
      eligible: OPP_PROFILE.monthlyIncome >= l.minSalary,
      eligibilityNote: `Requires AED ${(l.minSalary / 1000).toFixed(0)}K+ monthly salary`,
      keyTerms: [
        ['Amount', `AED ${LOANS_OPP_DATA.consolidation.amount.toLocaleString()} · 36 months`],
        ['Rate', `${l.rate}% reducing`],
        ['Monthly payment', `AED ${l.monthly.toLocaleString()} (now AED ${LOANS_OPP_DATA.consolidation.oldMonthly.toLocaleString()})`],
        ['Total interest', `AED ${l.totalInterest.toLocaleString()} (vs AED ${LOANS_OPP_DATA.consolidation.oldInterest.toLocaleString()} today)`],
        ['Processing fee', `AED ${l.fee} (1%)`],
      ],
    })),
  },

  fx: {
    title: 'FX & transfers',
    navLabel: 'FX marketplace',
    products: [
      { id: 'atlas-remit', provider: 'Atlas Remit', name: 'Atlas Remit', sub: 'Transfers · GBP, EUR, INR + 40 more', allIn: 0.45, fee12m: 191, chips: ['Same-day GBP & EUR', 'Rate lock 24h'], minSalary: 0, aiScore: 94 },
      { id: 'wio-multi', provider: 'Wio', name: 'Wio Multi-currency Card', sub: 'Card spend · 0.2% FX markup', allIn: 0.2, fee12m: 44, chips: ['Apple Pay', 'No annual fee'], minSalary: 0, aiScore: 90 },
      { id: 'quickremit', provider: 'QuickRemit', name: 'QuickRemit Exchange', sub: 'Transfers · INR, PHP, PKR corridors', allIn: 0.4, fee12m: 58, chips: ['Cash pickup option'], minSalary: 0, aiScore: 76 },
      { id: 'enbd-wire', provider: 'Emirates NBD', name: 'ENBD International Wire', sub: 'Bank wire · 2.1% all-in + AED 75/transfer', allIn: 2.1, fee12m: 1_545, chips: ['Your current route'], minSalary: 0, aiScore: 40, isCurrent: true, currentTag: 'Current route' },
      { id: 'primepay', provider: 'PrimePay', name: 'PrimePay Business FX', sub: 'Bulk corridors · 0.3% all-in', allIn: 0.3, fee12m: 140, chips: ['API payouts'], minSalary: 0, aiScore: 68, requiresBusiness: true },
    ].map((f) => ({
      ...f,
      metricValue: `${f.allIn}%`,
      metricLabel: 'all-in cost',
      sortSavings: FX_PAID - f.fee12m, sortFees: f.fee12m,
      eligible: !f.requiresBusiness,
      eligibilityNote: 'Requires a registered business account',
      keyTerms: [
        ['All-in cost', `${f.allIn}% of amount`],
        ['On your 12-month volume', `≈ AED ${f.fee12m.toLocaleString()} in fees`],
        ['vs what you paid', `AED ${FX_PAID.toLocaleString()}`],
      ],
    })),
  },

  life: {
    title: 'Term life cover',
    navLabel: 'Life cover marketplace',
    products: [
      { id: 'hayah-term', provider: 'Hayah', name: 'Hayah Term Protect', cover: 1_600_000, term: 20, monthly: 102, medical: 'Not required up to AED 2M', minSalary: 0, aiScore: 95 },
      { id: 'zurich-term', provider: 'Zurich', name: 'Zurich International Term', cover: 1_600_000, term: 20, monthly: 109, medical: 'Not required', minSalary: 0, aiScore: 88 },
      { id: 'metlife-live', provider: 'MetLife', name: 'MetLife LiveSecure', cover: 2_000_000, term: 20, monthly: 128, medical: 'Basic check', minSalary: 0, aiScore: 80 },
      { id: 'axa-term', provider: 'AXA', name: 'AXA Term Classic', cover: 1_600_000, term: 20, monthly: 121, medical: 'Full exam', minSalary: 0, aiScore: 74 },
      { id: 'pw-whole', provider: 'Lombard', name: 'Private Wealth Whole-of-Life', cover: 5_000_000, term: 99, monthly: 1_450, medical: 'Full exam', minSalary: 50_000, aiScore: 60 },
    ].map((p) => ({
      ...p,
      sub: `AED ${(p.cover / 1_000_000).toFixed(1)}M cover · ${p.term === 99 ? 'whole of life' : `${p.term} years`}`,
      metricValue: `AED ${p.monthly.toLocaleString()}/mo`,
      metricLabel: 'premium',
      chips: [`Medical · ${p.medical}`],
      sortSavings: -p.monthly, sortFees: p.monthly * 12,
      eligible: OPP_PROFILE.monthlyIncome >= p.minSalary,
      eligibilityNote: `Requires AED ${(p.minSalary / 1000).toFixed(0)}K+ monthly income`,
      keyTerms: [
        ['Cover', `AED ${p.cover.toLocaleString()}`],
        ['Term', p.term === 99 ? 'Whole of life' : `${p.term} years`],
        ['Premium', `AED ${p.monthly.toLocaleString()}/mo, fixed for the term`],
        ['Medical', p.medical],
      ],
    })),
  },

  income_protection: {
    title: 'Income protection',
    navLabel: 'Income protection marketplace',
    products: [
      { id: 'sukoon-income', provider: 'Sukoon', name: 'Sukoon IncomeShield', benefit: 14_880, deferred: 3, toAge: 60, monthly: 118, minSalary: 0, aiScore: 93 },
      { id: 'metlife-income', provider: 'MetLife', name: 'MetLife Income Guard', benefit: 14_880, deferred: 3, toAge: 60, monthly: 132, minSalary: 0, aiScore: 84 },
      { id: 'zurich-income', provider: 'Zurich', name: 'Zurich Income Protect', benefit: 14_880, deferred: 6, toAge: 65, monthly: 141, minSalary: 0, aiScore: 79 },
      { id: 'exec-ip', provider: 'FriendsProvident', name: 'Executive Income Cover', benefit: 21_000, deferred: 1, toAge: 65, monthly: 360, minSalary: 35_000, aiScore: 70 },
    ].map((p) => ({
      ...p,
      sub: `AED ${p.benefit.toLocaleString()}/mo benefit · ${p.deferred}-month wait · to age ${p.toAge}`,
      metricValue: `AED ${p.monthly.toLocaleString()}/mo`,
      metricLabel: 'premium',
      chips: [`Pays to age ${p.toAge}`, `${p.deferred}-month deferred period`],
      sortSavings: -p.monthly, sortFees: p.monthly * 12,
      eligible: OPP_PROFILE.monthlyIncome >= p.minSalary,
      eligibilityNote: `Requires AED ${(p.minSalary / 1000).toFixed(0)}K+ monthly income`,
      keyTerms: [
        ['Monthly benefit', `AED ${p.benefit.toLocaleString()} (60% of income)`],
        ['Deferred period', `${p.deferred} months`],
        ['Pays until', `Age ${p.toAge} or return to work`],
        ['Premium', `AED ${p.monthly.toLocaleString()}/mo`],
      ],
    })),
  },

  home: {
    title: 'Home & contents cover',
    navLabel: 'Home cover marketplace',
    products: [
      { id: 'sukoon-home', provider: 'Sukoon', name: 'Sukoon HomeShield Owner', sub: 'Building AED 620K + contents AED 200K', annual: 1_165, scope: 'Building + contents', minSalary: 0, aiScore: 94 },
      { id: 'rsa-home', provider: 'RSA', name: 'RSA HomeSecure', sub: 'Building AED 620K + contents AED 150K', annual: 1_240, scope: 'Building + contents', minSalary: 0, aiScore: 82 },
      { id: 'watania-home', provider: 'Watania', name: 'Watania Premier Home', sub: 'Building AED 620K + contents AED 175K', annual: 1_090, scope: 'Building + contents', minSalary: 0, aiScore: 79 },
      { id: 'axa-smarthome', provider: 'AXA', name: 'AXA SmartHome', sub: 'Building only · AED 620K', annual: 1_420, scope: 'Building only', minSalary: 0, aiScore: 55, isCurrent: true, currentTag: 'Your policy' },
      { id: 'salama-contents', provider: 'Salama', name: 'Salama Contents Only', sub: 'Contents AED 100K · renter plan', annual: 320, scope: 'Contents only', minSalary: 0, aiScore: 48, scopeNote: 'No building cover. Suits renters, not owners.' },
    ].map((p) => ({
      ...p,
      metricValue: `AED ${p.annual.toLocaleString()}/yr`,
      metricLabel: 'premium',
      chips: [p.scope, ...(p.scopeNote ? [p.scopeNote] : [])],
      sortSavings: 1_420 - p.annual, sortFees: p.annual,
      eligible: true,
      keyTerms: [
        ['Scope', p.scope],
        ['Cover', p.sub],
        ['Premium', `AED ${p.annual.toLocaleString()}/yr (now AED 1,420/yr building only)`],
        ['Excess', 'AED 500 per claim'],
      ],
    })),
  },

  car: {
    title: 'Car insurance',
    navLabel: 'Car cover marketplace',
    products: [
      { id: 'sukoon-motor', provider: 'Sukoon', name: 'Sukoon Motor Comprehensive', sub: 'Comprehensive · agency repair', annual: 1_890, scope: 'Comprehensive', minSalary: 0, aiScore: 93 },
      { id: 'gig-motor', provider: 'GIG', name: 'GIG Comprehensive', sub: 'Comprehensive · garage repair', annual: 1_975, scope: 'Comprehensive', minSalary: 0, aiScore: 85 },
      { id: 'rsa-motor', provider: 'RSA', name: 'RSA Motor', sub: 'Comprehensive · garage repair', annual: 2_050, scope: 'Comprehensive', minSalary: 0, aiScore: 78 },
      { id: 'axa-motor', provider: 'AXA', name: 'AXA Motor (renewal quote)', sub: 'Comprehensive · your current policy', annual: 2_400, scope: 'Comprehensive', minSalary: 0, aiScore: 60, isCurrent: true, currentTag: 'Your policy' },
      { id: 'salama-tp', provider: 'Salama', name: 'Salama Third Party', sub: 'Liability only', annual: 780, scope: 'Third party', minSalary: 0, aiScore: 45, scopeNote: 'A downgrade from comprehensive. Your own car is not covered.' },
    ].map((p) => ({
      ...p,
      metricValue: `AED ${p.annual.toLocaleString()}/yr`,
      metricLabel: 'premium',
      chips: [p.scope, ...(p.scopeNote ? [p.scopeNote] : [])],
      sortSavings: 2_400 - p.annual, sortFees: p.annual,
      eligible: true,
      keyTerms: [
        ['Cover', p.sub],
        ['Vehicle', '2022 Mazda CX-5 · insured value AED 74,500'],
        ['Premium', `AED ${p.annual.toLocaleString()}/yr (now AED 2,400/yr)`],
        ['Start date', 'At your Aug 2026 renewal, no-claims carried over'],
      ],
    })),
  },
};

// ── Marketplace sort + filter controls (per category) ────────────────────────
// `sorts`: how to order results. `filters`: quick toggles that narrow the list
// to products matching a relevant attribute. Comparators/predicates run against
// the product objects built above. The shared MarketplaceScreen reads these.
const oppNum = (v) => (typeof v === 'number' ? v : 0);
const oppHas = (p, ...keys) => keys.some((k) => new RegExp(k, 'i').test(`${p.sub || ''} ${p.scope || ''} ${p.fixedFor || ''} ${p.includes || ''} ${p.medical || ''}`));

Object.assign(OPP_MARKETPLACES.cards, {
  sorts: [
    { key: 'match', label: 'Best match', cmp: (a, b) => oppNum(b.aiScore) - oppNum(a.aiScore) },
    { key: 'rewards', label: 'Most rewards', cmp: (a, b) => oppNum(b.net12m) - oppNum(a.net12m) },
    { key: 'fee', label: 'Lowest fee', cmp: (a, b) => oppNum(a.annualFee) - oppNum(b.annualFee) },
  ],
  filters: [
    { key: 'nofee', label: 'No annual fee', test: (p) => p.annualFee === 0 },
    { key: 'nosalary', label: 'No salary transfer', test: (p) => !p.salaryTransfer },
    { key: 'lounge', label: 'Airport lounge', test: (p) => p.lounge },
  ],
});
Object.assign(OPP_MARKETPLACES.mortgage, {
  sorts: [
    { key: 'match', label: 'Best match', cmp: (a, b) => oppNum(b.aiScore) - oppNum(a.aiScore) },
    { key: 'rate', label: 'Lowest rate', cmp: (a, b) => oppNum(a.rate) - oppNum(b.rate) },
    { key: 'saving', label: 'Biggest saving', cmp: (a, b) => oppNum(b.sortSavings) - oppNum(a.sortSavings) },
  ],
  filters: [
    { key: 'fixed', label: 'Fixed rate', test: (p) => oppHas(p, 'fixed') },
    { key: 'eibor', label: 'EIBOR-linked', test: (p) => oppHas(p, 'eibor') },
    { key: 'islamic', label: 'Islamic', test: (p) => oppHas(p, 'islamic', 'profit rate') },
  ],
});
Object.assign(OPP_MARKETPLACES.loans, {
  sorts: [
    { key: 'match', label: 'Best match', cmp: (a, b) => oppNum(b.aiScore) - oppNum(a.aiScore) },
    { key: 'rate', label: 'Lowest rate', cmp: (a, b) => oppNum(a.rate) - oppNum(b.rate) },
    { key: 'monthly', label: 'Lowest monthly', cmp: (a, b) => oppNum(a.monthly) - oppNum(b.monthly) },
  ],
  filters: [
    { key: 'nosalary', label: 'No salary transfer', test: (p) => !p.salaryTransfer },
  ],
});
Object.assign(OPP_MARKETPLACES.fx, {
  sorts: [
    { key: 'match', label: 'Best match', cmp: (a, b) => oppNum(b.aiScore) - oppNum(a.aiScore) },
    { key: 'cost', label: 'Lowest cost', cmp: (a, b) => oppNum(a.allIn) - oppNum(b.allIn) },
    { key: 'saving', label: 'Most saved', cmp: (a, b) => oppNum(b.sortSavings) - oppNum(a.sortSavings) },
  ],
  filters: [
    { key: 'transfers', label: 'Transfers', test: (p) => oppHas(p, 'transfer', 'corridor', 'wire') },
    { key: 'card', label: 'Card spend', test: (p) => oppHas(p, 'card') },
  ],
});
Object.assign(OPP_MARKETPLACES.life, {
  sorts: [
    { key: 'match', label: 'Best match', cmp: (a, b) => oppNum(b.aiScore) - oppNum(a.aiScore) },
    { key: 'premium', label: 'Lowest premium', cmp: (a, b) => oppNum(a.monthly) - oppNum(b.monthly) },
    { key: 'cover', label: 'Highest cover', cmp: (a, b) => oppNum(b.cover) - oppNum(a.cover) },
  ],
  filters: [
    { key: 'nomedical', label: 'No medical exam', test: (p) => oppHas(p, 'not required') },
  ],
});
Object.assign(OPP_MARKETPLACES.income_protection, {
  sorts: [
    { key: 'match', label: 'Best match', cmp: (a, b) => oppNum(b.aiScore) - oppNum(a.aiScore) },
    { key: 'premium', label: 'Lowest premium', cmp: (a, b) => oppNum(a.monthly) - oppNum(b.monthly) },
  ],
  filters: [
    { key: 'shortwait', label: 'Short waiting period', test: (p) => oppNum(p.deferred) <= 3 },
    { key: 'to65', label: 'Pays to age 65', test: (p) => oppNum(p.toAge) >= 65 },
  ],
});
Object.assign(OPP_MARKETPLACES.home, {
  sorts: [
    { key: 'match', label: 'Best match', cmp: (a, b) => oppNum(b.aiScore) - oppNum(a.aiScore) },
    { key: 'premium', label: 'Lowest premium', cmp: (a, b) => oppNum(a.annual) - oppNum(b.annual) },
    { key: 'saving', label: 'Most saved', cmp: (a, b) => oppNum(b.sortSavings) - oppNum(a.sortSavings) },
  ],
  filters: [
    { key: 'contents', label: 'Includes contents', test: (p) => oppHas(p, 'contents') },
  ],
});
Object.assign(OPP_MARKETPLACES.car, {
  sorts: [
    { key: 'match', label: 'Best match', cmp: (a, b) => oppNum(b.aiScore) - oppNum(a.aiScore) },
    { key: 'premium', label: 'Lowest premium', cmp: (a, b) => oppNum(a.annual) - oppNum(b.annual) },
    { key: 'saving', label: 'Most saved', cmp: (a, b) => oppNum(b.sortSavings) - oppNum(a.sortSavings) },
  ],
  filters: [
    { key: 'comprehensive', label: 'Comprehensive', test: (p) => /comprehensive/i.test(p.scope || '') },
  ],
});

// ── Per-screen opportunity definitions ────────────────────────────────────────
// Consumed by the generic OpportunityDetailScreen. Strings only, no JSX.
const OPPORTUNITIES = {
  mortgage: {
    route: 'mortgage_optimization_detail',
    navLabel: 'Spending',
    category: 'mortgage',
    hero: {
      label: 'Mortgage reprice opportunity',
      value: MORTGAGE_BEST.totalSaved.toLocaleString(), dh: true,
      subtitle: `saved over your remaining ${MORTGAGE_CURRENT.remainingLabel}`,
      info: 'Net of all switching costs, at the best rate you qualify for.',
      twoStat: { leftLabel: 'Your payment today', leftValue: `${MORTGAGE_CURRENT.monthly.toLocaleString()}/mo`, rightLabel: 'At 3.74% fixed', rightValue: `${MORTGAGE_BEST.monthly.toLocaleString()}/mo` },
    },
    situation: {
      rows: [
        ['Outstanding balance', `AED ${MORTGAGE_CURRENT.balance.toLocaleString()}`],
        ['Current rate', `${MORTGAGE_CURRENT.rate}% · reverted from fixed`],
        ['Monthly payment', `AED ${MORTGAGE_CURRENT.monthly.toLocaleString()}`],
        ['Remaining term', MORTGAGE_CURRENT.remainingLabel],
      ],
    },
    recoLabel: 'Recommended · Himma AI',
    reco: [
      { productId: 'fab-home-fix', tags: ['Lowest eligible rate', '3-year fixed'] },
      { productId: 'mashreq-reprice', tags: ['No switching costs'] },
    ],
    compare: {
      label: 'Today vs 3.74% fixed',
      columns: ['Today', 'FAB 3.74%'],
      rows: [
        { label: 'Rate', a: '4.50%', b: '3.74%' },
        { label: 'Monthly payment', a: '2,840', b: MORTGAGE_BEST.monthly.toLocaleString(), hi: true },
        { label: 'Early settlement fee', sub: 'capped at 1% or AED 10K', a: '0', b: MORTGAGE_SWITCH_COSTS.earlySettlement.toLocaleString() },
        { label: 'Valuation + processing', a: '0', b: (MORTGAGE_SWITCH_COSTS.valuation + MORTGAGE_SWITCH_COSTS.processing).toLocaleString() },
        { label: 'Break-even point', a: 'n/a', b: `${MORTGAGE_BEST.breakEvenMonths} months`, hi: true },
        { label: 'Saved over term', a: 'n/a', b: MORTGAGE_BEST.totalSaved.toLocaleString(), hi: true },
      ],
      footnote: `All switching costs included: AED ${MORTGAGE_SWITCH_COSTS.earlySettlement.toLocaleString()} early settlement (the lower of 1% of balance or AED 10,000), AED ${MORTGAGE_SWITCH_COSTS.valuation.toLocaleString()} valuation, AED ${MORTGAGE_SWITCH_COSTS.processing.toLocaleString()} processing.`,
    },
    exploreLabel: 'Explore all mortgage offers',
    assumptions: [
      'Balance, rate, payment and remaining term come from your linked Mashreq mortgage.',
      'New payments assume the same remaining term (23 years) on the outstanding balance.',
      'Switching costs: early settlement capped at the lower of 1% of outstanding or AED 10,000, plus valuation and new-bank processing fees.',
      'Fixed rates revert to the lender\'s variable rate after the fixed period. The backtest assumes the headline rate for the full term.',
      'Only lenders whose minimum income you meet are recommended.',
    ],
  },

  loans: {
    route: 'loan_optimization_detail',
    navLabel: 'Spending',
    category: 'loans',
    hero: {
      label: 'Loan cost opportunity',
      value: LOANS_SAVING.toLocaleString(), dh: true,
      subtitle: 'less interest',
      info: 'By consolidating your personal loan and card balances into one facility at 5.49%.',
      twoStat: { leftLabel: 'Interest on current path', leftValue: `AED ${LOANS_OPP_DATA.consolidation.oldInterest.toLocaleString()}`, rightLabel: 'After consolidation', rightValue: `AED ${LOANS_OPP_DATA.consolidation.newInterest.toLocaleString()}` },
    },
    situation: {
      valueHeader: 'Interest to payoff',
      optionRows: LOANS_OPP_DATA.debts.map((d) => ({ name: d.name, sub: d.sub, value: `AED ${d.interestToMaturity.toLocaleString()}` })),
      note: {
        label: 'Why the auto loan isn’t refinanced',
        body: 'Your auto loan is a flat rate: 5.9% flat is roughly 10.8% on a reducing basis, but its early-settlement penalty would erase the refinance gain, so it stays. The cards at 33 to 36% are the expensive part.',
      },
    },
    recoLabel: 'Recommended · Himma AI',
    reco: [
      { productId: 'fab-consol', tags: ['Consolidate AED 25,680', '36 months'], detailLabel: 'See how this works', detail: 'Folds the Mashreq personal loan (AED 18,400 at 6.8%) and both card balances (AED 7,280 at 33 to 36%) into one payment. AED 775/mo instead of AED 1,285, and AED 3,575 less interest to payoff. Inputs: your balances, rates and minimum payments.' },
    ],
    compare: {
      label: 'Current path vs consolidation',
      columns: ['Today', 'Consolidated'],
      rows: [
        { label: 'Monthly payments', a: '1,285', b: '775', hi: true },
        { label: 'Highest rate carried', a: '36% APR', b: '5.49%' },
        { label: 'Interest to payoff', a: LOANS_OPP_DATA.consolidation.oldInterest.toLocaleString(), b: LOANS_OPP_DATA.consolidation.newInterest.toLocaleString(), hi: true },
        { label: 'Debt-free date', a: 'Open-ended', b: '36 months' },
        { label: 'Processing fee', a: '0', b: '257' },
      ],
      footnote: 'Flat-rate balances are converted to reducing-rate equivalents before comparison. Card interest assumes minimum payments continue.',
    },
    exploreLabel: 'Explore consolidation offers',
    assumptions: [
      'Balances, rates and payments come from your linked loan and card accounts.',
      'Card interest to payoff assumes you keep paying minimums on 33 to 36% APR revolving balances.',
      'The auto loan is excluded: its flat-rate early-settlement penalty outweighs the refinance saving.',
      'Flat rates are converted to reducing equivalents (5.9% flat ≈ 10.8% reducing) so comparisons are like for like.',
      'Consolidation figures assume 36 months at 5.49% reducing with a 1% processing fee.',
    ],
  },

  fx: {
    route: 'fx_leakage_detail',
    navLabel: 'Spending',
    category: 'fx',
    hero: {
      label: 'FX fees opportunity',
      value: FX_SAVING.toLocaleString(), dh: true,
      subtitle: 'you would have saved in the last 12 months using the cheapest provider on each corridor',
      twoStat: { leftLabel: 'You paid in fees + spread', leftValue: `AED ${FX_PAID.toLocaleString()}`, rightLabel: 'Cheapest routes', rightValue: `AED ${FX_BEST.toLocaleString()}` },
    },
    situation: {
      intro: 'Your cross-currency activity, last 12 months:',
      optionRows: FX_CORRIDORS.map((c) => ({ name: c.corridor, sub: `${c.use} · AED ${c.volume.toLocaleString()} via ${c.via} at ~${c.paidPct}%`, value: `AED ${c.paid.toLocaleString()}`, valueSub: 'fees + spread' })),
      note: 'Costs include both visible fees and the exchange-rate spread versus mid-market at the time of each transaction.',
    },
    recoLabel: 'Recommended per corridor · Himma AI',
    reco: [
      { productId: 'atlas-remit', tags: ['AED → GBP', 'AED → INR'], why: 'Cheapest on your two transfer corridors at 0.45% all-in vs the 1.3 to 2.1% you pay. On your AED 42,400 of transfers, that is AED 591 paid down to about AED 184.' },
      { productId: 'wio-multi', tags: ['AED → EUR card spend'], why: 'Your EUR card spend carries a 3.5% bank markup, the single biggest leak (AED 770). A multi-currency card at 0.2% cuts it to about AED 44.' },
    ],
    compare: {
      label: '12-month backtest by corridor',
      columns: ['You paid', 'Best route'],
      rows: FX_CORRIDORS.map((c) => ({ label: c.corridor, sub: `${c.bestProvider} at ${c.bestPct}%`, a: c.paid.toLocaleString(), b: c.best.toLocaleString(), hi: true })),
      totals: { label: 'Total', a: FX_PAID.toLocaleString(), b: FX_BEST.toLocaleString() },
      footnote: `Had you used the best provider per corridor over the last 12 months, you would have saved AED ${FX_SAVING.toLocaleString()}.`,
    },
    exploreLabel: 'Explore FX providers',
    assumptions: [
      'Corridors and volumes are derived from your international transfers and foreign-currency card transactions over the last 12 months.',
      'Costs paid include transfer fees plus the spread versus the mid-market rate at transaction time.',
      'Provider pricing uses current advertised rates applied to your historical volumes.',
      'Transfer limits, delivery speed and recipient options vary by provider.',
    ],
  },

  life: {
    route: 'life_insurance_finder_detail',
    navLabel: 'Protection',
    category: 'life',
    // Merged from the former "No life cover detected" insight: its gap hero +
    // "Why life cover" rationale sit above this screen's reco and comparison.
    gapHero: {
      icon: 'shieldCheck',
      title: 'No life cover detected',
      subtitle: 'Premiums rise with age',
      rows: [
        ['Age', '31'],
        ['Monthly income', 'AED 24,800'],
      ],
    },
    whyLabel: 'Why life cover',
    why: [
      ['Income continues', 'Your family keeps receiving money if your income stops.'],
      ['Debts stay covered', 'The mortgage gets settled instead of passing on as a burden.'],
      ['Cheaper now', 'Premiums lock in at your current age. Waiting costs more.'],
    ],
    recoLabel: 'Recommended · Himma AI',
    reco: [
      { productId: 'hayah-term', tags: ['AED 1.6M · 20 years', 'No medical exam'], why: 'Cheapest premium at the recommended cover for your age (31) and profile, with no medical exam below AED 2M. Locking the rate now matters: premiums rise roughly 5 to 8% per year of age at entry.' },
      { productId: 'zurich-term', tags: ['Runner-up'], why: 'AED 7/mo more for comparable cover. Worth it if you want critical-illness as an add-on later, which Hayah does not offer.' },
    ],
    compare: {
      label: 'Doing nothing vs covered',
      columns: ['Today', 'With cover'],
      rows: [
        { label: 'Family receives if you pass', a: '0', b: '1,600,000', hi: true },
        { label: 'Mortgage settled', a: 'No', b: 'Yes' },
        { label: 'Monthly cost', a: '0', b: '102' },
        { label: 'Share of income', a: 'n/a', b: '0.4%' },
      ],
      footnote: 'Premium fixed for the full 20-year term at your entry age.',
    },
    exploreLabel: 'Explore all life cover',
    assumptions: [
      'Cover need = 5 years of income replacement + outstanding liabilities − liquid assets.',
      'Income and liabilities come from your linked accounts; dependants from your profile.',
      'Premiums are indicative for age 31, non-smoker, and subject to underwriting.',
      'No existing life policy was detected in 12 months of transactions; employer benefits, if any, are not included.',
    ],
  },

  income_protection: {
    route: 'disability_insurance_detail',
    navLabel: 'Insurance',
    category: 'income_protection',
    hero: {
      label: 'Income at risk',
      value: '24,800', dh: true,
      subtitle: 'per month',
      info: 'Stops if illness or injury keeps you from working. No income-protection premium detected in your transactions.',
      twoStat: { leftLabel: 'Insurable benefit · 60%', leftValue: 'AED 14,880/mo', rightLabel: 'From', rightValue: 'AED 118/mo' },
    },
    situation: {
      rows: [
        ['Monthly income', 'AED 24,800'],
        ['Fixed commitments', 'AED 5,000/mo'],
        ['Emergency fund', 'AED 24,000'],
        ['Existing cover', 'None detected'],
      ],
      note: 'Your fixed debt payments alone are AED 5,000/mo. With under 2 months of buffer, a long absence from work would bite quickly.',
    },
    recoLabel: 'Recommended · Himma AI',
    reco: [
      { productId: 'sukoon-income', tags: ['AED 14,880/mo benefit', '3-month wait'], why: 'Lowest premium for the standard 60% benefit, paying until age 60 or return to work. The 3-month deferred period roughly matches your emergency fund, which keeps the premium down. Inputs: income, fixed commitments, buffer size.' },
    ],
    compare: {
      label: 'Income stops vs covered',
      columns: ['Uncovered', 'Covered'],
      rows: [
        { label: 'Monthly income after 3 months', a: '0', b: '14,880', hi: true },
        { label: 'Fixed commitments covered', a: 'From savings', b: 'Yes' },
        { label: 'Savings run out in', a: '~2 months', b: 'Protected' },
        { label: 'Monthly cost', a: '0', b: '118' },
      ],
      footnote: 'Benefit is tax-free and pays until age 60 or return to work, whichever is sooner.',
    },
    exploreLabel: 'Explore income protection',
    assumptions: [
      'Income is your average salary credit over the last 12 months.',
      'Benefit is capped at 60% of income by insurers; premiums are indicative for age 31, office-based work.',
      'The deferred period is matched to your emergency fund (about 2 months of essentials).',
      'Employer sick-pay policies vary and end with the job; they are not counted as cover.',
    ],
  },

  home: {
    route: 'home_insurance_detail',
    navLabel: 'Insurance',
    category: 'home',
    hero: {
      label: 'Uninsured contents',
      value: '150,400', dh: true,
      subtitle: 'of contents and valuables in your owned JVC Studio with no cover.',
    },
    whyLabel: 'Why it matters',
    whyCollapsible: true,
    why: [
      ['Contents aren\'t covered', 'Your policy insures the building, but AED 150,400 of furniture, electronics and valuables would not be replaced after theft, fire or water damage.'],
      ['Valuables need scheduling', 'AED 46K of gold jewellery sits above standard per-item limits, so it only pays out if listed on the policy.'],
      ['Cover can cost less', 'Adding contents through the right policy can come in below your current building-only premium.'],
    ],
    recoLabel: 'Recommended · Himma AI',
    recoHideSub: true,
    recoClampWhy: true,
    reco: [
      { productId: 'sukoon-home', tags: ['Building + contents AED 200K', 'Cheaper than today'], why: 'Covers the building like your current policy and adds AED 200K of contents, for AED 255/yr less than you pay now. Schedule the jewellery at no extra premium up to AED 50K. Inputs: property value, contents estimate, current premium.' },
    ],
    exploreLabel: 'Explore home cover',
    assumptions: [
      'Owner status and property value come from your tracked JVC Studio asset.',
      'The current premium is detected from a recurring AXA payment in your transactions.',
      'Contents are estimated from your tracked valuables plus a furnishing allowance for the apartment size.',
      'Quotes assume standard excess (AED 500) and no claims in the last 3 years.',
    ],
  },

  car: {
    route: 'car_insurance_detail',
    navLabel: 'Insurance',
    category: 'car',
    hero: {
      label: 'Car cover opportunity',
      value: '510', dh: true,
      subtitle: 'less per year',
      info: 'For equivalent comprehensive cover, switching at your August renewal.',
      twoStat: { leftLabel: 'AXA renewal quote', leftValue: 'AED 2,400/yr', rightLabel: 'Best equivalent', rightValue: 'AED 1,890/yr' },
    },
    situation: {
      rows: [
        ['Vehicle', '2022 Mazda CX-5 · AED 74,500'],
        ['Current policy', 'AXA · comprehensive'],
        ['Premium detected', 'AED 2,400'],
      ],
    },
    reminder: { label: 'Remind me 3 weeks before renewal', confirm: 'Reminder set for 28 Jul 2026' },
    recoLabel: 'Recommended · Himma AI',
    reco: [
      { productId: 'sukoon-motor', tags: ['Switch at renewal', 'Agency repair included'] },
    ],
    compare: {
      label: 'AXA renewal vs recommended',
      columns: ['AXA', 'Sukoon'],
      rows: [
        { label: 'Cover', a: 'Comprehensive', b: 'Comprehensive' },
        { label: 'Agency repair', a: '+AED 400', b: 'Included', hi: true },
        { label: 'Excess', a: '500', b: '500' },
        { label: 'Roadside assistance', a: 'Included', b: 'Included' },
        { label: 'Premium per year', a: '2,400', b: '1,890', hi: true },
      ],
      footnote: 'Switching at renewal avoids cancellation fees and keeps your no-claims record intact.',
    },
    exploreLabel: 'Explore car cover',
    assumptions: [
      'Current premium and renewal date are inferred from your last AXA payment (18 Aug 2025).',
      'Vehicle value comes from your tracked asset (AED 74,500) and is the insured sum across quotes.',
      'Quotes assume a 3-year no-claims history and a clean licence.',
      'Comprehensive quotes are matched on excess and core cover; add-ons are listed separately.',
    ],
  },
};

Object.assign(window, {
  OPP_PROFILE,
  OPP_PARTNER,
  OPP_CONSENT_ITEMS,
  OPP_DISCLAIMER,
  CARD_SPEND_12M,
  CARD_SPEND_TOTAL,
  CARDS_CATALOG,
  CARD_REWARDS_CURRENT,
  CARD_REWARDS_RECO,
  CARD_REWARDS_ASSUMPTIONS,
  getCardRewardsBacktest,
  cardEarnOn,
  OPP_MARKETPLACES,
  OPPORTUNITIES,
  MORTGAGE_CURRENT,
  MORTGAGE_SWITCH_COSTS,
  getMortgageReprice,
  LOANS_OPP_DATA,
  FX_CORRIDORS,
  INSURANCE_INPUTS,
});
