// screens.jsx — Dashboard, Calculator, Charts, Learn screens.
// Uses LoanEngine, LineChart, Sparkline, InputsPanel globals.

const { useMemo: useMemoScr, useState: useStateScr, useEffect: useEffectScr } = React;
const LE = window.LoanEngine;

function fmt(n, mode) {return LE.fmtGBP(n, mode);}

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

// ---------- Strategy summary card ----------
function StrategyCard({ title, sub, color, primaryLabel, primaryValue,
  rows, isBest, chipClass, fmtMode }) {
  return (
    <div className={`card strat-card ${isBest ? 'is-best' : ''}`}>
      <div className="accent-bar" style={{ background: color, boxShadow: `0 0 12px ${color}` }} />
      {isBest && <div className="best-pill">Recommended</div>}
      <span className={`chip ${chipClass}`}><span className="swatch" />{title}</span>
      <div style={{ height: 12 }} />
      <div className="label" style={{ marginBottom: 4 }}>{primaryLabel}</div>
      <div className="num num-lg" style={{ color: isBest ? color : 'var(--ink-0)' }}>
        <AnimatedNumber value={primaryValue} format={(v) => fmt(v, fmtMode)} />
      </div>
      <p style={{ color: 'var(--ink-2)', fontSize: 12, margin: '6px 0 14px', minHeight: 32 }}>{sub}</p>
      <div className="div-h" />
      {rows.map((r, i) =>
      <div key={i} className="balance-strip" style={r.divider ? { borderTop: '1px dashed var(--line)', marginTop: 8, paddingTop: 16 } : {}}>
          <span style={{ fontSize: 12, color: 'var(--ink-2)' }}>{r.label}</span>
          <span className="num" style={{ fontSize: 14, color: r.muted ? 'var(--ink-2)' : 'var(--ink-0)' }}>{r.value}</span>
        </div>
      )}
    </div>);

}

