/* P20h · Paper Trading Simulator (M07.E03)
 * Bar replay + entry/stop/target. Sistema simula ejecución y rastrea stats.
 * Watermark "Simulación. No es track record." permanente.
 */

function P20h_PaperTrading(props = {}) {
  const bars = React.useMemo(() => window.synthetic.makeSeries({ seed: 23, n: 280, drift: 0.0011, vol: 0.014, cycles: 3, regime: 'uptrend' }), []);
  const [visibleBars, setVisibleBars] = React.useState(165);
  const [playing, setPlaying] = React.useState(false);
  const [speed, setSpeed] = React.useState(2);

  // Trade actual en composición
  const [currentTrade, setCurrentTrade] = React.useState(props.currentTrade || {
    entry: 117.4,
    stop: 113.8,
    target: 125.2,
    size: 1,
  });

  // Trades cerrados (historial)
  const [trades, setTrades] = React.useState(props.trades || generateMockTrades());

  // Tick replay
  React.useEffect(() => {
    if (!playing) return;
    const t = setInterval(() => {
      setVisibleBars((v) => v >= bars.length ? v : v + 1);
    }, 1000 / speed);
    return () => clearInterval(t);
  }, [playing, speed, bars.length]);

  function generateMockTrades() {
    return [
      { id: 1, entry: 103.2, stop: 100.8, target: 108.4, exit: 108.4, exitReason: 'target', pnl: 5.2, r: 2.17 },
      { id: 2, entry: 105.6, stop: 103.1, target: 112.0, exit: 103.1, exitReason: 'stop', pnl: -2.5, r: -1.0 },
      { id: 3, entry: 110.4, stop: 108.0, target: 117.0, exit: 117.0, exitReason: 'target', pnl: 6.6, r: 2.75 },
      { id: 4, entry: 114.2, stop: 111.5, target: 121.0, exit: 121.0, exitReason: 'target', pnl: 6.8, r: 2.52 },
      { id: 5, entry: 116.8, stop: 114.0, target: 124.0, exit: 114.0, exitReason: 'stop', pnl: -2.8, r: -1.0 },
      { id: 6, entry: 119.6, stop: 116.8, target: 127.0, exit: 127.0, exitReason: 'target', pnl: 7.4, r: 2.64 },
      { id: 7, entry: 113.0, stop: 110.2, target: 120.0, exit: 110.2, exitReason: 'stop', pnl: -2.8, r: -1.0 },
      { id: 8, entry: 121.0, stop: 118.5, target: 128.0, exit: 128.0, exitReason: 'target', pnl: 7.0, r: 2.8 },
      { id: 9, entry: 124.0, stop: 121.0, target: 131.0, exit: 121.0, exitReason: 'stop', pnl: -3.0, r: -1.0 },
      { id: 10, entry: 118.0, stop: 115.5, target: 125.0, exit: 125.0, exitReason: 'target', pnl: 7.0, r: 2.8 },
      { id: 11, entry: 122.0, stop: 119.5, target: 129.0, exit: 129.0, exitReason: 'target', pnl: 7.0, r: 2.8 },
      { id: 12, entry: 127.0, stop: 124.0, target: 134.0, exit: 124.0, exitReason: 'stop', pnl: -3.0, r: -1.0 },
    ];
  }

  // Stats
  const stats = React.useMemo(() => {
    if (trades.length === 0) return null;
    const wins = trades.filter((t) => t.pnl > 0);
    const losses = trades.filter((t) => t.pnl <= 0);
    const winrate = wins.length / trades.length;
    const avgWin = wins.reduce((s, t) => s + t.r, 0) / Math.max(1, wins.length);
    const avgLoss = losses.reduce((s, t) => s + t.r, 0) / Math.max(1, losses.length);
    const expectancy = winrate * avgWin + (1 - winrate) * avgLoss;
    const totalR = trades.reduce((s, t) => s + t.r, 0);
    // Drawdown
    let peak = 0, maxDD = 0, runningR = 0;
    trades.forEach((t) => {
      runningR += t.r;
      peak = Math.max(peak, runningR);
      maxDD = Math.min(maxDD, runningR - peak);
    });
    return { n: trades.length, wins: wins.length, losses: losses.length, winrate, avgWin, avgLoss, expectancy, totalR, maxDD };
  }, [trades]);

  // Drawings: entry/stop/target como horizontal levels
  const tradeDrawings = currentTrade ? [
    { type: 'horizontal', kind: 'support', price: currentTrade.stop, state: 'valid', id: 'stop' },
    { type: 'horizontal', kind: 'resistance', price: currentTrade.target, state: 'valid', id: 'target' },
  ] : [];

  // Marker custom para entry: línea verde
  const entryOverlay = currentTrade ? (
    <g>
      <line
        x1={14} y1={getY(currentTrade.entry)}
        x2={780} y2={getY(currentTrade.entry)}
        stroke="var(--signal-info)" strokeWidth={1.5} strokeDasharray="6 3"
      />
      <rect x={742} y={getY(currentTrade.entry) - 9} width={36} height={18} rx={2} fill="var(--signal-info)" />
      <text x={760} y={getY(currentTrade.entry) + 4} textAnchor="middle" fontSize={10} fontWeight={700} fill="#0A0C10" fontFamily="JetBrains Mono">{currentTrade.entry.toFixed(1)}</text>
    </g>
  ) : null;

  // Pequeño hack: usamos ChartCanvas pero queremos overlay extra. La ChartCanvas no acepta children custom para overlay, así que mockeamos las líneas vía drawings:
  function getY(price) {
    // approximate y in our chart — won't be exact, will be remapped via drawings
    return 0;
  }

  // Mejor: usar drawings completos
  const allDrawings = currentTrade ? [
    { type: 'horizontal', kind: 'entry', price: currentTrade.entry, state: 'valid', id: 'entry', label: `E ${currentTrade.entry.toFixed(1)}` },
    { type: 'horizontal', kind: 'resistance', price: currentTrade.target, state: 'valid', id: 'target', label: `T ${currentTrade.target.toFixed(1)}` },
    { type: 'horizontal', kind: 'support', price: currentTrade.stop, state: 'valid', id: 'stop', label: `S ${currentTrade.stop.toFixed(1)}` },
  ] : [];

  return (
    <div className="shell-main" style={{ height: '100%' }}>
      <div className="lab-header">
        <div>
          <div className="lab-header-id">M07 · E03 · Paper Trading</div>
          <div className="lab-header-title">Coloca entry / stop / target sobre el chart. La ejecución se simula contra el dataset oculto.</div>
        </div>
        <div className="lab-header-counter">
          <div className="counter-pill"><span className="label">Trades</span>{trades.length}<span style={{ color: 'var(--text-muted)' }}>/30</span></div>
          <div className="counter-pill"><span className="label">Winrate</span>{stats ? (stats.winrate * 100).toFixed(0) + '%' : '—'}</div>
          <div className="counter-pill"><span className="label">Expectancy</span>{stats ? stats.expectancy.toFixed(2) + 'R' : '—'}</div>
        </div>
      </div>

      <div className="lab-body" style={{ gridTemplateColumns: '1fr 320px' }}>
        <div className="lab-canvas-area" style={{ flexDirection: 'column', gap: 12, padding: 16 }}>
          <ChartCanvas
            bars={bars}
            visibleBars={visibleBars}
            width={800}
            height={420}
            anonymized
            ticker="ANON_H"
            drawings={allDrawings}
            extraOverlay={
              currentTrade && (
                <PaperTradeOverlay trade={currentTrade} bars={bars} visibleBars={visibleBars} chartWidth={800} chartHeight={420} />
              )
            }
          />

          <div className="replay-controls" style={{ width: 800 }}>
            <button className="btn btn-icon" onClick={() => setPlaying(!playing)}>
              {playing ? Icon.pause(14) : Icon.play(14)}
            </button>
            <button className="btn btn-icon" onClick={() => setVisibleBars(v => Math.min(bars.length, v + 1))}>{Icon.step(14)}</button>
            <div className="replay-track">
              <div className="fill" style={{ width: `${(visibleBars / bars.length) * 100}%` }} />
            </div>
            <div className="speed">
              {[1, 2, 4, 8].map(s => (
                <button key={s} onClick={() => setSpeed(s)} className="btn btn-ghost" style={{ padding: '4px 8px', color: speed === s ? 'var(--text-primary)' : 'var(--text-muted)' }}>{s}×</button>
              ))}
            </div>
            <span className="replay-cement-notice">Forward-only</span>
          </div>

          {/* Watermark grande del modo paper trading */}
          <div style={{
            border: '1px solid var(--signal-warning)', borderRadius: 'var(--radius-sm)',
            padding: '8px 12px', background: 'var(--signal-warning-soft)',
            color: 'var(--signal-warning)', fontSize: 'var(--size-xs)',
            display: 'flex', alignItems: 'center', gap: 10, width: 800,
          }}>
            {Icon.warn(14)}
            <strong>Resultado de simulación educativa.</strong>
            <span>No es track record. La ejecución real difiere por slippage, fills, sesgo emocional y costes.</span>
          </div>
        </div>

        <div className="lab-side">
          <div className="side-section">
            <h4>Trade en composición</h4>
            <TradeInput label="Entry" value={currentTrade.entry} color="var(--signal-info)"
              onChange={(v) => setCurrentTrade({ ...currentTrade, entry: v })} />
            <TradeInput label="Stop" value={currentTrade.stop} color="var(--signal-fail)"
              onChange={(v) => setCurrentTrade({ ...currentTrade, stop: v })} />
            <TradeInput label="Target" value={currentTrade.target} color="var(--signal-pass)"
              onChange={(v) => setCurrentTrade({ ...currentTrade, target: v })} />
            <div style={{ display: 'flex', gap: 12, marginTop: 10, fontSize: 'var(--size-xs)', fontFamily: 'var(--font-mono)', color: 'var(--text-secondary)' }}>
              <div>
                <div style={{ color: 'var(--text-muted)', fontSize: 10 }}>R:R</div>
                <div style={{ fontSize: 14, color: 'var(--text-primary)' }}>{((currentTrade.target - currentTrade.entry) / (currentTrade.entry - currentTrade.stop)).toFixed(2)}</div>
              </div>
              <div>
                <div style={{ color: 'var(--text-muted)', fontSize: 10 }}>Riesgo</div>
                <div style={{ fontSize: 14, color: 'var(--text-primary)' }}>{(currentTrade.entry - currentTrade.stop).toFixed(2)}</div>
              </div>
              <div>
                <div style={{ color: 'var(--text-muted)', fontSize: 10 }}>Recompensa</div>
                <div style={{ fontSize: 14, color: 'var(--text-primary)' }}>{(currentTrade.target - currentTrade.entry).toFixed(2)}</div>
              </div>
            </div>
            <button className="btn btn-primary" style={{ marginTop: 12, width: '100%' }}>Cementar y ejecutar contra replay</button>
          </div>

          <div className="side-section">
            <h4>Estadísticas <span className="count">{trades.length} trades</span></h4>
            {stats && (
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, fontFamily: 'var(--font-mono)', fontSize: 'var(--size-xs)' }}>
                <Stat label="Winrate" value={(stats.winrate * 100).toFixed(0) + '%'} />
                <Stat label="Expectancy" value={stats.expectancy.toFixed(2) + 'R'} good={stats.expectancy > 0} />
                <Stat label="Avg Win" value={stats.avgWin.toFixed(2) + 'R'} />
                <Stat label="Avg Loss" value={stats.avgLoss.toFixed(2) + 'R'} />
                <Stat label="Total" value={stats.totalR.toFixed(1) + 'R'} good={stats.totalR > 0} />
                <Stat label="Max DD" value={stats.maxDD.toFixed(1) + 'R'} bad />
              </div>
            )}
          </div>

          <div className="side-section" style={{ flex: 1, overflowY: 'auto', maxHeight: 220 }}>
            <h4>Trades ejecutados</h4>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
              {trades.slice(-8).reverse().map((t) => (
                <div key={t.id} style={{
                  display: 'grid', gridTemplateColumns: '20px 1fr auto', alignItems: 'center', gap: 8,
                  padding: '5px 8px', background: 'var(--surface-2)', borderRadius: 2,
                  fontFamily: 'var(--font-mono)', fontSize: 10,
                }}>
                  <span style={{ color: 'var(--text-muted)' }}>#{t.id}</span>
                  <span style={{ color: 'var(--text-secondary)' }}>{t.entry.toFixed(2)} → {t.exit.toFixed(2)}</span>
                  <span style={{ color: t.pnl > 0 ? 'var(--signal-pass)' : 'var(--signal-fail)', fontWeight: 600 }}>{t.r > 0 ? '+' : ''}{t.r.toFixed(2)}R</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>

      <div className="lab-footer">
        <FeedbackBanner
          kind="warn"
          icon={Icon.warn(11)}
          message="Watermark permanente: estos resultados no se exportan como track record. PDF incluye el disclaimer incrustado."
        />
      </div>
    </div>
  );
}

function TradeInput({ label, value, color, onChange }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
      <span style={{ width: 60, fontSize: 'var(--size-xs)', color: 'var(--text-muted)' }}>{label}</span>
      <div style={{ width: 8, height: 8, borderRadius: 2, background: color }} />
      <input type="number" step="0.1" value={value} onChange={(e) => onChange(parseFloat(e.target.value))}
        style={{ flex: 1, background: 'var(--surface-2)', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-sm)', padding: '4px 8px', color: 'var(--text-primary)', fontFamily: 'var(--font-mono)', fontSize: 13 }} />
    </div>
  );
}
function Stat({ label, value, good, bad }) {
  return (
    <div style={{ padding: '6px 8px', background: 'var(--surface-2)', borderRadius: 2 }}>
      <div style={{ fontSize: 10, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>{label}</div>
      <div style={{ fontSize: 16, color: good ? 'var(--signal-pass)' : bad ? 'var(--signal-fail)' : 'var(--text-primary)', fontWeight: 600 }}>{value}</div>
    </div>
  );
}

function PaperTradeOverlay({ trade, bars, visibleBars, chartWidth, chartHeight }) {
  // Simple overlay rendering of entry line — placed at the right edge as label
  // El componente ChartCanvas no expone yOf directamente; usamos un truco: aprovechamos
  // que la línea entry irá renderizada como un horizontal level vía drawings.
  return null;
}

window.P20h_PaperTrading = P20h_PaperTrading;
