/* ============================================================
   Payoff diagram of multi-leg option strategies
   ============================================================ */

const PRESETS = {
  'bull-call': {
    name: 'Bull Call Spread',
    legs: [
      { side: 'long', type: 'call', strike: 60, premium: 5.50, qty: 1 },
      { side: 'short', type: 'call', strike: 70, premium: 1.80, qty: 1 },
    ],
    spot: 62
  },
  'bear-put': {
    name: 'Bear Put Spread',
    legs: [
      { side: 'long', type: 'put', strike: 70, premium: 5.20, qty: 1 },
      { side: 'short', type: 'put', strike: 60, premium: 1.60, qty: 1 },
    ],
    spot: 65
  },
  'straddle': {
    name: 'Long Straddle',
    legs: [
      { side: 'long', type: 'call', strike: 100, premium: 4.20, qty: 1 },
      { side: 'long', type: 'put', strike: 100, premium: 3.80, qty: 1 },
    ],
    spot: 100
  },
  'iron-condor': {
    name: 'Iron Condor',
    legs: [
      { side: 'long', type: 'put', strike: 80, premium: 0.60, qty: 1 },
      { side: 'short', type: 'put', strike: 90, premium: 2.10, qty: 1 },
      { side: 'short', type: 'call', strike: 110, premium: 2.40, qty: 1 },
      { side: 'long', type: 'call', strike: 120, premium: 0.80, qty: 1 },
    ],
    spot: 100
  },
  'collar': {
    name: 'Collar (protetor)',
    legs: [
      { side: 'long', type: 'put', strike: 95, premium: 2.40, qty: 1 },
      { side: 'short', type: 'call', strike: 110, premium: 2.10, qty: 1 },
    ],
    spot: 100
  },
  'covered-call': {
    name: 'Covered Call',
    legs: [
      { side: 'long', type: 'future', strike: 100, premium: 0, qty: 1 },
      { side: 'short', type: 'call', strike: 105, premium: 3.20, qty: 1 },
    ],
    spot: 100
  }
};