// ---------- DASHBOARD ----------
function DashboardScreen({ inputs, results, reco, fmtMode, chartStyle }) {
  const plan = LE.PLANS[inputs.planKey];
  const std = results.standard,ovr = results.overpay,lump = results.lump,inv = results.invest;

  // Build line chart data — net worth over time (loan reduction - extra spent + invested)
  const horizonYears = std.writeOffYears;
  const yearSeries = (sim, projKey) => sim.series.
  filter((p) => p.year <= horizonYears).
  map((p) => ({ x: p.year, y: projKey(p, sim) }));

  // Net worth advantage vs standard at each year
  const stdSeries = std.series;
  const advAt = (sim, idx) => {
    const s = stdSeries[idx];const o = sim.series[idx];
    if (!s || !o) return 0;
    if (sim.strategy === 'invest') return o.invested - (s.balance - o.balance);
    if (sim.strategy === 'overpay') return s.balance - o.balance;
    if (sim.strategy === 'lump') return s.balance - o.balance;
    return 0;
  };

  const netWorthSeries = [
  {
    key: 'invest', label: 'Invest the difference', color: 'var(--c-invest)',
    points: inv.series.map((p) => ({ x: p.year, y: p.invested - p.balance }))
  },
  {
    key: 'overpay', label: 'Overpay monthly', color: 'var(--c-overpay)',
    points: ovr.series.map((p) => ({ x: p.year, y: p.invested - p.balance }))
  },
  {
    key: 'lump', label: 'Lump sum', color: 'var(--c-lump)',
    points: lump.series.map((p) => ({ x: p.year, y: p.invested - p.balance }))
  },
  {
    key: 'standard', label: 'Standard', color: 'var(--c-std)', dashed: true,
    points: std.series.map((p) => ({ x: p.year, y: -p.balance }))
  }];


  const wealthInvest = inv.finalInvested - inv.finalBalance;
  const wealthOver = ovr.finalInvested - ovr.finalBalance;
  const wealthLump = lump.finalInvested - lump.finalBalance;
  const wealthStd = -std.finalBalance;
  const bestKey = reco.best;

  return (
    <div className="stack">
      {/* Hero recommendation — Verdict style */}
      <div className="card reco card-pad-lg">
        <div className="label" style={{ color: 'var(--c-invest)', marginBottom: 18 }}>
          ● {plan.label} · {fmt(inputs.balance, 'short')} balance · {fmt(inputs.salary, 'short')} salary
        </div>
        <h2 className="reco-headline">
          {reco.headlinePrefix}{' '}
          <span className="reco-accent">{reco.headlineAccent}</span>{' '}
          {reco.headlineSuffix}
        </h2>
        <p style={{ maxWidth: '65ch' }}>{reco.reasoning}</p>
      </div>

      {/* Strategy comparison row */}
      <div className="grid grid-4">
        <StrategyCard
          title="Standard" sub="Just pay the minimum and let the clock run out"
          color="var(--c-std)" chipClass="chip-std" isBest={bestKey === 'standard'} fmtMode={fmtMode}
          primaryLabel="Net wealth (vs. baseline)" primaryValue={wealthStd}
          rows={[
          { label: 'Total repaid', value: fmt(std.totalRepaid, fmtMode) },
          { label: 'Interest paid', value: fmt(std.totalInterest, fmtMode) },
          { label: 'Written off', value: fmt(std.writtenOff, fmtMode) },
          { label: 'Cleared by', value: std.payoffMonth ? `Year ${(std.payoffMonth / 12).toFixed(1)}` : `Write-off (yr ${std.writeOffYears})` }]
          } />
        
        <StrategyCard
          title="Overpay" sub={`Extra £${inputs.monthlyOverpay}/mo onto the loan, then invest once it's clear`}
          color="var(--c-overpay)" chipClass="chip-overpay" isBest={bestKey === 'overpay'} fmtMode={fmtMode}
          primaryLabel="Net wealth (vs. baseline)" primaryValue={wealthOver}
          rows={[
          { label: 'Interest saved', value: fmt(std.totalInterest - ovr.totalInterest, fmtMode) },
          { label: 'Cleared by', value: ovr.payoffMonth ? `Year ${(ovr.payoffMonth / 12).toFixed(1)}` : `Not before write-off` },
          { label: 'Then invested', value: ovr.payoffMonth ? `£${inputs.monthlyOverpay}/mo from yr ${(ovr.payoffMonth / 12).toFixed(0)}` : '—' },
          { label: 'Portfolio at write-off', value: fmt(ovr.finalInvested, fmtMode) }]
          } />
        
        <StrategyCard
          title="Lump sum" sub={`${fmt(inputs.lumpSum, fmtMode)} paid today, then the £${inputs.monthlyOverpay}/mo ${{invest: 'invests', overpay: 'overpays', none: 'is spent'}[inputs.lumpThenAction]}`}
          color="var(--c-lump)" chipClass="chip-lump" isBest={bestKey === 'lump'} fmtMode={fmtMode}
          primaryLabel="Net wealth (vs. baseline)" primaryValue={wealthLump}
          rows={[
          { label: 'Upfront payment', value: fmt(inputs.lumpSum, fmtMode) },
          { label: 'Interest saved', value: fmt(std.totalInterest - lump.totalInterest, fmtMode) },
          { label: 'Then the monthly', value: {invest: 'Invested', overpay: 'Overpaid', none: 'Spent'}[inputs.lumpThenAction] },
          { label: inputs.lumpThenAction === 'invest' || inputs.lumpThenAction === 'overpay' ? 'Portfolio at write-off' : 'Cleared by', value: (inputs.lumpThenAction === 'none') ? (lump.payoffMonth ? `Year ${(lump.payoffMonth / 12).toFixed(1)}` : `Write-off (yr ${std.writeOffYears})`) : fmt(lump.finalInvested, fmtMode) }]
          } />
        
        <StrategyCard
          title="Invest" sub={`Invest £${inputs.monthlyOverpay}/mo + lump in ${inputs.wrapper}`}
          color="var(--c-invest)" chipClass="chip-invest" isBest={bestKey === 'invest'} fmtMode={fmtMode}
          primaryLabel="Net wealth (vs. baseline)" primaryValue={wealthInvest}
          rows={[
          { label: 'Portfolio value', value: fmt(inv.finalInvested, fmtMode) },
          { label: 'Inflation-adjusted', value: fmt(inv.series[inv.series.length - 1]?.realInvested || 0, fmtMode) },
          { label: 'Loan written off', value: fmt(std.writtenOff, fmtMode) },
          { label: 'Cleared by', value: `Write-off (yr ${std.writeOffYears})` }]
          } />
        
      </div>

      {/* Net worth chart */}
      <div className="card">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 4 }}>
          <h3 className="card-title">Net wealth over time</h3>
          <div style={{ display: 'flex', gap: 12 }}>
            {netWorthSeries.map((s) =>
            <span key={s.key} style={{ fontSize: 12, display: 'flex', alignItems: 'center', gap: 6, color: 'var(--ink-2)' }}>
                <span style={{ width: 10, height: 2, background: s.color, display: 'inline-block', borderTop: s.dashed ? `2px dashed ${s.color}` : 'none' }} />
                {s.label}
              </span>
            )}
          </div>
        </div>
        <p className="card-sub">Portfolio value minus outstanding loan, projected for the next {horizonYears} years</p>
        <LineChart series={netWorthSeries} width={1000} height={340}
        style={chartStyle === 'bar' ? 'line' : chartStyle}
        xFormat={(v) => `${Math.round(v)}y`}
        yFormat={(v) => fmt(v, 'short')}
        highlightX={std.writeOffYears}
        highlightLabel={`Write-off (${std.writeOffYears}y)`} />
      </div>
    </div>);

}

