/* ============================================================
   Black-Scholes calculator — functional
   ============================================================ */

function CalcBlackScholesPage() {
  const [type, setType] = useState('call');
  const [S, setS] = useState(100);
  const [K, setK] = useState(100);
  const [days, setDays] = useState(60);
  const [r, setR] = useState(13.75);
  const [q, setQ] = useState(0);
  const [sigma, setSigma] = useState(28);

  const T = days / 365;
  const res = IBDMath.bs(+S, +K, T, +r / 100, +q / 100, +sigma / 100, type);

  // Sensitivity: price vs spot
  const sensitivity = useMemo(() => {
    const sMin = +S * 0.7, sMax = +S * 1.3;
    const pts = [];
    for (let i = 0; i <= 60; i++) {
      const s = sMin + (sMax - sMin) * (i / 60);
      const r1 = IBDMath.bs(s, +K, T, +r / 100, +q / 100, +sigma / 100, type);
      pts.push({ s, p: r1.price });
    }
    return pts;
  }, [S, K, days, r, q, sigma, type]);

  return (
    <Page fullBleed>
      <div className="tool-stage">
        <aside className="tool-controls">
          <div className="crumb" style={{marginBottom: 'var(--s-4)'}}>
            <a href="#/">Início</a><span className="crumb-sep"></span>
            <a href="#/biblioteca">Ferramentas</a><span className="crumb-sep"></span>
            <span>Black-Scholes</span>
          </div>
          <div className="eyebrow eyebrow-accent">Pricing · Opções europeias</div>
          <h2 style={{marginTop: 'var(--s-2)'}}>Calculadora Black-Scholes</h2>
          <p style={{color: 'var(--fg-muted)', fontSize: 13, marginTop: 'var(--s-3)'}}>
            Modelo Black-Scholes-Merton com rendimento contínuo. Para opções europeias.
          </p>

          <div style={{marginTop: 'var(--s-5)'}}>
            <div className="eyebrow" style={{fontSize: 10, marginBottom: 'var(--s-3)'}}>Tipo de opção</div>
            <div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0, border: '1px solid var(--rule-strong)'}}>
              <button onClick={() => setType('call')}
                      className="mono"
                      style={{padding: 12, background: type === 'call' ? 'var(--primary)' : 'transparent',
                              color: type === 'call' ? 'var(--primary-fg)' : 'var(--fg)',
                              border: 'none', fontSize: 13, letterSpacing: '0.08em', textTransform: 'uppercase', cursor: 'pointer'}}>
                Call
              </button>
              <button onClick={() => setType('put')}
                      className="mono"
                      style={{padding: 12, background: type === 'put' ? 'var(--primary)' : 'transparent',
                              color: type === 'put' ? 'var(--primary-fg)' : 'var(--fg)',
                              border: 'none', borderLeft: '1px solid var(--rule-strong)', fontSize: 13, letterSpacing: '0.08em', textTransform: 'uppercase', cursor: 'pointer'}}>
                Put
              </button>
            </div>
          </div>

          <NumField label="Preço à vista (S)" value={S} setValue={setS} unit="R$" step={0.5} hint="Cotação atual do ativo subjacente." />
          <NumField label="Preço de exercício (K)" value={K} setValue={setK} unit="R$" step={0.5} hint="Strike da opção." />
          <NumField label="Dias até o vencimento" value={days} setValue={setDays} unit="dias" step={1} hint="Convenção 365 dias / ano." />
          <NumField label="Taxa livre de risco (r)" value={r} setValue={setR} unit="%" step={0.25} hint="Taxa anual, equivalente DI." />
          <NumField label="Rendimento contínuo (q)" value={q} setValue={setQ} unit="%" step={0.25} hint="Dividend yield ou taxa estrangeira." />
          <NumField label="Volatilidade (σ)" value={sigma} setValue={setSigma} unit="%" step={1} hint="Volatilidade anualizada implícita ou histórica." />

          <div className="notice notice-warn" style={{marginTop: 'var(--s-5)', fontSize: 12}}>
            <div>
              <strong>Apenas para fins educacionais.</strong> Modelo BS pressupõe distribuição log-normal,
              vol constante e não captura volatility smile. Para uso prático, calibre frente ao mercado.
            </div>
          </div>
        </aside>

        <div className="tool-output">
          {/* Result header */}
          <div className="eyebrow eyebrow-accent">Resultado · {type === 'call' ? 'Call' : 'Put'} europeia</div>
          <div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--s-7)', alignItems: 'end', marginTop: 'var(--s-3)'}}>
            <div>
              <div style={{fontFamily: 'var(--font-serif)', fontSize: 'clamp(2.5rem, 5vw, 4rem)', fontWeight: 400, letterSpacing: '-0.02em', lineHeight: 1}}>
                {IBDMath.fmtBRL(res.price)}
              </div>
              <div className="mono" style={{color: 'var(--fg-muted)', fontSize: 12, marginTop: 'var(--s-3)'}}>
                Prêmio teórico · σ {sigma}% · T {days} dias · r {r}%
              </div>
            </div>
            <div style={{display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4}}>
              <div className="mono" style={{fontSize: 12, color: 'var(--fg-muted)'}}>moneyness</div>
              <div className="mono" style={{fontSize: 18}}>
                {(((+S - +K) / +K) * 100).toLocaleString('pt-BR', {maximumFractionDigits: 2})}%
              </div>
              <div className="mono" style={{fontSize: 11, color: 'var(--fg-subtle)', marginTop: 4}}>
                S/K = {(+S / +K).toFixed(4)}
              </div>
            </div>
          </div>

          {/* Greeks */}
          <div style={{marginTop: 'var(--s-7)'}}>
            <div className="eyebrow" style={{marginBottom: 'var(--s-3)'}}>Gregas</div>
            <div className="greeks">
              <Greek name="Δ" label="delta" value={IBDMath.fmtNum(res.delta, 4)} sub="∂C/∂S" />
              <Greek name="Γ" label="gamma" value={IBDMath.fmtNum(res.gamma, 4)} sub="∂²C/∂S²" />
              <Greek name="ν" label="vega" value={IBDMath.fmtNum(res.vega, 4)} sub="por 1% de σ" />
              <Greek name="Θ" label="theta" value={IBDMath.fmtNum(res.theta, 4)} sub="por dia" />
              <Greek name="ρ" label="rho" value={IBDMath.fmtNum(res.rho, 4)} sub="por 1% de r" />
            </div>
          </div>

          {/* Sensitivity chart */}
          <div className="panel" style={{marginTop: 'var(--s-6)'}}>
            <div className="panel-head">
              <h3>Sensibilidade do prêmio ao preço à vista</h3>
              <span className="mono" style={{fontSize: 11, color: 'var(--fg-muted)'}}>
                S ∈ [{(S*0.7).toFixed(2)} … {(S*1.3).toFixed(2)}]
              </span>
            </div>
            <SensitivityChart points={sensitivity} S={+S} K={+K} type={type} />
          </div>

          {/* Decomposition */}
          <div className="panel" style={{marginTop: 'var(--s-5)'}}>
            <div className="panel-head">
              <h3>Decomposição do prêmio</h3>
            </div>
            <div style={{display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 0}}>
              {(() => {
                const intrinsic = type === 'call' ? Math.max(+S - +K, 0) : Math.max(+K - +S, 0);
                const time = res.price - intrinsic;
                return (
                  <>
                    <div style={{padding: 'var(--s-4)', borderRight: '1px solid var(--rule)'}}>
                      <div className="eyebrow" style={{fontSize: 10}}>Valor intrínseco</div>
                      <div className="mono" style={{fontSize: 22, marginTop: 6}}>{IBDMath.fmtBRL(intrinsic)}</div>
                      <div className="mono" style={{fontSize: 11, color: 'var(--fg-muted)', marginTop: 4}}>
                        max({type === 'call' ? 'S−K' : 'K−S'}, 0)
                      </div>
                    </div>
                    <div style={{padding: 'var(--s-4)', borderRight: '1px solid var(--rule)'}}>
                      <div className="eyebrow" style={{fontSize: 10}}>Valor extrínseco</div>
                      <div className="mono" style={{fontSize: 22, marginTop: 6, color: 'var(--accent)'}}>{IBDMath.fmtBRL(time)}</div>
                      <div className="mono" style={{fontSize: 11, color: 'var(--fg-muted)', marginTop: 4}}>
                        prêmio − intrínseco
                      </div>
                    </div>
                    <div style={{padding: 'var(--s-4)'}}>
                      <div className="eyebrow" style={{fontSize: 10}}>Volatilidade implícita usada</div>
                      <div className="mono" style={{fontSize: 22, marginTop: 6}}>{(+sigma).toFixed(2)}%</div>
                      <div className="mono" style={{fontSize: 11, color: 'var(--fg-muted)', marginTop: 4}}>
                        ann. · base 252 / 365
                      </div>
                    </div>
                  </>
                );
              })()}
            </div>
          </div>

          {/* Formula */}
          <div style={{marginTop: 'var(--s-6)', padding: 'var(--s-5)', background: 'var(--bg-sunken)', border: '1px solid var(--rule)'}}>
            <div className="eyebrow" style={{marginBottom: 'var(--s-3)'}}>Fórmula utilizada</div>
            <div className="mono" style={{fontSize: 13, lineHeight: 1.9}}>
              d₁ = [ ln(S/K) + (r − q + σ²/2)·T ] / (σ·√T) = <span style={{color: 'var(--accent)'}}>{IBDMath.fmtNum(res.d1, 4)}</span><br/>
              d₂ = d₁ − σ·√T = <span style={{color: 'var(--accent)'}}>{IBDMath.fmtNum(res.d2, 4)}</span><br/>
              {type === 'call'
                ? 'C = S·e^(−qT)·N(d₁) − K·e^(−rT)·N(d₂)'
                : 'P = K·e^(−rT)·N(−d₂) − S·e^(−qT)·N(−d₁)'}
            </div>
          </div>
        </div>
      </div>
    </Page>
  );
}

