// Runway Calculator — interactive component
const { useState: useStateCalc, useMemo: useMemoCalc, useEffect: useEffectCalc } = React;

const CALC_SCENARIOS = {
  downside: { label: 'Downside',  revMult: 0.80, costMult: 1.05, growthDelta: -2 },
  base:     { label: 'Base',      revMult: 1.00, costMult: 1.00, growthDelta:  0 },
  stretch:  { label: 'Stretch',   revMult: 1.10, costMult: 0.95, growthDelta:  2 },
};

function fmtMoney(n, opts = {}) {
  const { short = false, sign = false } = opts;
  if (!isFinite(n)) return '—';
  const abs = Math.abs(n);
  let out;
  if (short) {
    if (abs >= 1_000_000) out = '$' + (n / 1_000_000).toFixed(abs >= 10_000_000 ? 1 : 2) + 'M';
    else if (abs >= 1_000) out = '$' + Math.round(n / 1_000) + 'k';
    else out = '$' + Math.round(n).toLocaleString();
  } else {
    out = '$' + Math.round(n).toLocaleString();
  }
  if (sign && n > 0) out = '+' + out;
  return out;
}

function fmtMonths(m) {
  if (!isFinite(m) || m < 0) return '∞';
  if (m >= 120) return '10+ yrs';
  if (m >= 24)  return (m / 12).toFixed(1) + ' yrs';
  return m.toFixed(1);
}

function addMonthsToDate(date, months) {
  const d = new Date(date);
  const whole = Math.floor(months);
  const frac = months - whole;
  d.setMonth(d.getMonth() + whole);
  d.setDate(d.getDate() + Math.round(frac * 30));
  return d;
}

function fmtDate(d) {
  return d.toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
}

/* Reusable money input */
function MoneyInput({ value, onChange, prefix = '$', suffix, placeholder = '0' }) {
  return (
    <label className="calc-input">
      {prefix && <span className="prefix">{prefix}</span>}
      <input
        type="number"
        value={value === 0 ? '' : value}
        placeholder={placeholder}
        min="0"
        step="any"
        onChange={(e) => {
          const v = e.target.value === '' ? 0 : Number(e.target.value);
          onChange(isNaN(v) ? 0 : v);
        }}
      />
      {suffix && <span className="suffix">{suffix}</span>}
    </label>
  );
}

function PercentInput({ value, onChange, min = -50, max = 50 }) {
  return (
    <div className="calc-slider-wrap">
      <input
        type="range"
        className="calc-slider"
        min={min} max={max} step="0.5"
        value={value}
        onChange={(e) => onChange(Number(e.target.value))}
      />
      <div className="calc-slider-value">
        {value > 0 ? '+' : ''}{value.toFixed(1)}%<span style={{color:'var(--ink-muted)', marginLeft: 4}}>/mo</span>
      </div>
    </div>
  );
}

/* Small close icon */
function XIcon({ size = 14 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 14 14" fill="none" aria-hidden>
      <path d="M3 3l8 8M11 3l-8 8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
    </svg>
  );
}
function PlusIcon({ size = 12 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 12 12" fill="none" aria-hidden>
      <path d="M6 2v8M2 6h8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
    </svg>
  );
}

function InfoIcon({ size = 16 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none" aria-hidden>
      <circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.3"/>
      <path d="M8 7v4M8 5.3v0" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
    </svg>
  );
}

