// Embedded venue savings calculator — a lightweight, GoodCup-style inline tool
// that lives right in the "Why restaurants choose LÜP" section (venues only).
//
// The venue enters TWO numbers it already knows; instead of guessing one
// adoption rate, the tool shows savings across a RANGE of uptake (1-in-10 →
// all) in a simple table, so the venue picks the row it believes. Network
// assumptions (wash, fee, bowls/order, open days) are baked in and disclosed in
// the transparency note. Client-side only.
//
// ⚠️ Every number here comes from window.LUP_ECON (economics.js), which mirrors
// the app repo's lib/economics.ts. Nothing is hardcoded — three different
// savings rates used to be live across the site, the app and the leaflet.
window.SavingsCalc = function SavingsCalc() {
  const h = React.createElement;
  const E = window.LUP_ECON;

  const FEE = E.NETWORK_FEE_PER_BOWL;
  const WASH = E.WASH_COST_PER_BOWL;
  const BPO = E.BOWLS_PER_ORDER;
  const OPEN_DAYS = E.OPEN_DAYS_PER_WEEK;
  const WEEKS = E.WEEKS_PER_YEAR;

  const [takeaway, setTakeaway] = React.useState(String(E.DEFAULT_MEALS_PER_DAY));
  const [disp, setDisp] = React.useState(E.DISPOSABLE_COST_PER_CONTAINER.toFixed(2));

  const numT = Math.max(0, parseFloat(takeaway) || 0);
  const numD = Math.max(0, parseFloat(disp) || 0);

  // Per-BOWL margin is adoption-independent; annual saving + containers scale
  // linearly with the share of meals served in a LÜP bowl. These were named
  // "perOrder"/"ordersPerYear" but have always been per BOWL — an order is 1.1
  // bowls, so the per-order figure is perBowl x BPO (see savingPerOrder below).
  const perBowl = Math.max(0, numD - (FEE + WASH));
  const perOrder = perBowl * BPO;
  const bowlsPerYearAt = (a) => numT * a * BPO * OPEN_DAYS * WEEKS;
  const annualAt = (a) => bowlsPerYearAt(a) * perBowl;
  const keptPct = numD > 0 ? Math.round((perBowl / numD) * 100) : 0;

  const LEVELS = E.ADOPTION_LADDER.map((a) => ({ n: Math.round(a * 10), pct: Math.round(a * 100) + '%' }));

  const money = (v, d) => '$' + Number(v).toLocaleString('en-AU', { minimumFractionDigits: d || 0, maximumFractionDigits: d || 0 });
  const int = (v) => Math.round(v).toLocaleString('en-AU');

  const card = { background: 'var(--ivory)', border: '1px solid var(--border-cream)', borderRadius: 14 };

  const field = (label, value, onChange, step) =>
    h('label', { style: { display: 'flex', flexDirection: 'column', gap: 6 } },
      h('span', { style: { fontSize: 13, color: 'var(--stone)', lineHeight: 1.3 } }, label),
      h('input', {
        type: 'number', inputMode: 'decimal', value: value, min: 0, step: step,
        onChange: (ev) => onChange(ev.target.value),
        style: {
          width: '100%', padding: '11px 13px', fontSize: 16, fontWeight: 500,
          color: 'var(--charcoal)', background: 'var(--ivory)',
          border: '1px solid var(--border-cream)', borderRadius: 10, outline: 'none',
        },
      }),
    );

  const stat = (value, caption) =>
    h('div', { style: { ...card, padding: '15px 14px', textAlign: 'center' } },
      h('div', { style: { fontFamily: 'var(--font-serif)', fontSize: 24, fontWeight: 500, lineHeight: 1, color: '#3E7C4F' } }, value),
      h('div', { style: { fontSize: 12.5, color: 'var(--stone)', marginTop: 7, lineHeight: 1.35 } }, caption),
    );

  // Ten person silhouettes; the first `n` are filled (chose LÜP), the rest faint.
  const people = (n) =>
    h('div', { style: { display: 'flex', gap: 4, marginTop: 11, flexWrap: 'wrap' } },
      Array.from({ length: 10 }).map((_, k) =>
        h('svg', {
          key: k, viewBox: '0 0 24 24', width: 21, height: 21,
          fill: k < n ? '#3E7C4F' : 'rgba(58,53,48,0.15)',
          'aria-hidden': true, style: { flexShrink: 0 },
        },
          h('circle', { cx: 12, cy: 7, r: 4.2 }),
          h('path', { d: 'M12 13c-4.4 0-8 2.9-8 6.5V21h16v-1.5c0-3.6-3.6-6.5-8-6.5z' }),
        )),
    );

  return h('div', {
    style: { background: 'var(--ivory)', border: '1px solid var(--border-cream)', borderRadius: 20, padding: 'clamp(22px, 4vw, 38px)', maxWidth: 680, margin: '0 auto' },
  },
    // ── Title ──
    h('div', { style: { textAlign: 'center', marginBottom: 22 } },
      h('div', { className: 'eyebrow', style: { justifyContent: 'center', marginBottom: 12 } },
        h('span', { className: 'dot' }), 'Your savings'),
      h('h3', {
        style: { fontFamily: 'var(--font-serif)', fontSize: 'clamp(24px, 3vw, 32px)', fontWeight: 500, color: 'var(--charcoal)', lineHeight: 1.12, letterSpacing: '-0.01em' },
      },
        'Every bowl you don’t buy is money you keep. ',
        h('span', { className: 'serif-accent' }, 'Here’s yours.'),
      ),
      h('p', { style: { fontSize: 14.5, color: 'var(--stone)', marginTop: 10 } },
        'Two numbers you already know — it updates as you type.'),
    ),

    // ── Inputs ──
    h('div', {
      style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(190px, 1fr))', gap: 16, marginBottom: 22 },
    },
      field('Meals per day', takeaway, setTakeaway, 10),
      field('What you pay per container + lid ($)', disp, setDisp, 0.05),
    ),

    // ── Savings across adoption levels ──
    h('div', { style: { ...card, padding: 0, overflow: 'hidden', marginBottom: 14, boxShadow: '0 8px 24px rgba(184,80,31,0.12)' } },
      // Terracotta header row — anchors the table and makes it pop.
      h('div', {
        style: { display: 'flex', justifyContent: 'space-between', gap: 12, padding: '13px 18px', background: 'var(--terracotta)' },
      },
        h('span', { style: { fontSize: 12, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', color: 'var(--ivory)' } }, 'Customers choosing LÜP'),
        h('span', { style: { fontSize: 12, fontWeight: 700, letterSpacing: '0.05em', textTransform: 'uppercase', color: 'var(--ivory)', textAlign: 'right' } }, 'Savings per year'),
      ),
      LEVELS.map((lvl, i) => h('div', {
        key: lvl.pct,
        style: { padding: '14px 18px', background: i % 2 ? 'var(--parchment)' : 'var(--ivory)', borderTop: i === 0 ? 'none' : '1px solid var(--border-cream)' },
      },
        h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 } },
          h('div', {},
            h('b', { style: { color: 'var(--charcoal)', fontSize: 15.5 } }, lvl.n + ' in 10'),
            h('span', { style: { color: 'var(--stone)', fontSize: 13 } }, '  ·  ' + lvl.pct),
            h('div', { style: { fontSize: 11.5, color: 'var(--stone)', marginTop: 3 } }, '~' + int(bowlsPerYearAt(lvl.n / 10)) + ' containers avoided'),
          ),
          h('div', { style: { fontFamily: 'var(--font-serif)', fontWeight: 500, fontSize: 26, lineHeight: 1, color: '#3E7C4F', whiteSpace: 'nowrap' } }, money(annualAt(lvl.n / 10))),
        ),
        people(lvl.n),
      )),
    ),

    // ── Constant reassurances ──
    h('div', {
      style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: 12, marginBottom: 14 },
    },
      stat(money(perBowl, 2), 'kept on every LÜP bowl (after fee + wash)'),
      stat(keptPct + '%', 'of your packaging spend kept'),
      stat('$0', 'upfront · free fleet we own, stock & rebalance'),
    ),

    // ── Transparency note ──
    h('div', { style: { background: 'var(--parchment)', border: '1px solid var(--border-cream)', borderRadius: 12, padding: '15px 18px' } },
      h('div', { style: { fontSize: 11, fontWeight: 600, letterSpacing: '0.06em', textTransform: 'uppercase', color: 'var(--stone)', marginBottom: 8 } }, 'What’s baked in'),
      h('p', { style: { fontSize: 12.5, color: 'var(--stone)', lineHeight: 1.6, margin: 0 } },
        h('b', { style: { color: 'var(--charcoal)' } }, E.money(FEE, 2) + ' + GST'), ' LÜP fee per bowl issued (only when a customer borrows) — ' + E.money(perOrder, 2) + ' on a typical ' + BPO + '-bowl order · ',
        h('b', { style: { color: 'var(--charcoal)' } }, '~' + E.money(WASH, 2)), '/bowl to wash in your existing dishwasher · ',
        h('b', { style: { color: 'var(--charcoal)' } }, '~' + BPO), ' bowls/order · ' + OPEN_DAYS + ' open days/week · ',
        h('b', { style: { color: 'var(--charcoal)' } }, '$0 upfront'), ' — the free fleet is sized to your volume (about ' + E.int(E.fleetSize(numT, E.DEFAULT_ADOPTION)) + ' bowls at ' + Math.round(E.DEFAULT_ADOPTION * 100) + '% adoption) and we restock & rebalance. If a customer doesn\'t bring a bowl back within 7 days they buy it for ' + E.KEEP_PRICE_LABEL + ' — never billed to you. Bowls that go missing from your own venue stock are separate: we reconcile fleet counts with you periodically, and during the pilot we\'re only tracking, not charging.',
      ),
      h('p', { style: { fontSize: 11.5, color: 'var(--stone)', opacity: 0.85, lineHeight: 1.5, margin: '9px 0 0', paddingTop: 9, borderTop: '1px dashed var(--border-cream)' } },
        'Savings = (your disposable cost − ' + E.money(FEE, 2) + ' fee − ~' + E.money(WASH, 2) + ' wash) × bowls issued. ' + E.GST_FOOTNOTE),
    ),
  );
};
