// app.jsx — Take-Home Pay calculator UI (Aurora Glass shell)
const { useState, useMemo, useEffect } = React;
const PE = window.PayEngine;

const SL_PLANS = [
  { key: 'none', label: 'None' },
  { key: 'plan1', label: 'Plan 1' },
  { key: 'plan2', label: 'Plan 2' },
  { key: 'plan4', label: 'Plan 4' },
  { key: 'plan5', label: 'Plan 5' },
  { key: 'pgl', label: 'Postgrad' },
];

const PRESETS = [
  { label: '£25k', gross: 25000 },
  { label: '£35k', gross: 35000 },
  { label: '£50k', gross: 50000 },
  { label: '£75k', gross: 75000 },
  { label: '£100k', gross: 100000 },
  { label: '£150k', gross: 150000 },
];

const DEFAULTS = {
  gross: 45000,
  bonus: 0,
  region: 'ruk',
  pensionPct: 5,
  pensionType: 'sacrifice',
  planKey: 'plan5',
  pglAlso: false,
  overSPA: false,
};

function AnimatedNumber({ value, format = (v) => v, duration = 600 }) {
  const [shown, setShown] = useState(value);
  useEffect(() => {
    let raf, start = null; const from = shown;
    const step = (ts) => {
      if (start === null) start = ts;
      const t = Math.min(1, (ts - start) / duration);
      const e = 1 - Math.pow(1 - t, 3);
      setShown(from + (value - from) * e);
      if (t < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [value]);
  return <span>{format(shown)}</span>;
}

function Slider({ label, value, onChange, min, max, step, fmt }) {
  return (
    <div className="slider-row">
      <div className="head"><label>{label}</label><span className="val">{fmt ? fmt(value) : value}</span></div>
      <input type="range" min={min} max={max} step={step} value={value} onChange={(e) => onChange(Number(e.target.value))} />
    </div>
  );
}

function Toggle({ label, on, onChange }) {
  return (
    <div className="toggle-row">
      <span className="t-label">{label}</span>
      <div className={`tgl ${on ? 'on' : ''}`} onClick={() => onChange(!on)} role="switch" aria-checked={on} tabIndex={0}
           onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onChange(!on); } }} />
    </div>
  );
}