// ---------- CALCULATOR SCREEN ----------
function CalculatorScreen({ inputs, setInputs, results, fmtMode, chartStyle }) {
  const plan = LE.PLANS[inputs.planKey];
  const tax = LE.ukTax(inputs.salary + inputs.bonus);
  const monthlyRepay = LE.monthlyRepayment(plan, inputs.salary + inputs.bonus);
  const interestRate = LE.monthlyInterestRate(plan, inputs.salary + inputs.bonus) * 12;
  const std = results.standard,ovr = results.overpay,inv = results.invest;

  const balanceSeries = [
  { key: 'standard', label: 'Standard', color: 'var(--c-std)', dashed: true,
    points: std.series.map((p) => ({ x: p.year, y: p.balance })) },
  { key: 'overpay', label: 'Overpay', color: 'var(--c-overpay)',
    points: ovr.series.map((p) => ({ x: p.year, y: p.balance })) },
  { key: 'lump', label: 'Lump sum', color: 'var(--c-lump)',
    points: results.lump.series.map((p) => ({ x: p.year, y: p.balance })) }];


  return (
    <div className="grid grid-calc">
      <InputsPanel inputs={inputs} setInputs={setInputs} fmt={fmtMode} />

      <div className="stack" style={{ width: "660px" }}>
        <div className="card">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <div>
              <h3 className="card-title">This month</h3>
              <p className="card-sub">Based on {plan.label} rules · gross £{(inputs.salary + inputs.bonus).toLocaleString('en-GB')}/yr</p>
            </div>
            <span className="chip" style={{ background: 'var(--glass-2)' }}>
              {plan.label} · {(interestRate * 100).toFixed(2)}% APR
            </span>
          </div>

          <div className="grid grid-4" style={{ marginTop: 10 }}>
            <div className="pill-stat">
              <div className="label">Gross monthly</div>
              <div className="num">{fmt((inputs.salary + inputs.bonus) / 12, 'short')}</div>
              <div className="delta">{fmt(inputs.salary + inputs.bonus, 'short')} / yr</div>
            </div>
            <div className="pill-stat">
              <div className="label">Tax + NI</div>
              <div className="num">{fmt((tax.tax + tax.ni) / 12, 'short')}</div>
              <div className="delta">{((tax.tax + tax.ni) / (inputs.salary + inputs.bonus) * 100).toFixed(1)}% effective</div>
            </div>
            <div className="pill-stat">
              <div className="label">Student loan</div>
              <div className="num" style={{ color: 'var(--c-overpay)' }}>{fmt(monthlyRepay, 'short')}</div>
              <div className="delta">9% over £{plan.threshold.toLocaleString('en-GB')}</div>
            </div>
            <div className="pill-stat">
              <div className="label">Take-home</div>
              <div className="num">{fmt((tax.net - monthlyRepay * 12) / 12, 'short')}</div>
              <div className="delta up">+{fmt(inputs.monthlyOverpay, 'short')} freeable</div>
            </div>
          </div>
        </div>

        <div className="card">
          <h3 className="card-title">Loan balance — projected</h3>
          <p className="card-sub">When each strategy clears the loan (or doesn't)</p>
          <LineChart series={balanceSeries} width={900} height={320}
          style={chartStyle === 'bar' ? 'area' : chartStyle}
          xFormat={(v) => `${Math.round(v)}y`}
          yFormat={(v) => fmt(v, 'short')}
          highlightX={std.writeOffYears}
          highlightLabel={`Write-off`} />
        </div>

        <div className="grid grid-2">
          <div className="card">
            <h3 className="card-title">If you invest instead</h3>
            <p className="card-sub">£{inputs.monthlyOverpay}/mo compounding inside a {inputs.wrapper}</p>
            <div className="grid grid-2" style={{ marginTop: 8 }}>
              <div className="pill-stat">
                <div className="label">Portfolio @ write-off</div>
                <div className="num" style={{ color: 'var(--c-invest)' }}>{fmt(inv.finalInvested, fmtMode)}</div>
                <div className="delta">{((inputs.investReturn - inputs.investFee) * 100).toFixed(2)}% / yr after fees</div>
              </div>
              <div className="pill-stat">
                <div className="label">Real value (today's £)</div>
                <div className="num">{fmt(inv.series[inv.series.length - 1]?.realInvested || 0, fmtMode)}</div>
                <div className="delta">{(inputs.inflation * 100).toFixed(1)}% inflation</div>
              </div>
            </div>
          </div>
          <div className="card">
            <h3 className="card-title">Effective repayment rate</h3>
            <p className="card-sub">For every extra £1 you earn, you keep…</p>
            <div className="num num-xl" style={{ color: 'var(--c-invest)', marginTop: 6 }}>
              <AnimatedNumber value={(1 - 0.40 - 0.02 - 0.09) * 100} format={(v) => `${v.toFixed(0)}p`} />
            </div>
            <div className="muted" style={{ fontSize: 13, marginTop: 8 }}>
              At higher-rate band, you lose 40p to tax, 2p NI, and 9p to your student loan above the threshold — leaving 49p in your pocket.
            </div>
          </div>
        </div>
      </div>
    </div>);

}

// ---------- CHARTS SCREEN ----------
function ChartsScreen({ inputs, results, fmtMode, chartStyle }) {
  const plan = LE.PLANS[inputs.planKey];
  const std = results.standard,ovr = results.overpay,inv = results.invest;

  const balanceSeries = [
  { key: 'standard', label: 'Standard', color: 'var(--c-std)', dashed: true,
    points: std.series.map((p) => ({ x: p.year, y: p.balance })) },
  { key: 'overpay', label: 'Overpay', color: 'var(--c-overpay)',
    points: ovr.series.map((p) => ({ x: p.year, y: p.balance })) },
  { key: 'lump', label: 'Lump', color: 'var(--c-lump)',
    points: results.lump.series.map((p) => ({ x: p.year, y: p.balance })) }];

  const wealthSeries = [
  { key: 'invest', label: 'Invest', color: 'var(--c-invest)',
    points: inv.series.map((p) => ({ x: p.year, y: p.invested - p.balance })) },
  { key: 'overpay', label: 'Overpay', color: 'var(--c-overpay)',
    points: ovr.series.map((p) => ({ x: p.year, y: p.invested - p.balance })) },
  { key: 'standard', label: 'Standard', color: 'var(--c-std)', dashed: true,
    points: std.series.map((p) => ({ x: p.year, y: -p.balance })) }];

  const interestSeries = [
  { key: 'std-int', label: 'Std · interest', color: 'var(--c-std)',
    points: std.series.map((p) => ({ x: p.year, y: p.cumulativeInterest })) },
  { key: 'ovr-int', label: 'Overpay · interest', color: 'var(--c-overpay)',
    points: ovr.series.map((p) => ({ x: p.year, y: p.cumulativeInterest })) }];

  // Crossover: when invest wealth crosses overpay wealth
  let crossover = null;
  for (let i = 0; i < inv.series.length; i++) {
    const iw = inv.series[i].invested - inv.series[i].balance;
    const ow = -ovr.series[i].balance;
    if (iw > ow && crossover === null) {crossover = inv.series[i].year;break;}
  }

  return (
    <div className="stack">
      <div className="grid grid-2">
        <div className="card">
          <h3 className="card-title">Loan balance over time</h3>
          <p className="card-sub">All strategies overlaid · write-off at year {std.writeOffYears}</p>
          <LineChart series={balanceSeries} width={680} height={300}
          style={chartStyle === 'bar' ? 'area' : chartStyle}
          xFormat={(v) => `${Math.round(v)}y`}
          yFormat={(v) => fmt(v, 'short')}
          highlightX={std.writeOffYears} highlightLabel="Write-off" />
        </div>
        <div className="card">
          <h3 className="card-title">Net wealth comparison</h3>
          <p className="card-sub">Portfolio minus loan balance</p>
          <LineChart series={wealthSeries} width={680} height={300}
          style={chartStyle === 'bar' ? 'area' : chartStyle}
          xFormat={(v) => `${Math.round(v)}y`}
          yFormat={(v) => fmt(v, 'short')}
          highlightX={crossover || undefined}
          highlightLabel={crossover ? `Invest overtakes overpay · yr ${crossover.toFixed(1)}` : null} />
        </div>
      </div>
      <div className="grid grid-2">
        <div className="card">
          <h3 className="card-title">Cumulative interest paid</h3>
          <p className="card-sub">Overpaying saves you {fmt(std.totalInterest - ovr.totalInterest, fmtMode)} in interest</p>
          <LineChart series={interestSeries} width={680} height={260}
          style="area"
          xFormat={(v) => `${Math.round(v)}y`}
          yFormat={(v) => fmt(v, 'short')} />
        </div>
        <div className="card">
          <h3 className="card-title">Sensitivity · investment return</h3>
          <p className="card-sub">How investing wealth shifts with assumed return rate</p>
          <SensitivityTable inputs={inputs} fmtMode={fmtMode} />
        </div>
      </div>
    </div>);

}

function SensitivityTable({ inputs, fmtMode }) {
  const returns = [0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10];
  const rows = returns.map((r) => {
    const inv = LE.simulate({ ...inputs, strategy: 'invest', investReturn: r });
    const ovr = LE.simulate({ ...inputs, strategy: 'overpay' });
    return {
      r,
      portfolio: inv.finalInvested,
      net: inv.finalInvested - inv.finalBalance,
      vsOver: inv.finalInvested - inv.finalBalance - (ovr.finalInvested - ovr.finalBalance)
    };
  });
  return (
    <div style={{ overflow: 'hidden', borderRadius: 12, border: '1px solid var(--line)' }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', fontFamily: 'var(--font-mono)', fontSize: 13 }}>
        <thead>
          <tr style={{ background: 'var(--glass-2)' }}>
            <th style={th()}>Return</th>
            <th style={th()}>Portfolio</th>
            <th style={th()}>Net wealth</th>
            <th style={th()}>vs Overpay</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r) =>
          <tr key={r.r} style={{ borderTop: '1px solid var(--line)' }}>
              <td style={td()}>{(r.r * 100).toFixed(0)}%</td>
              <td style={td()}>{fmt(r.portfolio, fmtMode)}</td>
              <td style={td()}>{fmt(r.net, fmtMode)}</td>
              <td style={{ ...td(), color: r.vsOver > 0 ? 'var(--c-good)' : 'var(--c-warn)' }}>
                {r.vsOver > 0 ? '+' : ''}{fmt(r.vsOver, fmtMode)}
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </div>);

  function th() {return { textAlign: 'left', padding: '10px 14px', fontSize: 11, color: 'var(--ink-2)', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.06em' };}
  function td() {return { padding: '10px 14px', color: 'var(--ink-0)' };}
}

// ---------- LEARN ----------
function LearnScreen() {
  const cards = [
  {
    kicker: '01 · The basics',
    title: 'Why UK student loans aren\u2019t really debt',
    body: 'A UK student loan behaves more like a graduate tax than a mortgage. You pay 9% of everything above the threshold — no demand for fixed monthly amounts, no court summons if you lose your job, no impact on your credit score. After 25\u201340 years (depending on plan) anything left is wiped.',
    bullets: [
    'Your repayment is a function of salary, not balance',
    'Stop earning over the threshold? You pay nothing that month',
    'Whatever\u2019s left at write-off is gone, not transferred']

  },
  {
    kicker: '02 · The maths',
    title: 'Why overpaying often loses to investing',
    body: 'If you\u2019re unlikely to fully repay before write-off, every extra pound you throw at the loan is a pound you\u2019d have lost anyway. Investing that pound at compound market returns over decades almost always wins.',
    bullets: [
    'Compound growth over 30\u201340 years dwarfs interest savings',
    'A Stocks & Shares ISA shelters returns from CGT and dividend tax',
    'The certainty of paying down debt feels good — but it isn\u2019t free']

  },
  {
    kicker: '03 · The exceptions',
    title: 'Who should consider overpaying',
    body: 'Some career paths make the loan worth clearing. If you\u2019ll comfortably repay before write-off, the loan becomes real debt and every interest pound saved is a pound earned.',
    bullets: [
    'High earners on Plan 2 or PGL with steep salary trajectories',
    'Doctors, lawyers, IB analysts, senior engineers',
    'Anyone with a small balance who\u2019ll clear it in <10 years']

  },
  {
    kicker: '04 · The wrappers',
    title: 'ISA vs Pension vs Taxable',
    body: 'Where you invest matters as much as whether you invest. ISAs give tax-free growth with full access. Pensions give a tax kick on the way in but lock the money until 57+. Taxable accounts have flexibility but face CGT.',
    bullets: [
    '\u00a320,000/yr ISA allowance \u2014 use it before pensions if access matters',
    'Pension contributions get income-tax relief at your marginal rate',
    'Salary sacrifice pension lowers your loan repayment too']

  }];

  return (
    <div className="grid grid-2">
      {cards.map((c, i) =>
      <div key={i} className="learn-card">
          <div className="kicker">{c.kicker}</div>
          <h3>{c.title}</h3>
          <p>{c.body}</p>
          <ul>{c.bullets.map((b, j) => <li key={j}>{b}</li>)}</ul>
        </div>
      )}
    </div>);

}

Object.assign(window, { DashboardScreen, CalculatorScreen, ChartsScreen, LearnScreen, AnimatedNumber });