/* Main calculator */
function RunwayCalculator() {
  // Default values — realistic for a seed-stage SMB
  const DEFAULTS = {
    cash: 450000,
    revenue: 85000,
    growth: 3.0,
    cogs: 18000,
    labor: [
      { id: 1, name: 'Full-time team (4)', value: 42000 },
      { id: 2, name: 'Contractors & payroll tax', value: 8500 },
    ],
    expenses: [
      { id: 1, name: 'Rent & utilities',   value: 6200 },
      { id: 2, name: 'Software & tools',   value: 3400 },
      { id: 3, name: 'Marketing & ads',    value: 7500 },
      { id: 4, name: 'Insurance & admin',  value: 1800 },
    ],
    oneTime: 0,
    scenario: 'base',
  };

  const [cash, setCash]           = useStateCalc(DEFAULTS.cash);
  const [revenue, setRevenue]     = useStateCalc(DEFAULTS.revenue);
  const [growth, setGrowth]       = useStateCalc(DEFAULTS.growth);
  const [cogs, setCogs]           = useStateCalc(DEFAULTS.cogs);
  const [labor, setLabor]         = useStateCalc(DEFAULTS.labor);
  const [expenses, setExpenses]   = useStateCalc(DEFAULTS.expenses);
  const [oneTime, setOneTime]     = useStateCalc(DEFAULTS.oneTime);
  const [scenario, setScenario]   = useStateCalc(DEFAULTS.scenario);
  const [nextId, setNextId]       = useStateCalc(100);

  const reset = () => {
    setCash(DEFAULTS.cash); setRevenue(DEFAULTS.revenue); setGrowth(DEFAULTS.growth);
    setCogs(DEFAULTS.cogs); setLabor(DEFAULTS.labor); setExpenses(DEFAULTS.expenses);
    setOneTime(DEFAULTS.oneTime); setScenario(DEFAULTS.scenario);
  };

  const updateRow = (list, setList) => (id, patch) => {
    setList(list.map(r => r.id === id ? { ...r, ...patch } : r));
  };
  const removeRow = (list, setList) => (id) => {
    if (list.length <= 1) return;
    setList(list.filter(r => r.id !== id));
  };
  const addRow = (list, setList, defaultName) => () => {
    setList([...list, { id: nextId, name: defaultName, value: 0 }]);
    setNextId(n => n + 1);
  };

  const totalLabor = labor.reduce((s, r) => s + (Number(r.value) || 0), 0);
  const totalExpenses = expenses.reduce((s, r) => s + (Number(r.value) || 0), 0);

  // Scenario multipliers
  const sc = CALC_SCENARIOS[scenario];
  const scRevenue = revenue * sc.revMult;
  const scCogs    = cogs    * sc.costMult;
  const scLabor   = totalLabor * sc.costMult;
  const scOther   = totalExpenses * sc.costMult;
  const scGrowth  = growth + sc.growthDelta;

  const monthlyFixedCost = scCogs + scLabor + scOther;

  // Month-by-month projection (36 months max)
  const projection = useMemoCalc(() => {
    const rows = [];
    let curCash = cash - oneTime;
    let curRev  = scRevenue;
    let hitZero = null;
    for (let i = 0; i < 60; i++) {
      // Cost that grows with revenue is COGS only; labor + other are fixed
      const costCogs = scCogs * (curRev / Math.max(scRevenue, 1));
      const totalCost = costCogs + scLabor + scOther;
      const net = curRev - totalCost;
      curCash += net;
      if (hitZero === null && curCash < 0) hitZero = i + (curCash / (-net || 1));
      rows.push({ month: i, revenue: curRev, cost: totalCost, net, cash: curCash });
      curRev = curRev * (1 + scGrowth / 100);
    }
    return { rows, hitZero };
  }, [cash, scRevenue, scCogs, scLabor, scOther, scGrowth, oneTime]);

  // Compute runway & burn
  const netMonth1 = scRevenue - monthlyFixedCost;
  const burnMonth1 = Math.max(0, -netMonth1); // only positive burn
  const startingCash = cash - oneTime;

  let runwayMonths, runwayLabel, status;
  if (netMonth1 >= 0 && scGrowth >= 0) {
    // profitable and growing — infinite runway
    runwayMonths = Infinity;
    runwayLabel = '∞';
    status = 'profitable';
  } else if (projection.hitZero !== null) {
    runwayMonths = projection.hitZero;
    runwayLabel = fmtMonths(runwayMonths);
    status = runwayMonths < 6 ? 'critical' : (runwayMonths < 12 ? 'warn' : 'ok');
  } else {
    runwayMonths = 60;
    runwayLabel = '5+ yrs';
    status = 'ok';
  }

  const cashOutDate = isFinite(runwayMonths)
    ? fmtDate(addMonthsToDate(new Date(), runwayMonths))
    : 'Cash-flow positive';

  const statusClass =
    status === 'profitable' ? 'is-profitable' :
    status === 'critical'   ? 'is-critical'   :
    status === 'warn'       ? 'is-warn' : '';

  /* Chart */
  const chart = useMemoCalc(() => {
    const W = 560, H = 220, padL = 44, padR = 12, padT = 14, padB = 26;
    const months = Math.min(projection.rows.length, 24);
    const pts = projection.rows.slice(0, months);
    const cashes = pts.map(p => p.cash);
    const maxC = Math.max(cash, ...cashes, 0);
    const minC = Math.min(0, ...cashes);
    const x = (i) => padL + (i / (months - 1)) * (W - padL - padR);
    const y = (v) => {
      const range = maxC - minC || 1;
      return padT + (1 - (v - minC) / range) * (H - padT - padB);
    };
    const pathCash = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${x(i).toFixed(1)},${y(p.cash).toFixed(1)}`).join(' ');
    const areaCash = `${pathCash} L${x(months-1).toFixed(1)},${y(minC).toFixed(1)} L${x(0).toFixed(1)},${y(minC).toFixed(1)} Z`;
    const zeroY = y(0);
    // monthly net bars
    const barW = (W - padL - padR) / months * 0.5;
    const bars = pts.map((p, i) => ({
      x: x(i) - barW/2,
      y: p.net >= 0 ? y(p.net) : y(0),
      h: Math.abs(y(p.net) - y(0)),
      pos: p.net >= 0,
    }));
    // Y-axis ticks
    const ticks = [maxC, maxC * 0.66, maxC * 0.33, 0].filter((v, i, a) => i === 0 || Math.abs(v - a[i-1]) > 1);
    return { W, H, padL, padB, pathCash, areaCash, zeroY, x, y, months, pts, bars, ticks, minC, maxC };
  }, [projection, cash]);

  const runwayX = (isFinite(runwayMonths) && runwayMonths > 0 && runwayMonths < chart.months)
    ? chart.x(runwayMonths) : null;

  return (
    <>
      <section className="container">
        <div className="calc-hero">
          <div className="eyebrow">Resources · Tools</div>
          <h1 className="display">How long until you <em>run out of cash?</em></h1>
          <p className="lede">
            Plug in your cash, revenue, and monthly costs. We'll show you your burn rate, runway in months, and cash-out date — plus how growth and cost cuts change the answer.
          </p>
        </div>
      </section>

      <section className="container" style={{ paddingBottom: 24 }}>
        <div className="calc-shell">

          {/* INPUTS */}
          <div className="calc-inputs">
            <div className="calc-inputs-head">
              <div>
                <div className="eyebrow">Your numbers</div>
                <h2>Tell us where you stand.</h2>
              </div>
              <button className="calc-reset" onClick={reset}>Reset</button>
            </div>

            {/* Cash position */}
            <div className="calc-group">
              <div className="calc-group-label">Cash position</div>
              <div className="calc-field">
                <div className="calc-field-row">
                  <div>
                    <div className="calc-field-label">Cash in bank today</div>
                    <div className="calc-field-hint">Operating + reserves across all accounts.</div>
                  </div>
                  <MoneyInput value={cash} onChange={setCash}/>
                </div>
              </div>
              <div className="calc-field">
                <div className="calc-field-row">
                  <div>
                    <div className="calc-field-label">One-time cash outflow</div>
                    <div className="calc-field-hint">Tax bill, deposit, equipment — upfront, not monthly.</div>
                  </div>
                  <MoneyInput value={oneTime} onChange={setOneTime}/>
                </div>
              </div>
            </div>

            {/* Incoming cash */}
            <div className="calc-group">
              <div className="calc-group-label">Monthly cash in</div>
              <div className="calc-field">
                <div className="calc-field-row">
                  <div>
                    <div className="calc-field-label">Recurring revenue / collections</div>
                    <div className="calc-field-hint">Cash actually collected each month — not booked revenue.</div>
                  </div>
                  <MoneyInput value={revenue} onChange={setRevenue}/>
                </div>
              </div>
              <div className="calc-field">
                <div className="calc-field-row" style={{gridTemplateColumns: '1fr 240px'}}>
                  <div>
                    <div className="calc-field-label">Expected revenue growth</div>
                    <div className="calc-field-hint">Compounding month over month. Be honest.</div>
                  </div>
                  <PercentInput value={growth} onChange={setGrowth}/>
                </div>
              </div>
            </div>

            {/* Cost of labor */}
            <div className="calc-group">
              <div className="calc-group-label">Cost of labor · monthly</div>
              <div className="calc-rows">
                {labor.map((r) => (
                  <div className="calc-row" key={r.id}>
                    <input
                      type="text"
                      value={r.name}
                      onChange={(e) => updateRow(labor, setLabor)(r.id, { name: e.target.value })}
                    />
                    <MoneyInput value={r.value} onChange={(v) => updateRow(labor, setLabor)(r.id, { value: v })}/>
                    <button className="calc-row-remove" onClick={() => removeRow(labor, setLabor)(r.id)} aria-label="Remove">
                      <XIcon/>
                    </button>
                  </div>
                ))}
              </div>
              <button className="calc-add" onClick={addRow(labor, setLabor, 'New labor line')}>
                <PlusIcon/> Add a labor line
              </button>
            </div>

            {/* COGS */}
            <div className="calc-group">
              <div className="calc-group-label">Cost of goods / services · monthly</div>
              <div className="calc-field">
                <div className="calc-field-row">
                  <div>
                    <div className="calc-field-label">COGS (variable)</div>
                    <div className="calc-field-hint">Materials, merchant fees, fulfillment — scales with revenue.</div>
                  </div>
                  <MoneyInput value={cogs} onChange={setCogs}/>
                </div>
              </div>
            </div>

            {/* Operating expenses */}
            <div className="calc-group">
              <div className="calc-group-label">Operating expenses · monthly</div>
              <div className="calc-rows">
                {expenses.map((r) => (
                  <div className="calc-row" key={r.id}>
                    <input
                      type="text"
                      value={r.name}
                      onChange={(e) => updateRow(expenses, setExpenses)(r.id, { name: e.target.value })}
                    />
                    <MoneyInput value={r.value} onChange={(v) => updateRow(expenses, setExpenses)(r.id, { value: v })}/>
                    <button className="calc-row-remove" onClick={() => removeRow(expenses, setExpenses)(r.id)} aria-label="Remove">
                      <XIcon/>
                    </button>
                  </div>
                ))}
              </div>
              <button className="calc-add" onClick={addRow(expenses, setExpenses, 'New expense line')}>
                <PlusIcon/> Add an expense line
              </button>
            </div>
          </div>

          {/* RESULTS */}
          <div className="calc-results">

            <div>
              <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom: 14, flexWrap:'wrap', gap: 12}}>
                <div className="eyebrow">Your runway</div>
                <div className="calc-scenarios" role="tablist" aria-label="Scenario">
                  {Object.entries(CALC_SCENARIOS).map(([key, s]) => (
                    <button
                      key={key}
                      role="tab"
                      aria-selected={scenario === key}
                      className={`calc-scenario-btn ${scenario === key ? 'active' : ''}`}
                      onClick={() => setScenario(key)}
                    >{s.label}</button>
                  ))}
                </div>
              </div>

              <div className={`calc-hero-result ${statusClass}`}>
                <div className="eyebrow" style={{color:'var(--ink-muted)'}}>
                  {status === 'profitable' ? 'Cash-flow positive' : 'Months of runway'}
                </div>
                <div className="big tabular">
                  <em>{runwayLabel}</em>
                  {isFinite(runwayMonths) && runwayMonths < 24 && <span className="unit">months</span>}
                </div>
                <div className="sub">
                  {status === 'profitable' ? (
                    <>You're generating <strong>{fmtMoney(netMonth1, {short:true})}</strong> in net cash each month at your current pace. Reinvest, raise salaries, or build a reserve — you choose.</>
                  ) : (
                    <>At your current pace you'll hit $0 around <strong>{cashOutDate}</strong>. That's the moment to have capital raised, costs cut, or revenue accelerated.</>
                  )}
                </div>

                <div className="calc-assumptions">
                  <span className="calc-chip"><span className="dot"/> {CALC_SCENARIOS[scenario].label} case</span>
                  <span className="calc-chip">Growth {scGrowth > 0 ? '+' : ''}{scGrowth.toFixed(1)}%/mo</span>
                  <span className="calc-chip">Fixed costs {fmtMoney(scLabor + scOther, {short:true})}/mo</span>
                </div>
              </div>
            </div>

            {/* Stat strip */}
            <div className="calc-stats">
              <div className="calc-stat">
                <div className="label">Monthly burn</div>
                <div className={`value ${burnMonth1 > 0 ? 'neg' : 'pos'}`}>
                  {burnMonth1 > 0 ? fmtMoney(burnMonth1, {short:true}) : fmtMoney(netMonth1, {short:true, sign:true})}
                </div>
                <div className="delta">{burnMonth1 > 0 ? 'Net cash out' : 'Net cash in'}</div>
              </div>
              <div className="calc-stat">
                <div className="label">Starting cash</div>
                <div className="value">{fmtMoney(startingCash, {short:true})}</div>
                <div className="delta">After one-time outflow</div>
              </div>
              <div className="calc-stat">
                <div className="label">Cash-out date</div>
                <div className="value" style={{fontSize: 22, paddingTop: 4}}>{cashOutDate}</div>
                <div className="delta">At {CALC_SCENARIOS[scenario].label.toLowerCase()} pace</div>
              </div>
            </div>

            {/* Chart */}
            <div className="calc-chart-wrap">
              <div className="calc-chart-head">
                <div className="calc-chart-title">Cash balance · next 24 months</div>
                <div className="calc-chart-legend">
                  <span><span className="sw" style={{background:'var(--accent)'}}/>Cash</span>
                  <span><span className="sw" style={{background:'var(--accent-line)'}}/>Net/mo</span>
                </div>
              </div>
              <svg className="calc-chart-svg" viewBox={`0 0 ${chart.W} ${chart.H}`} preserveAspectRatio="none">
                {/* Y grid */}
                {chart.ticks.map((t, i) => (
                  <g key={i}>
                    <line x1={chart.padL} x2={chart.W - 12} y1={chart.y(t)} y2={chart.y(t)} stroke="var(--rule-soft)" strokeWidth="1"/>
                    <text x={chart.padL - 8} y={chart.y(t) + 4} textAnchor="end" fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-muted)">{fmtMoney(t, {short:true})}</text>
                  </g>
                ))}

                {/* Zero line */}
                <line x1={chart.padL} x2={chart.W - 12} y1={chart.zeroY} y2={chart.zeroY} stroke="var(--ink-faint)" strokeWidth="1" strokeDasharray="2 3"/>

                {/* Net bars */}
                {chart.bars.map((b, i) => (
                  <rect
                    key={i}
                    x={b.x} y={b.y} width={(chart.W - chart.padL - 12) / chart.months * 0.5} height={Math.max(0.5, b.h)}
                    fill={b.pos ? 'var(--accent-line)' : '#F0CFC2'}
                    opacity="0.85"
                  />
                ))}

                {/* Cash area */}
                <path d={chart.areaCash} fill="var(--accent)" opacity="0.1"/>
                <path d={chart.pathCash} fill="none" stroke="var(--accent)" strokeWidth="2" strokeLinejoin="round"/>

                {/* Runway marker */}
                {runwayX !== null && (
                  <g>
                    <line x1={runwayX} x2={runwayX} y1={14} y2={chart.H - chart.padB} stroke="#B5441C" strokeWidth="1" strokeDasharray="3 3"/>
                    <circle cx={runwayX} cy={chart.zeroY} r="4" fill="#B5441C"/>
                    <rect x={runwayX + 6} y={16} width="88" height="22" rx="4" fill="#B5441C"/>
                    <text x={runwayX + 50} y={31} textAnchor="middle" fontSize="10.5" fontFamily="var(--font-mono)" fill="#fff">CASH-OUT · M{runwayMonths.toFixed(1)}</text>
                  </g>
                )}

                {/* X axis labels */}
                {[0, 6, 12, 18, 23].map((m) => (
                  <text key={m} x={chart.x(m)} y={chart.H - 8} textAnchor="middle" fontSize="10" fontFamily="var(--font-mono)" fill="var(--ink-muted)">
                    {m === 0 ? 'Today' : `M${m}`}
                  </text>
                ))}
              </svg>
            </div>
          </div>

        </div>

        {/* Disclaimer */}
        <div className="calc-disclaimer">
          <div className="calc-disclaimer-icon"><InfoIcon/></div>
          <div className="calc-disclaimer-body">
            <strong>This is a back-of-the-envelope model, not financial advice.</strong> The calculator uses simple compounding on a handful of inputs and assumes your COGS scales linearly with revenue while labor and operating costs stay fixed. It doesn't account for seasonality, receivables timing, tax obligations, debt schedules, capital expenditures, or the hundred other things a real model would. For a runway projection you can actually plan around — and a thirteen-week cash forecast you can take to your board or your bank — <a href="cfo.html">talk to a Revenu CFO</a> or <a href="pricing.html">start a free trial</a>.
          </div>
        </div>
      </section>

      {/* Tips */}
      <section className="container">
        <div className="calc-tips">
          <div className="calc-tip">
            <div className="num">01 / Extend runway</div>
            <h3>Cut, then raise.</h3>
            <p>Every dollar of fixed cost removed buys more time than a dollar raised — and it's cheaper than dilution. Audit software, rent, and contractors before the deck.</p>
          </div>
          <div className="calc-tip">
            <div className="num">02 / Collect faster</div>
            <h3>AR is runway hiding in plain sight.</h3>
            <p>Shaving 15 days off your average receivable period can be worth a month of runway on its own. Tighten terms, automate reminders, and chase early.</p>
          </div>
          <div className="calc-tip">
            <div className="num">03 / Raise before you need it</div>
            <h3>Nine months is the new six.</h3>
            <p>Investors and lenders price risk off your runway. Start the conversation when you have twelve months left — not four. The math of a raise at zero is never kind.</p>
          </div>
        </div>
      </section>
    </>
  );
}

Object.assign(window, { RunwayCalculator });
