/* live.jsx — Avero Operator Console — real-time data layer
   - useLiveFeed: a polling hook that mimics a WebSocket subscription, pushing
     fresh price/equity payloads into state on an interval (no page reload).
   - LiveDot: blinking green indicator that flashes when a new payload arrives.
   - LiveEquityChart: Recharts area chart bound to a dynamic feed; axes auto-scale.
   - AdminPanel: toggles trading algorithms on/off, mutating shared global state. */

/* ── Base positions (entry prices are fixed; last price streams live) ──────── */
const BASE_POSITIONS = [
  { sym: 'NVDA', side: 'LONG', qty: 120, entry: 118.40, last: 125.42 },
  { sym: 'TSLA', side: 'SHORT', qty: 60, entry: 242.10, last: 247.28 },
  { sym: 'AAPL', side: 'LONG', qty: 200, entry: 227.80, last: 228.39 },
  { sym: 'MSFT', side: 'LONG', qty: 45, entry: 412.05, last: 419.60 },
  { sym: 'AMD', side: 'SHORT', qty: 90, entry: 168.20, last: 165.10 },
];

function computePos(p) {
  const dir = p.side === 'LONG' ? 1 : -1;
  const pnlPct = ((p.last - p.entry) / p.entry) * 100 * dir;
  const pnl = (p.last - p.entry) * p.qty * dir;
  return { ...p, pnlPct, pnl };
}

/* ── useLiveFeed — WS-style polling hook ───────────────────────────────────── */
function useLiveFeed(intervalMs = 1500) {
  const [positions, setPositions] = useState(() => BASE_POSITIONS.map(computePos));
  const [equity, setEquity] = useState(() => {
    let v = 119000; const out = [];
    for (let i = 0; i < 48; i++) { v += Math.sin(i / 5) * 380 + (Math.random() - 0.42) * 520; out.push({ t: i, equity: Math.round(v) }); }
    return out;
  });
  const [tickCount, setTickCount] = useState(0);
  const [flash, setFlash] = useState(false);     // pulses true briefly on each payload
  const [changed, setChanged] = useState({});      // per-symbol up/down for cell flash
  const tRef = useRef(48);

  useEffect(() => {
    let flashTimer;
    const id = setInterval(() => {
      // simulate an inbound socket payload
      setPositions(prev => {
        const ch = {};
        const next = prev.map(p => {
          const drift = (Math.random() - 0.48) * (p.last * 0.0016);
          const last = Math.max(0.01, p.last + drift);
          ch[p.sym] = last >= p.last ? 'up' : 'down';
          return computePos({ ...p, last });
        });
        setChanged(ch);
        return next;
      });
      setEquity(prev => {
        const lastEq = prev[prev.length - 1].equity;
        const nextEq = Math.round(lastEq + (Math.random() - 0.42) * 640);
        const t = tRef.current++;
        return [...prev.slice(1), { t, equity: nextEq }];
      });
      setTickCount(c => c + 1);
      setFlash(true);
      clearTimeout(flashTimer);
      flashTimer = setTimeout(() => setFlash(false), 420);
    }, intervalMs);
    return () => { clearInterval(id); clearTimeout(flashTimer); };
  }, [intervalMs]);

  return { positions, equity, tickCount, flash, changed };
}

/* ── LiveDot — blinking "payload received" indicator ───────────────────────── */
function LiveDot({ flash, label = 'LIVE' }) {
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontFamily: 'var(--font-mono)', fontSize: 9, fontWeight: 700, letterSpacing: '0.8px', color: 'var(--text-faint)' }}>
      <span className={`live-dot ${flash ? 'recv' : ''}`} />
      {label}
    </span>
  );
}