function NumField({ label, value, setValue, unit, step, hint }) {
  return (
    <div className="form-field" style={{marginBottom: 'var(--s-4)'}}>
      <label>{label}</label>
      <div style={{display: 'grid', gridTemplateColumns: '1fr auto', gap: 0, border: '1px solid var(--rule-strong)'}}>
        <input
          type="number"
          step={step}
          value={value}
          onChange={e => setValue(e.target.value === '' ? '' : +e.target.value)}
          className="mono"
          style={{padding: 12, border: 'none', background: 'var(--bg-elev)', fontSize: 15, color: 'var(--fg)', outline: 'none', width: '100%'}}
        />
        <span className="mono" style={{padding: '12px 14px', background: 'var(--bg-sunken)', borderLeft: '1px solid var(--rule-strong)', fontSize: 12, color: 'var(--fg-muted)', display: 'grid', placeItems: 'center', minWidth: 56}}>
          {unit}
        </span>
      </div>
      {hint && <div className="form-hint">{hint}</div>}
    </div>
  );
}

function Greek({ name, label, value, sub }) {
  return (
    <div>
      <div className="greek-name">{name}</div>
      <div className="greek-value">{value}</div>
      <div className="mono" style={{fontSize: 10, color: 'var(--fg-subtle)', marginTop: 4, letterSpacing: '0.05em'}}>{label} · {sub}</div>
    </div>
  );
}