function App() {
  const [inp, setInp] = useState(DEFAULTS);
  const [period, setPeriod] = useState('year'); // year | month | week
  const set = (k) => (v) => setInp((s) => ({ ...s, [k]: v }));

  const r = useMemo(() => PE.calculate(inp), [inp]);

  const div = period === 'year' ? 1 : period === 'month' ? 12 : 52;
  const per = (n) => n / div;
  const gbp = (n, dp = 0) => PE.gbp(n, dp);

  const items = [
    { key: 'take', name: 'Take-home pay', sub: `${(r.keepRate * 100).toFixed(1)}% of gross`, amt: r.takeHome, color: 'var(--c-take)' },
    { key: 'tax', name: 'Income Tax', sub: inp.region === 'scotland' ? 'Scottish rates' : 'England/Wales/NI', amt: r.incomeTax, color: 'var(--c-tax)' },
    { key: 'ni', name: 'National Insurance', sub: inp.overSPA ? 'Over State Pension age — exempt' : 'Class 1 employee', amt: r.ni, color: 'var(--c-ni)' },
    { key: 'sl', name: 'Student loan', sub: inp.planKey === 'none' ? 'None' : SL_PLANS.find((p) => p.key === inp.planKey)?.label + (inp.pglAlso ? ' + PGL' : ''), amt: r.studentLoan, color: 'var(--c-sl)' },
    { key: 'pen', name: 'Pension', sub: inp.pensionType === 'sacrifice' ? 'Salary sacrifice' : inp.pensionType === 'netpay' ? 'Net pay (workplace)' : 'None', amt: r.pension, color: 'var(--c-pension)' },
  ].filter((it) => it.key === 'take' || it.amt > 0.5);

  const segOf = (parts) => parts.map((p) => `${p.color} ${p.from}%, ${p.color} ${p.to}%`);
  // stacked bar fractions of gross
  let acc = 0;
  const stack = items.map((it) => {
    const frac = r.gross > 0 ? (it.amt / r.gross) * 100 : 0;
    const seg = { color: it.color, grow: frac };
    acc += frac; return seg;
  });

  function exportReport() {
    const region = inp.region === 'scotland' ? 'Scotland' : 'England / Wales / NI';
    const plan = SL_PLANS.find((p) => p.key === inp.planKey)?.label || 'None';
    const g = (n) => PE.gbp(n);
    const pct = (n) => r.gross > 0 ? (n / r.gross * 100).toFixed(1) + '%' : '0%';
    const tapering = r.gross > 100000 && r.gross < 125140;
    window.PremiumReport.generate({
      tool: 'Take-Home Pay',
      accent: '#33a06a',
      scenario: `${g(r.gross)} gross${inp.bonus ? ` (incl. ${g(inp.bonus)} bonus)` : ''} · ${region} · ${inp.pensionPct}% ${inp.pensionType} pension · ${plan}${inp.pglAlso && inp.planKey !== 'pgl' ? ' + PGL' : ''}`,
      verdict: {
        line: `You keep ${(r.keepRate * 100).toFixed(1)}p in every £1 — ${g(r.takeHome / 12)} a month after everything.`,
        reasoning: `On ${g(r.gross)} you take home ${g(r.takeHome)} a year. Your effective deduction rate is ${(r.effectiveTaxRate * 100).toFixed(1)}%, but the next £1 you earn is taxed at a marginal ${(r.marginalRate * 100).toFixed(0)}% — worth knowing before you chase a pay rise or pay more into a pension.`,
      },
      metrics: [
        { label: 'Take-home / yr', value: g(r.takeHome), accent: '#1f8a5b' },
        { label: 'Take-home / mo', value: g(r.takeHome / 12), accent: '#1f8a5b' },
        { label: 'Keep-rate', value: (r.keepRate * 100).toFixed(1) + 'p / £1' },
        { label: 'Effective rate', value: (r.effectiveTaxRate * 100).toFixed(1) + '%' },
        { label: 'Marginal rate', value: (r.marginalRate * 100).toFixed(0) + '%' },
        { label: 'Personal allowance', value: g(r.personalAllowance) },
      ],
      tables: [{
        title: 'Where your gross pay goes',
        headers: ['Component', 'Per year', 'Per month', '% of gross'],
        rows: [
          ['Take-home pay', g(r.takeHome), g(r.takeHome / 12), pct(r.takeHome)],
          ['Income Tax', g(r.incomeTax), g(r.incomeTax / 12), pct(r.incomeTax)],
          ['National Insurance', g(r.ni), g(r.ni / 12), pct(r.ni)],
          ['Student loan', g(r.studentLoan), g(r.studentLoan / 12), pct(r.studentLoan)],
          ['Pension', g(r.pension), g(r.pension / 12), pct(r.pension)],
        ],
        highlightRow: 0,
      }],
      notes: [
        inp.pensionType === 'sacrifice'
          ? 'Your pension uses salary sacrifice, which lowers your taxable pay, NI and student-loan deductions — the most tax-efficient route.'
          : 'Switching to a salary-sacrifice pension would cut your NI and student-loan deductions too, not just your Income Tax.',
        tapering
          ? 'You\u2019re in the £100k–£125,140 band where the personal allowance tapers away — an effective 60% marginal rate. Pension contributions are especially powerful here.'
          : 'Your marginal rate is what matters for a pay rise or bonus — it\u2019s what you lose on the next pound, not the average across all your pay.',
        `Figures use ${PE.CONFIG.taxYear} UK rates and assume a standard tax code.`,
      ],
    });
  }

  return (
    <React.Fragment>
      <div className="aurora"><span className="a"></span><span className="b"></span><span className="c"></span></div>
      <div className="app" data-screen-label="Take-Home Pay">
        <aside className="sidebar">
          <nav className="rail-nav">
            <div className="nav-group">
              <div className="nav-group-label">Calculate</div>
              <button className="nav-item active"><span className="ni-dot" /><span className="ni-label">Take-home pay</span></button>
            </div>
            <div className="nav-group">
              <div className="nav-group-label">Quick salary</div>
              {PRESETS.map((p) => (
                <button key={p.label} className={`nav-item ${inp.gross === p.gross ? 'active' : ''}`} onClick={() => set('gross')(p.gross)}>
                  <span className="ni-dot" /><span className="ni-label">{p.label} / year</span>
                </button>
              ))}
            </div>
          </nav>
          <div className="rail-foot">
            <div className="rail-foot-label">Your pay</div>
            <div className="rail-foot-row"><span>Gross</span><b>{gbp(r.gross)}</b></div>
            <div className="rail-foot-row"><span>Deductions</span><b>{gbp(r.totalDeductions)}</b></div>
            <div className="rail-foot-row hero"><span>Take-home / mo</span><b>{gbp(r.takeHome / 12)}</b></div>
            <div className="rail-foot-note">{PE.CONFIG.taxYear} rates · estimate only</div>
          </div>
        </aside>

        <main className="main">
          <div className="topbar">
            <div>
              <h1>Take-home <span className="accent">pay</span>.</h1>
              <div className="sub">What actually lands in your account after tax, NI, pension and student loan — recalculated live.</div>
            </div>
            <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
            <div className="seg">
              {['year', 'month', 'week'].map((p) => (
                <button key={p} className={period === p ? 'active' : ''} onClick={() => setPeriod(p)}>Per {p}</button>
              ))}
            </div>
            <button onClick={exportReport} style={{
              flex: '0 0 auto', display: 'inline-flex', alignItems: 'center', gap: 7, whiteSpace: 'nowrap',
              fontFamily: 'inherit', fontSize: 13, fontWeight: 600, cursor: 'pointer',
              padding: '9px 15px', borderRadius: 10, border: '1px solid transparent', color: '#04231c',
              background: 'linear-gradient(135deg, oklch(.7 .15 165), oklch(.66 .15 150))',
              boxShadow: '0 8px 24px -12px oklch(.6 .15 160)',
            }}>↓ PDF report</button>
            </div>
          </div>

          <div className="grid grid-main">
            {/* INPUTS */}
            <div className="stack">
              <div className="card">
                <h3 className="card-title">Your salary</h3>
                <p className="card-sub">Gross, before anything is taken</p>
                <div className="input-row">
                  <label>Annual gross salary</label>
                  <div style={{ position: 'relative' }}>
                    <span style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', color: 'var(--ink-3)', fontFamily: 'var(--font-mono)', fontSize: 15, pointerEvents: 'none' }}>£</span>
                    <input className="input" type="number" value={inp.gross} step={500} min={0} max={2000000}
                           onChange={(e) => set('gross')(Number(e.target.value) || 0)} style={{ paddingLeft: 24 }} />
                  </div>
                </div>
                <div style={{ height: 14 }} />
                <Slider label="Annual bonus" value={inp.bonus} min={0} max={100000} step={500} onChange={set('bonus')} fmt={(v) => gbp(v)} />
                <div style={{ height: 16 }} />
                <label className="label" style={{ display: 'block', marginBottom: 8 }}>Where you live</label>
                <div className="seg" style={{ width: '100%' }}>
                  {[{ k: 'ruk', l: 'England / Wales / NI' }, { k: 'scotland', l: 'Scotland' }].map((o) => (
                    <button key={o.k} className={inp.region === o.k ? 'active' : ''} onClick={() => set('region')(o.k)} style={{ flex: 1 }}>{o.l}</button>
                  ))}
                </div>
              </div>

              <div className="card">
                <h3 className="card-title">Pension</h3>
                <p className="card-sub">Contributions before take-home</p>
                <Slider label="Contribution" value={inp.pensionPct} min={0} max={40} step={0.5} onChange={set('pensionPct')} fmt={(v) => `${v}%`} />
                <div style={{ height: 14 }} />
                <div className="seg" style={{ width: '100%' }}>
                  {[{ k: 'sacrifice', l: 'Sacrifice' }, { k: 'netpay', l: 'Net pay' }, { k: 'none', l: 'None' }].map((o) => (
                    <button key={o.k} className={inp.pensionType === o.k ? 'active' : ''} onClick={() => set('pensionType')(o.k)} style={{ flex: 1 }}>{o.l}</button>
                  ))}
                </div>
                <p className="bd-sub" style={{ marginTop: 10, lineHeight: 1.5 }}>
                  {inp.pensionType === 'sacrifice' && 'Salary sacrifice cuts your taxable pay — you save Income Tax, NI and student-loan deductions on it.'}
                  {inp.pensionType === 'netpay' && 'Net-pay (workplace) gives Income Tax relief, but NI and student loan still apply to the full salary.'}
                  {inp.pensionType === 'none' && 'No pension contribution modelled.'}
                </p>
              </div>

              <div className="card">
                <h3 className="card-title">Student loan</h3>
                <p className="card-sub">Repaid through payroll above the threshold</p>
                <div className="plan-grid">
                  {SL_PLANS.map((p) => (
                    <button key={p.key} className={`chipbtn ${inp.planKey === p.key ? 'active' : ''}`} onClick={() => set('planKey')(p.key)}>{p.label}</button>
                  ))}
                </div>
                <div className="div-h" />
                <Toggle label="Also repaying a Postgraduate loan" on={inp.pglAlso} onChange={set('pglAlso')} />
                <Toggle label="Over State Pension age (no NI)" on={inp.overSPA} onChange={set('overSPA')} />
              </div>
            </div>

            {/* RESULTS */}
            <div className="stack">
              <div className="card">
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', flexWrap: 'wrap', gap: 16 }}>
                  <div className="result-hero">
                    <span className="label">Take-home · per {period}</span>
                    <span className="num num-xl grad"><AnimatedNumber value={per(r.takeHome)} format={(v) => gbp(v)} /></span>
                    <span className="muted" style={{ fontSize: 13, marginTop: 6 }}>from {gbp(per(r.gross))} gross · keep {(r.keepRate * 100).toFixed(1)}p in every £1</span>
                  </div>
                </div>

                <div style={{ height: 22 }} />
                <span className="label" style={{ display: 'block', marginBottom: 8 }}>Where your {gbp(r.gross)} goes</span>
                <div className="stackbar">
                  {stack.map((s, i) => <i key={i} style={{ background: s.color, flexGrow: s.grow, flexBasis: 0 }} />)}
                </div>
                <div className="legend">
                  {items.map((it) => (
                    <span key={it.key}><i style={{ background: it.color }} />{it.name} <b>{gbp(it.amt)}</b></span>
                  ))}
                </div>
              </div>

              <div className="card">
                <h3 className="card-title">Breakdown</h3>
                <p className="card-sub">Annual figures · {PE.CONFIG.taxYear}</p>
                {items.map((it) => (
                  <div key={it.key} className="bd-row">
                    <span className="bd-dot" style={{ background: it.color }} />
                    <span className="bd-name">{it.name}<div className="bd-sub">{it.sub}</div></span>
                    <span className="bd-amt" style={{ color: it.key === 'take' ? 'var(--c-take)' : 'var(--ink-0)' }}>
                      {it.key === 'take' ? '' : '−'}{gbp(it.amt)}
                    </span>
                    <span className="bd-pct">{r.gross > 0 ? ((it.amt / r.gross) * 100).toFixed(1) : '0.0'}%</span>
                  </div>
                ))}
              </div>

              <div className="grid grid-2">
                <div className="pill-stat">
                  <span className="label">Effective tax rate</span>
                  <span className="num" style={{ color: 'var(--c-tax)' }}><AnimatedNumber value={r.effectiveTaxRate * 100} format={(v) => v.toFixed(1) + '%'} /></span>
                  <span className="delta">tax + NI + loan ÷ gross</span>
                </div>
                <div className="pill-stat">
                  <span className="label">Marginal rate</span>
                  <span className="num" style={{ color: r.marginalRate > 0.5 ? 'var(--c-warn)' : 'var(--ink-0)' }}><AnimatedNumber value={r.marginalRate * 100} format={(v) => v.toFixed(0) + 'p'} /></span>
                  <span className="delta">kept from your next £1: {gbp(1 - r.marginalRate, 2)}</span>
                </div>
              </div>

              {r.gross > 100000 && r.gross < 125140 && (
                <div className="card" style={{ borderColor: 'var(--c-warn)', boxShadow: '0 0 0 1px var(--c-warn), var(--shadow-card)' }}>
                  <h3 className="card-title" style={{ color: 'var(--c-warn)' }}>You're in the 60% tax trap</h3>
                  <p className="card-sub" style={{ marginBottom: 0 }}>
                    Between £100k and £125,140 your Personal Allowance is withdrawn £1 for every £2 earned — so each extra £1 of salary is effectively taxed at {(r.marginalRate * 100).toFixed(0)}%. A pension contribution that drops you below £100k can be remarkably efficient.
                  </p>
                </div>
              )}
            </div>
          </div>
        </main>
      </div>
    </React.Fragment>
  );
}

// keep nav theme in sync (default dark)
const gn = document.querySelector('global-nav');
if (gn) gn.setAttribute('theme', document.documentElement.getAttribute('data-theme') || 'dark');

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