function CalcPayoffPage() {
  const [preset, setPreset] = useState('bull-call');
  const [legs, setLegs] = useState(PRESETS['bull-call'].legs);
  const [spot, setSpot] = useState(PRESETS['bull-call'].spot);

  const loadPreset = (key) => {
    setPreset(key);
    setLegs(JSON.parse(JSON.stringify(PRESETS[key].legs)));
    setSpot(PRESETS[key].spot);
  };

  const updateLeg = (i, patch) => setLegs(legs.map((l, j) => j === i ? { ...l, ...patch } : l));
  const removeLeg = (i) => setLegs(legs.filter((_, j) => j !== i));
  const addLeg = () => setLegs([...legs, { side: 'long', type: 'call', strike: +spot, premium: 1, qty: 1 }]);

  // Analysis
  const minStrike = Math.min(...legs.map(l => l.strike));
  const maxStrike = Math.max(...legs.map(l => l.strike));
  const sMin = Math.max(0, Math.min(minStrike, spot) * 0.7);
  const sMax = Math.max(maxStrike, spot) * 1.3;
  const curve = IBDMath.payoffCurve(legs, sMin, sMax, 240);
  const bes = IBDMath.findBreakevens(legs, sMin, sMax, 800);

  const currentPL = IBDMath.strategyPayoff(legs, +spot);
  const maxP = Math.max(...curve.map(p => p.p));
  const minP = Math.min(...curve.map(p => p.p));

  const netDebit = legs.reduce((acc, l) => {
    if (l.type === 'future') return acc;
    return acc + (l.side === 'long' ? l.premium : -l.premium) * l.qty;
  }, 0);

  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>Payoff</span>
          </div>
          <div className="eyebrow eyebrow-accent">Estratégias · Múltiplas pernas</div>
          <h2 style={{marginTop: 'var(--s-2)'}}>Diagrama de Payoff</h2>
          <p style={{color: 'var(--fg-muted)', fontSize: 13, marginTop: 'var(--s-3)'}}>
            Resultado financeiro no vencimento, em função do preço do ativo subjacente.
          </p>

          <div style={{marginTop: 'var(--s-5)'}}>
            <div className="eyebrow" style={{fontSize: 10, marginBottom: 'var(--s-3)'}}>Estratégias predefinidas</div>
            <select className="form-select mono" value={preset} onChange={e => loadPreset(e.target.value)}>
              {Object.keys(PRESETS).map(k => <option key={k} value={k}>{PRESETS[k].name}</option>)}
            </select>
          </div>

          <NumField label="Preço à vista do subjacente" value={spot} setValue={setSpot} unit="R$" step={0.5} />

          <div style={{marginTop: 'var(--s-5)'}}>
            <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'baseline'}}>
              <div className="eyebrow" style={{fontSize: 10}}>Pernas da estratégia</div>
              <button className="btn-text" style={{fontSize: 12}} onClick={addLeg}>+ Adicionar</button>
            </div>

            <div style={{marginTop: 'var(--s-3)', display: 'flex', flexDirection: 'column', gap: 'var(--s-3)'}}>
              {legs.map((leg, i) => (
                <div key={i} style={{border: '1px solid var(--rule)', padding: 'var(--s-3)', background: 'var(--bg-elev)'}}>
                  <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 'var(--s-2)'}}>
                    <span className="mono" style={{fontSize: 11, color: 'var(--accent)'}}>PERNA {String(i+1).padStart(2,'0')}</span>
                    <button onClick={() => removeLeg(i)} className="btn-text" style={{fontSize: 11, color: 'var(--danger)'}}>Remover</button>
                  </div>
                  <div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--s-2)'}}>
                    <select className="form-select" value={leg.side} onChange={e => updateLeg(i, {side: e.target.value})} style={{padding: 8, fontSize: 13}}>
                      <option value="long">Comprado</option>
                      <option value="short">Vendido</option>
                    </select>
                    <select className="form-select" value={leg.type} onChange={e => updateLeg(i, {type: e.target.value})} style={{padding: 8, fontSize: 13}}>
                      <option value="call">Call</option>
                      <option value="put">Put</option>
                      <option value="future">Futuro / ativo</option>
                    </select>
                  </div>
                  <div style={{display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 'var(--s-2)', marginTop: 'var(--s-2)'}}>
                    <MiniField label="Strike" value={leg.strike} onChange={v => updateLeg(i, {strike: +v})} />
                    <MiniField label="Prêmio" value={leg.premium} onChange={v => updateLeg(i, {premium: +v})} disabled={leg.type === 'future'} />
                    <MiniField label="Qtde" value={leg.qty} onChange={v => updateLeg(i, {qty: +v})} />
                  </div>
                </div>
              ))}
            </div>
          </div>
        </aside>

        <div className="tool-output">
          <div className="eyebrow eyebrow-accent">Resultado · {PRESETS[preset]?.name || 'Estratégia customizada'}</div>
          <div style={{display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, marginTop: 'var(--s-4)', border: '1px solid var(--rule)'}}>
            <KV label="P&L no preço atual" value={IBDMath.fmtBRL(currentPL)} sign={currentPL >= 0 ? 'pos' : 'neg'} />
            <KV label="Máximo teórico" value={maxP > 1e6 ? 'Ilimitado' : IBDMath.fmtBRL(maxP)} sign="pos" />
            <KV label="Perda máxima" value={minP < -1e6 ? 'Ilimitada' : IBDMath.fmtBRL(minP)} sign="neg" />
            <KV label={netDebit >= 0 ? 'Débito líquido' : 'Crédito líquido'} value={IBDMath.fmtBRL(Math.abs(netDebit))} />
          </div>

          <div className="panel" style={{marginTop: 'var(--s-5)'}}>
            <div className="panel-head">
              <h3>Payoff no vencimento</h3>
              <span className="mono" style={{fontSize: 11, color: 'var(--fg-muted)'}}>
                Breakevens: {bes.length === 0 ? '—' : bes.map(b => b.toFixed(2)).join(' · ')}
              </span>
            </div>
            <PayoffChart curve={curve} spot={+spot} breakevens={bes} legs={legs} />
          </div>

          <div className="panel" style={{marginTop: 'var(--s-5)'}}>
            <div className="panel-head">
              <h3>Tabela de payoff por cenário</h3>
            </div>
            <table className="table">
              <thead>
                <tr>
                  <th>Cenário</th>
                  <th className="num">Preço (S<sub>T</sub>)</th>
                  <th className="num">Variação vs. à vista</th>
                  <th className="num">P&L da estratégia</th>
                  <th className="num">Resultado</th>
                </tr>
              </thead>
              <tbody>
                {[-0.20, -0.10, -0.05, 0, 0.05, 0.10, 0.20].map(d => {
                  const ST = +spot * (1 + d);
                  const p = IBDMath.strategyPayoff(legs, ST);
                  return (
                    <tr key={d}>
                      <td>{d === 0 ? 'À vista' : (d > 0 ? '+' : '') + (d * 100).toFixed(0) + '%'}</td>
                      <td className="num">{ST.toFixed(2)}</td>
                      <td className="num" style={{color: 'var(--fg-muted)'}}>{(d * 100).toFixed(1)}%</td>
                      <td className="num" style={{color: p >= 0 ? 'var(--success)' : 'var(--danger)', fontWeight: 500}}>{IBDMath.fmtBRL(p)}</td>
                      <td className="num">
                        <span className="tag" style={{borderColor: p >= 0 ? 'var(--success)' : 'var(--danger)', color: p >= 0 ? 'var(--success)' : 'var(--danger)'}}>
                          {p > 0 ? 'LUCRO' : p < 0 ? 'PERDA' : 'NULO'}
                        </span>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </Page>
  );
}

function MiniField({ label, value, onChange, disabled }) {
  return (
    <div>
      <div className="eyebrow" style={{fontSize: 9, marginBottom: 2}}>{label}</div>
      <input
        type="number"
        step="0.01"
        value={value}
        onChange={e => onChange(e.target.value)}
        disabled={disabled}
        className="mono"
        style={{
          width: '100%', padding: 8, border: '1px solid var(--rule-strong)',
          background: disabled ? 'var(--bg-sunken)' : 'var(--bg-elev)',
          color: disabled ? 'var(--fg-subtle)' : 'var(--fg)',
          fontSize: 13
        }}
      />
    </div>
  );
}

function KV({ label, value, sign }) {
  return (
    <div style={{padding: 'var(--s-4)', borderRight: '1px solid var(--rule)'}}>
      <div className="eyebrow" style={{fontSize: 10}}>{label}</div>
      <div className={'mono ' + (sign === 'pos' ? 'kv-value pos' : sign === 'neg' ? 'kv-value neg' : 'kv-value')} style={{fontSize: 20, marginTop: 6, color: sign === 'pos' ? 'var(--success)' : sign === 'neg' ? 'var(--danger)' : 'var(--fg)'}}>
        {value}
      </div>
    </div>
  );
}

function PayoffChart({ curve, spot, breakevens, legs }) {
  const w = 800, h = 360, pad = { l: 56, r: 20, t: 20, b: 36 };
  const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b;

  const sMin = curve[0].s, sMax = curve[curve.length - 1].s;
  const yMin0 = Math.min(...curve.map(p => p.p));
  const yMax0 = Math.max(...curve.map(p => p.p));
  const yRange = Math.max(Math.abs(yMin0), Math.abs(yMax0));
  const yMin = -yRange * 1.1, yMax = yRange * 1.1;

  const x = s => pad.l + ((s - sMin) / (sMax - sMin)) * iw;
  const y = v => pad.t + ih - ((v - yMin) / (yMax - yMin)) * ih;
  const y0 = y(0);

  // build path with area split (positive green, negative red)
  const path = curve.map((p, i) => (i === 0 ? 'M' : 'L') + x(p.s).toFixed(2) + ',' + y(p.p).toFixed(2)).join(' ');

  // areas
  const posArea = [
    `M ${pad.l},${y0}`,
    ...curve.map(p => `L ${x(p.s).toFixed(2)},${y(Math.max(p.p, 0)).toFixed(2)}`),
    `L ${pad.l + iw},${y0}`,
    'Z'
  ].join(' ');
  const negArea = [
    `M ${pad.l},${y0}`,
    ...curve.map(p => `L ${x(p.s).toFixed(2)},${y(Math.min(p.p, 0)).toFixed(2)}`),
    `L ${pad.l + iw},${y0}`,
    'Z'
  ].join(' ');

  const xTicks = 8, yTicks = 6;
  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 - yMin) / 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(0)}</text>
            </g>
          );
        })}
        {Array.from({length: xTicks + 1}, (_, i) => {
          const xx = pad.l + (iw / xTicks) * i;
          const v = sMin + ((sMax - sMin) / 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>
          );
        })}

        {/* zero line */}
        <line x1={pad.l} x2={pad.l + iw} y1={y0} y2={y0} stroke="var(--fg-muted)" strokeWidth="1" />

        {/* areas */}
        <path d={posArea} fill="color-mix(in srgb, var(--success) 14%, transparent)" />
        <path d={negArea} fill="color-mix(in srgb, var(--danger) 14%, transparent)" />

        {/* main curve */}
        <path d={path} fill="none" stroke="var(--primary)" strokeWidth="2.2" />

        {/* strikes */}
        {legs.map((l, i) => (
          <g key={'k' + i}>
            <line x1={x(l.strike)} x2={x(l.strike)} y1={pad.t} y2={pad.t + ih} stroke="var(--fg-subtle)" strokeWidth="1" strokeDasharray="2 3" opacity="0.6" />
            <text x={x(l.strike)} y={pad.t + ih - 4} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill="var(--fg-muted)">K{i+1}</text>
          </g>
        ))}

        {/* breakevens */}
        {breakevens.map((b, i) => (
          <g key={'b' + i}>
            <line x1={x(b)} x2={x(b)} y1={y0 - 6} y2={y0 + 6} stroke="var(--accent)" strokeWidth="2" />
            <text x={x(b)} y={y0 - 10} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill="var(--accent)">BE {b.toFixed(2)}</text>
          </g>
        ))}

        {/* spot marker */}
        <line x1={x(spot)} x2={x(spot)} y1={pad.t} y2={pad.t + ih} stroke="var(--accent)" strokeWidth="1.5" strokeDasharray="4 4" />
        <text x={x(spot)} y={pad.t + 14} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="11" fill="var(--accent)">S₀ {spot.toFixed(2)}</text>

        <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 NO VENCIMENTO (S_T)</text>
        <text x={14} y={pad.t + ih / 2} fontFamily="var(--font-sans)" fontSize="11" fill="var(--fg-muted)" letterSpacing="0.1em" transform={`rotate(-90, 14, ${pad.t + ih / 2})`}>P&L (R$)</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>Payoff total</span>
        <span><span className="swatch" style={{background: 'var(--accent)'}}></span>S à vista / breakeven</span>
        <span><span className="swatch" style={{background: 'color-mix(in srgb, var(--success) 30%, transparent)'}}></span>Lucro</span>
        <span><span className="swatch" style={{background: 'color-mix(in srgb, var(--danger) 30%, transparent)'}}></span>Perda</span>
      </div>
    </div>
  );
}

window.CalcPayoffPage = CalcPayoffPage;