/* ── LiveEquityChart — Chart.js, dynamic feed, auto-scaling axes ───────────── */
function LiveEquityChart({ data }) {
  const canvasRef = useRef(null);
  const chartRef = useRef(null);

  useEffect(() => {
    if (typeof Chart === 'undefined' || !canvasRef.current) return;
    const ctx = canvasRef.current.getContext('2d');
    const grad = ctx.createLinearGradient(0, 0, 0, 240);
    grad.addColorStop(0, 'rgba(0,245,255,0.30)');
    grad.addColorStop(1, 'rgba(0,245,255,0)');
    chartRef.current = new Chart(ctx, {
      type: 'line',
      data: {
        labels: data.map(d => d.t),
        datasets: [{ data: data.map(d => d.equity), borderColor: '#00f5ff', borderWidth: 1.6, fill: true, backgroundColor: grad, pointRadius: 0, tension: 0.35 }],
      },
      options: {
        responsive: true, maintainAspectRatio: false, animation: false,
        plugins: {
          legend: { display: false },
          tooltip: {
            backgroundColor: 'rgba(4,10,18,0.95)', borderColor: 'rgba(0,245,255,0.20)', borderWidth: 1,
            titleColor: '#64748b', bodyColor: '#00f5ff', titleFont: { family: 'JetBrains Mono', size: 10 }, bodyFont: { family: 'JetBrains Mono', size: 11 },
            displayColors: false, callbacks: { title: () => '', label: c => `$${Number(c.parsed.y).toLocaleString()}` },
          },
        },
        scales: {
          x: { display: false },
          y: { position: 'right', grace: '6%', ticks: { color: '#64748b', font: { family: 'JetBrains Mono', size: 9 }, callback: v => `$${(v / 1000).toFixed(0)}k` }, grid: { color: 'rgba(0,245,255,0.07)' }, border: { display: false } },
        },
      },
    });
    return () => { chartRef.current && chartRef.current.destroy(); chartRef.current = null; };
  }, []);

  // Push the live feed into the chart and auto-rescale — no reload.
  useEffect(() => {
    const c = chartRef.current;
    if (!c) return;
    c.data.labels = data.map(d => d.t);
    c.data.datasets[0].data = data.map(d => d.equity);
    c.update('none');
  }, [data]);

  if (typeof Chart === 'undefined') {
    return <div style={{ padding: 20, fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--red)' }}>Chart.js failed to load.</div>;
  }
  return <div style={{ position: 'relative', width: '100%', height: '100%' }}><canvas ref={canvasRef} /></div>;
}

/* ── AdminPanel — algorithm toggles → shared global state ──────────────────── */
const ALGO_DEFS = [
  { id: 'ppo_knn', name: 'PPO · KNN', desc: 'Proximal policy + k-nearest momentum', model: 'PPO·KNN' },
  { id: 'ppo_rf', name: 'PPO · RF', desc: 'Random-forest reinforcement ensemble', model: 'PPO·RF' },
  { id: 'ppo_lr', name: 'PPO · LR', desc: 'Logistic-regression policy head', model: 'PPO·LR' },
  { id: 'chart', name: 'Chart Engine', desc: 'Candlestick + pattern recognition', model: 'CHART' },
  { id: 'quantum', name: 'Quantum Confluence', desc: 'Quantum-inspired multi-factor confluence', model: 'QUANT' },
  { id: 'sentiment', name: 'Sentiment NLP', desc: 'News + social sentiment stream', model: 'NLP' },
  { id: 'pine', name: 'Pine Compiler', desc: 'User-authored Pine Script strategies', model: 'PINE' },
];

function AdminPanel({ open, onClose, algos, setAlgos }) {
  const activeCount = Object.values(algos).filter(Boolean).length;
  const toggle = (id) => setAlgos(a => ({ ...a, [id]: !a[id] }));
  return (
    <div className={`admin-scrim ${open ? 'open' : ''}`} onClick={onClose}>
      <aside className={`admin-drawer ${open ? 'open' : ''}`} onClick={e => e.stopPropagation()}>
        <div className="card-head" style={{ marginBottom: 14 }}>
          <div className="card-title"><span className="index">⚙</span> ALGORITHM CONTROL</div>
          <button className="btn" style={{ padding: '2px 8px' }} onClick={onClose}>✕</button>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14, padding: '8px 12px', borderRadius: 8, background: 'rgba(0,245,255,0.04)', border: '1px solid var(--border)' }}>
          <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-faint)', letterSpacing: '1px' }}>ACTIVE MODELS</span>
          <span style={{ fontFamily: 'var(--font-mono)', fontSize: 18, fontWeight: 800, color: 'var(--cyan)' }}>{activeCount}<span style={{ fontSize: 11, color: 'var(--text-faint)' }}>/{ALGO_DEFS.length}</span></span>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {ALGO_DEFS.map(a => {
            const on = algos[a.id];
            return (
              <div key={a.id} className="algo-row" onClick={() => toggle(a.id)}>
                <div style={{ flex: 1 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <LED tone={on ? 'green' : 'cyan'} off={!on} />
                    <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, fontWeight: 700, color: on ? 'var(--text)' : 'var(--text-faint)' }}>{a.name}</span>
                  </div>
                  <div style={{ fontFamily: 'var(--font-sans)', fontSize: 10, color: 'var(--text-faint)', marginTop: 3, marginLeft: 14 }}>{a.desc}</div>
                </div>
                <span className={`switch ${on ? 'on' : ''}`}><span className="knob" /></span>
              </div>
            );
          })}
        </div>
        <div style={{ marginTop: 16, fontFamily: 'var(--font-mono)', fontSize: 9, color: 'var(--text-faint)', lineHeight: 1.7, letterSpacing: '0.3px' }}>
          ◆ Toggling a model updates the live consensus instantly. Disabled models stop voting and are excluded from confidence.
        </div>
      </aside>
    </div>
  );
}

Object.assign(window, { useLiveFeed, LiveDot, LiveEquityChart, AdminPanel, ALGO_DEFS, computePos });