function SensitivityChart({ points, S, K, type }) {
  const w = 720, h = 280, pad = { l: 50, r: 16, t: 16, b: 36 };
  const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b;
  const xs = points.map(p => p.s);
  const ys = points.map(p => p.p);
  const xMin = Math.min(...xs), xMax = Math.max(...xs);
  const yMin = 0, yMax = Math.max(...ys) * 1.05;
  const x = s => pad.l + ((s - xMin) / (xMax - xMin)) * iw;
  const y = v => pad.t + ih - ((v - yMin) / (yMax - yMin)) * ih;
  const path = points.map((p, i) => (i === 0 ? 'M' : 'L') + x(p.s).toFixed(2) + ',' + y(p.p).toFixed(2)).join(' ');

  // intrinsic line
  const intrPath = points.map((p, i) => {
    const v = type === 'call' ? Math.max(p.s - K, 0) : Math.max(K - p.s, 0);
    return (i === 0 ? 'M' : 'L') + x(p.s).toFixed(2) + ',' + y(v).toFixed(2);
  }).join(' ');

  const xTicks = 6, yTicks = 5;
  return (
    <div style={{overflow: 'hidden'}}>
      <svg viewBox={`0 0 ${w} ${h}`} style={{width: '100%', height: 'auto', display: 'block'}}>
        {/* grid */}
        {Array.from({length: yTicks + 1}, (_, i) => {
          const yy = pad.t + (ih / yTicks) * i;
          const v = yMax - (yMax / yTicks) * i;
          return (
            <g key={'y' + i}>
              <line x1={pad.l} x2={pad.l + iw} y1={yy} y2={yy} stroke="var(--rule)" strokeWidth="1" />
              <text x={pad.l - 8} y={yy + 4} textAnchor="end" fontFamily="var(--font-mono)" fontSize="10" fill="var(--fg-muted)">{v.toFixed(2)}</text>
            </g>
          );
        })}
        {Array.from({length: xTicks + 1}, (_, i) => {
          const xx = pad.l + (iw / xTicks) * i;
          const v = xMin + ((xMax - xMin) / xTicks) * i;
          return (
            <g key={'x' + i}>
              <line x1={xx} x2={xx} y1={pad.t} y2={pad.t + ih} stroke="var(--rule)" strokeWidth="1" />
              <text x={xx} y={pad.t + ih + 18} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill="var(--fg-muted)">{v.toFixed(0)}</text>
            </g>
          );
        })}
        {/* intrinsic */}
        <path d={intrPath} fill="none" stroke="var(--fg-subtle)" strokeWidth="1" strokeDasharray="4 4" />
        {/* premium */}
        <path d={path} fill="none" stroke="var(--primary)" strokeWidth="2" />
        {/* current S */}
        <line x1={x(S)} x2={x(S)} y1={pad.t} y2={pad.t + ih} stroke="var(--accent)" strokeWidth="1" strokeDasharray="3 3" />
        <text x={x(S)} y={pad.t + 12} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill="var(--accent)">S = {S}</text>
        {/* strike K */}
        <line x1={x(K)} x2={x(K)} y1={pad.t} y2={pad.t + ih} stroke="var(--fg-muted)" strokeWidth="1" strokeDasharray="2 4" />
        <text x={x(K)} y={pad.t + ih - 6} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill="var(--fg-muted)">K</text>
        {/* axes labels */}
        <text x={pad.l + iw / 2} y={h - 6} textAnchor="middle" fontFamily="var(--font-sans)" fontSize="11" fill="var(--fg-muted)" letterSpacing="0.1em">PREÇO À VISTA (S)</text>
      </svg>
      <div style={{display: 'flex', gap: 'var(--s-5)', padding: 'var(--s-3) 0 0', borderTop: '1px solid var(--rule)', marginTop: 'var(--s-2)', fontFamily: 'var(--font-sans)', fontSize: 12, color: 'var(--fg-muted)'}}>
        <span><span className="swatch" style={{background: 'var(--primary)'}}></span>Prêmio teórico</span>
        <span><span className="swatch" style={{background: 'var(--fg-subtle)'}}></span>Valor intrínseco</span>
        <span><span className="swatch" style={{background: 'var(--accent)'}}></span>S atual</span>
      </div>
    </div>
  );
}

window.CalcBlackScholesPage = CalcBlackScholesPage;
window.NumField = NumField;
