/* ============================================================
   Futures simulator — daily mark-to-market + margin calls
   ============================================================ */

const CONTRACTS = {
  'WDO': { name: 'WDO · Mini-dólar', size: 10, im: 800, mm: 600, ticker: 'WDO', basePx: 5.10, vol: 0.12 },
  'WIN': { name: 'WIN · Mini-índice', size: 0.2, im: 200, mm: 150, ticker: 'WIN', basePx: 138000, vol: 0.18 },
  'BGI': { name: 'BGI · Boi gordo', size: 330, im: 4500, mm: 3500, ticker: 'BGI', basePx: 320, vol: 0.14 },
  'ICF': { name: 'ICF · Café arábica', size: 100, im: 6800, mm: 5200, ticker: 'ICF', basePx: 1482, vol: 0.22 },
  'CCM': { name: 'CCM · Milho', size: 450, im: 1200, mm: 900, ticker: 'CCM', basePx: 72, vol: 0.16 },
};

function CalcFuturosPage() {
  const [contractKey, setContractKey] = useState('WDO');
  const [side, setSide] = useState('long');
  const [qty, setQty] = useState(5);
  const [days, setDays] = useState(30);
  const [drift, setDrift] = useState(0);
  const [vol, setVol] = useState(12);
  const [seed, setSeed] = useState(42);
  const [scenario, setScenario] = useState('random');

  const contract = CONTRACTS[contractKey];

  const result = useMemo(() => {
    let priceSeries;
    if (scenario === 'random') {
      priceSeries = IBDMath.gbmSeries(contract.basePx, drift / 100, vol / 100, days, seed);
    } else if (scenario === 'up') {
      priceSeries = Array.from({length: days + 1}, (_, i) => contract.basePx * (1 + 0.001 * i + (i === 0 ? 0 : Math.sin(i * 0.5) * 0.003)));
    } else if (scenario === 'down') {
      priceSeries = Array.from({length: days + 1}, (_, i) => contract.basePx * (1 - 0.0015 * i + (i === 0 ? 0 : Math.sin(i * 0.5) * 0.003)));
    } else if (scenario === 'crash') {
      priceSeries = Array.from({length: days + 1}, (_, i) => {
        const crashDay = Math.floor(days * 0.4);
        if (i < crashDay) return contract.basePx * (1 + Math.sin(i * 0.4) * 0.005);
        const drop = Math.min((i - crashDay) * 0.012, 0.18);
        return contract.basePx * (1 - drop + Math.sin(i * 0.4) * 0.003);
      });
    }
    return IBDMath.simulateFutures({
      side,
      qty: +qty,
      entryPrice: contract.basePx,
      contractSize: contract.size,
      initialMargin: contract.im,
      maintenanceMargin: contract.mm,
      priceSeries
    });
  }, [contractKey, side, qty, days, drift, vol, seed, scenario]);

  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>Simulador de Futuros</span>
          </div>
          <div className="eyebrow eyebrow-accent">Simulação · Fluxo financeiro diário</div>
          <h2 style={{marginTop: 'var(--s-2)'}}>Simulador de Futuros</h2>
          <p style={{color: 'var(--fg-muted)', fontSize: 13, marginTop: 'var(--s-3)'}}>
            Simule ajuste diário, P&L acumulado, chamadas de margem e retorno sobre garantia.
          </p>

          <div style={{marginTop: 'var(--s-5)'}}>
            <div className="eyebrow" style={{fontSize: 10, marginBottom: 'var(--s-3)'}}>Contrato</div>
            <select className="form-select mono" value={contractKey} onChange={e => setContractKey(e.target.value)}>
              {Object.entries(CONTRACTS).map(([k, c]) => <option key={k} value={k}>{c.name}</option>)}
            </select>
            <div className="mono" style={{fontSize: 11, color: 'var(--fg-muted)', marginTop: 8, lineHeight: 1.7}}>
              Tamanho do contrato · {contract.size}<br/>
              Margem inicial · R$ {contract.im.toLocaleString('pt-BR')}<br/>
              Margem mantenedora · R$ {contract.mm.toLocaleString('pt-BR')}<br/>
              Preço-base · {contract.basePx.toLocaleString('pt-BR')}
            </div>
          </div>

          <div style={{marginTop: 'var(--s-5)'}}>
            <div className="eyebrow" style={{fontSize: 10, marginBottom: 'var(--s-3)'}}>Posição</div>
            <div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', border: '1px solid var(--rule-strong)'}}>
              <button onClick={() => setSide('long')} className="mono"
                      style={{padding: 12, background: side === 'long' ? 'var(--success)' : 'transparent',
                              color: side === 'long' ? 'white' : 'var(--fg)', border: 'none',
                              fontSize: 13, letterSpacing: '0.08em', textTransform: 'uppercase', cursor: 'pointer'}}>
                Comprado
              </button>
              <button onClick={() => setSide('short')} className="mono"
                      style={{padding: 12, background: side === 'short' ? 'var(--danger)' : 'transparent',
                              color: side === 'short' ? 'white' : 'var(--fg)', border: 'none',
                              borderLeft: '1px solid var(--rule-strong)',
                              fontSize: 13, letterSpacing: '0.08em', textTransform: 'uppercase', cursor: 'pointer'}}>
                Vendido
              </button>
            </div>
          </div>

          <NumField label="Quantidade de contratos" value={qty} setValue={setQty} unit="ctr" step={1} />
          <NumField label="Horizonte" value={days} setValue={setDays} unit="dias" step={1} />

          <div style={{marginTop: 'var(--s-5)'}}>
            <div className="eyebrow" style={{fontSize: 10, marginBottom: 'var(--s-3)'}}>Cenário de preço</div>
            <select className="form-select" value={scenario} onChange={e => setScenario(e.target.value)}>
              <option value="random">Aleatório (GBM)</option>
              <option value="up">Tendência de alta</option>
              <option value="down">Tendência de baixa</option>
              <option value="crash">Choque adverso</option>
            </select>
          </div>

          {scenario === 'random' && (
            <>
              <NumField label="Drift anual (μ)" value={drift} setValue={setDrift} unit="%" step={1} hint="Tendência esperada do preço." />
              <NumField label="Volatilidade (σ)" value={vol} setValue={setVol} unit="%" step={1} hint="Volatilidade anualizada." />
              <NumField label="Semente aleatória" value={seed} setValue={setSeed} unit="seed" step={1} hint="Para reproduzir o mesmo caminho de preço." />
            </>
          )}
        </aside>

        <div className="tool-output">
          <div className="eyebrow eyebrow-accent">
            Resultado · {contract.name} · {qty} {qty > 1 ? 'contratos' : 'contrato'} · {side === 'long' ? 'comprado' : 'vendido'} · {days} dias
          </div>

          <div style={{display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, marginTop: 'var(--s-4)', border: '1px solid var(--rule)'}}>
            <KV label="P&L total" value={IBDMath.fmtBRL(result.totalPnL)} sign={result.totalPnL >= 0 ? 'pos' : 'neg'} />
            <KV label="Margem aportada" value={IBDMath.fmtBRL(result.totalDeposits)} />
            <KV label="Retorno sobre margem" value={IBDMath.fmtPct(result.returnOnMargin, 2)} sign={result.returnOnMargin >= 0 ? 'pos' : 'neg'} />
            <KV label="Chamadas de margem" value={String(result.marginCallsCount)} sign={result.marginCallsCount > 0 ? 'neg' : null} />
          </div>

          <div className="panel" style={{marginTop: 'var(--s-5)'}}>
            <div className="panel-head">
              <h3>Preço, P&L acumulado e patrimônio em margem</h3>
              <span className="mono" style={{fontSize: 11, color: 'var(--fg-muted)'}}>D+0 → D+{days}</span>
            </div>
            <FuturesChart rows={result.rows} contract={contract} />
          </div>

          <div className="panel" style={{marginTop: 'var(--s-5)'}}>
            <div className="panel-head">
              <h3>Fluxo financeiro diário · D+0 a D+{Math.min(days, 14)}</h3>
              {days > 14 && <span className="mono" style={{fontSize: 11, color: 'var(--fg-muted)'}}>Mostrando primeiros 15 dias</span>}
            </div>
            <table className="table">
              <thead>
                <tr>
                  <th>Dia</th>
                  <th className="num">Preço</th>
                  <th className="num">Ajuste diário</th>
                  <th className="num">P&L acumulado</th>
                  <th className="num">Patrimônio em margem</th>
                  <th className="num">Chamada</th>
                </tr>
              </thead>
              <tbody>
                {result.rows.slice(0, 15).map(r => (
                  <tr key={r.day}>
                    <td className="mono">D+{r.day}</td>
                    <td className="num">{r.price.toLocaleString('pt-BR', {maximumFractionDigits: 3})}</td>
                    <td className="num" style={{color: r.variation >= 0 ? 'var(--success)' : 'var(--danger)'}}>
                      {r.variation > 0 ? '+' : ''}{IBDMath.fmtBRL(r.variation)}
                    </td>
                    <td className="num" style={{color: r.cumPnL >= 0 ? 'var(--success)' : 'var(--danger)'}}>
                      {IBDMath.fmtBRL(r.cumPnL)}
                    </td>
                    <td className="num">{IBDMath.fmtBRL(r.equity)}</td>
                    <td className="num" style={{color: r.marginCall > 0 ? 'var(--danger)' : 'var(--fg-subtle)'}}>
                      {r.marginCall > 0 ? IBDMath.fmtBRL(r.marginCall) : '—'}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          <div className="notice notice-warn" style={{marginTop: 'var(--s-5)'}}>
            <div>
              <strong>Metodologia.</strong> O ajuste diário é calculado como variação de preço × tamanho do contrato × quantidade × sinal da posição.
              Quando o patrimônio em margem cai abaixo da mantenedora, simula-se chamada de margem para reposição até a margem inicial.
              Preços aleatórios seguem GBM com base 252 dias úteis/ano.
            </div>
          </div>
        </div>
      </div>
    </Page>
  );
}

function FuturesChart({ rows, contract }) {
  const w = 800, h = 320, pad = { l: 60, r: 60, t: 20, b: 36 };
  const iw = w - pad.l - pad.r, ih = h - pad.t - pad.b;

  const prices = rows.map(r => r.price);
  const pnls = rows.map(r => r.cumPnL);
  const equities = rows.map(r => r.equity);

  const pMin = Math.min(...prices) * 0.99;
  const pMax = Math.max(...prices) * 1.01;
  const yMin = Math.min(0, Math.min(...pnls));
  const yMax = Math.max(0, Math.max(...pnls), Math.max(...equities));
  const yMinAll = Math.min(yMin, 0);

  const x = i => pad.l + (i / (rows.length - 1)) * iw;
  const yP = v => pad.t + ih - ((v - pMin) / (pMax - pMin)) * ih;
  const yL = v => pad.t + ih - ((v - yMinAll) / (yMax - yMinAll)) * ih;

  const pricePath = rows.map((r, i) => (i === 0 ? 'M' : 'L') + x(i).toFixed(2) + ',' + yP(r.price).toFixed(2)).join(' ');
  const pnlPath = rows.map((r, i) => (i === 0 ? 'M' : 'L') + x(i).toFixed(2) + ',' + yL(r.cumPnL).toFixed(2)).join(' ');
  const eqPath = rows.map((r, i) => (i === 0 ? 'M' : 'L') + x(i).toFixed(2) + ',' + yL(r.equity).toFixed(2)).join(' ');
  const zeroY = yL(0);

  const callDays = rows.filter(r => r.marginCall > 0);

  return (
    <div style={{overflow: 'hidden'}}>
      <svg viewBox={`0 0 ${w} ${h}`} style={{width: '100%', height: 'auto', display: 'block'}}>
        {/* grid */}
        {Array.from({length: 6}, (_, i) => {
          const yy = pad.t + (ih / 5) * i;
          return <line key={i} x1={pad.l} x2={pad.l + iw} y1={yy} y2={yy} stroke="var(--rule)" strokeWidth="1" />;
        })}

        {/* day labels */}
        {Array.from({length: 6}, (_, i) => {
          const dayIdx = Math.round((rows.length - 1) * (i / 5));
          const xx = x(dayIdx);
          return (
            <text key={i} x={xx} y={pad.t + ih + 18} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill="var(--fg-muted)">D+{dayIdx}</text>
          );
        })}

        {/* zero line for P&L */}
        <line x1={pad.l} x2={pad.l + iw} y1={zeroY} y2={zeroY} stroke="var(--fg-muted)" strokeWidth="1" strokeDasharray="3 3" />

        {/* margin call markers */}
        {callDays.map(r => (
          <g key={r.day}>
            <line x1={x(r.day)} x2={x(r.day)} y1={pad.t} y2={pad.t + ih} stroke="var(--danger)" strokeWidth="1" opacity="0.4" />
            <circle cx={x(r.day)} cy={pad.t + 10} r="3.5" fill="var(--danger)" />
          </g>
        ))}

        {/* price (right axis) */}
        <path d={pricePath} fill="none" stroke="var(--fg-muted)" strokeWidth="1.2" strokeDasharray="2 3" />

        {/* equity */}
        <path d={eqPath} fill="none" stroke="var(--accent)" strokeWidth="1.6" />

        {/* P&L (main) */}
        <path d={pnlPath} fill="none" stroke="var(--primary)" strokeWidth="2.4" />

        {/* left axis (P&L) */}
        {Array.from({length: 6}, (_, i) => {
          const yy = pad.t + (ih / 5) * i;
          const v = yMax - ((yMax - yMinAll) / 5) * i;
          return <text key={'lv' + i} x={pad.l - 8} y={yy + 4} textAnchor="end" fontFamily="var(--font-mono)" fontSize="10" fill="var(--fg-muted)">{Math.round(v).toLocaleString('pt-BR')}</text>;
        })}

        {/* right axis (price) */}
        {Array.from({length: 6}, (_, i) => {
          const yy = pad.t + (ih / 5) * i;
          const v = pMax - ((pMax - pMin) / 5) * i;
          return <text key={'rv' + i} x={pad.l + iw + 8} y={yy + 4} textAnchor="start" fontFamily="var(--font-mono)" fontSize="10" fill="var(--fg-muted)">{v.toFixed(2)}</text>;
        })}

        {/* axis titles */}
        <text x={pad.l + iw / 2} y={h - 6} textAnchor="middle" fontFamily="var(--font-sans)" fontSize="11" fill="var(--fg-muted)" letterSpacing="0.1em">DIAS DE PREGÃO</text>
        <text x={14} y={pad.t + ih / 2} fontFamily="var(--font-sans)" fontSize="10" fill="var(--fg-muted)" letterSpacing="0.08em" transform={`rotate(-90, 14, ${pad.t + ih / 2})`}>P&L · R$</text>
        <text x={w - 4} y={pad.t + ih / 2} fontFamily="var(--font-sans)" fontSize="10" fill="var(--fg-muted)" letterSpacing="0.08em" textAnchor="end" transform={`rotate(-90, ${w - 4}, ${pad.t + ih / 2})`}>PREÇO · {contract.ticker}</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)', flexWrap: 'wrap', fontFamily: 'var(--font-sans)', fontSize: 12, color: 'var(--fg-muted)'}}>
        <span><span className="swatch" style={{background: 'var(--primary)'}}></span>P&L acumulado</span>
        <span><span className="swatch" style={{background: 'var(--accent)'}}></span>Patrimônio em margem</span>
        <span><span className="swatch" style={{background: 'var(--fg-muted)'}}></span>Preço do contrato</span>
        <span><span className="swatch" style={{background: 'var(--danger)'}}></span>Chamada de margem</span>
      </div>
    </div>
  );
}

window.CalcFuturosPage = CalcFuturosPage;
