// @ts-nocheck
import * as React from 'react';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { sellableCargo } from '../game-slice/sliceEconomy';
import { withGameSliceSession } from '../game-slice/gameSliceState';
import { useGameSliceSession } from '../game-slice/useGameSliceSession';
import { api } from '../../data/fakeBackend';
import * as TH from '../../lib/threeHelpers';
import * as THREE from 'three';
/* ──────────────────────────────────────────────
   Commodities Exchange — Contract Market
   ────────────────────────────────────────────── */

/* ── Static contract catalogue ── */
const CATEGORIES = [
  { id: 'all',      label: 'All Contracts' },
  { id: 'ore',      label: 'Raw Ores' },
  { id: 'mineral',  label: 'Refined Minerals' },
  { id: 'gas',      label: 'Gas Products' },
  { id: 'isotope',  label: 'Isotopes' },
  { id: 'exotic',   label: 'Exotic Matter' },
];

const CONTRACTS = [
  /* Ores */
  { symbol:'VLD', name:'Veldspar',    category:'ore',     lotSize:1000, tickSize:0.01, marginPct:8,  basePrice:14,  hub:'Jita IV – Moon 4' },
  { symbol:'SCR', name:'Scordite',    category:'ore',     lotSize:500,  tickSize:0.02, marginPct:10, basePrice:32,  hub:'Jita IV – Moon 4' },
  { symbol:'PYX', name:'Pyroxeres',   category:'ore',     lotSize:500,  tickSize:0.05, marginPct:10, basePrice:45,  hub:'Amarr VIII – Emperor' },
  { symbol:'KRN', name:'Kernite',     category:'ore',     lotSize:250,  tickSize:0.10, marginPct:12, basePrice:90,  hub:'Amarr VIII – Emperor' },
  { symbol:'OMB', name:'Omber',       category:'ore',     lotSize:250,  tickSize:0.10, marginPct:12, basePrice:135, hub:'Rens VI – Moon 8' },
  { symbol:'JSP', name:'Jaspet',      category:'ore',     lotSize:200,  tickSize:0.10, marginPct:15, basePrice:190, hub:'Dodixie IX – Moon 20' },
  { symbol:'HEM', name:'Hemorphite',  category:'ore',     lotSize:100,  tickSize:0.50, marginPct:18, basePrice:360, hub:'Jita IV – Moon 4' },
  { symbol:'ARK', name:'Arkonor',     category:'ore',     lotSize:50,   tickSize:1.00, marginPct:20, basePrice:620, hub:'Jita IV – Moon 4' },
  /* Minerals */
  { symbol:'TRI', name:'Tritanium',   category:'mineral', lotSize:5000, tickSize:0.01, marginPct:6,  basePrice:5,   hub:'Jita IV – Moon 4' },
  { symbol:'PYE', name:'Pyerite',     category:'mineral', lotSize:2000, tickSize:0.01, marginPct:8,  basePrice:12,  hub:'Jita IV – Moon 4' },
  { symbol:'MLX', name:'Mexallon',    category:'mineral', lotSize:1000, tickSize:0.02, marginPct:8,  basePrice:35,  hub:'Jita IV – Moon 4' },
  { symbol:'ISO', name:'Isogen',      category:'mineral', lotSize:500,  tickSize:0.05, marginPct:12, basePrice:110, hub:'Amarr VIII – Emperor' },
  { symbol:'NCX', name:'Nocxium',     category:'mineral', lotSize:250,  tickSize:0.10, marginPct:15, basePrice:380, hub:'Jita IV – Moon 4' },
  { symbol:'ZDR', name:'Zydrine',     category:'mineral', lotSize:100,  tickSize:0.50, marginPct:18, basePrice:950, hub:'Jita IV – Moon 4' },
  { symbol:'MEG', name:'Megacyte',    category:'mineral', lotSize:50,   tickSize:1.00, marginPct:20, basePrice:2800,hub:'Jita IV – Moon 4' },
  { symbol:'MOR', name:'Morphite',    category:'mineral', lotSize:10,   tickSize:5.00, marginPct:25, basePrice:8500,hub:'Jita IV – Moon 4' },
  /* Gas */
  { symbol:'ATM', name:'Atmospheric', category:'gas',     lotSize:2000, tickSize:0.01, marginPct:10, basePrice:8,   hub:'Jita IV – Moon 4' },
  { symbol:'NEB', name:'Nebular',     category:'gas',     lotSize:500,  tickSize:0.05, marginPct:12, basePrice:45,  hub:'Amarr VIII – Emperor' },
  { symbol:'ION', name:'Ionized',     category:'gas',     lotSize:200,  tickSize:0.10, marginPct:15, basePrice:120, hub:'Jita IV – Moon 4' },
  { symbol:'FUL', name:'Fullerides',  category:'gas',     lotSize:100,  tickSize:0.50, marginPct:18, basePrice:450, hub:'Jita IV – Moon 4' },
  /* Isotopes */
  { symbol:'H3',  name:'Hydrogen-3',  category:'isotope', lotSize:500,  tickSize:0.05, marginPct:15, basePrice:85,  hub:'Jita IV – Moon 4' },
  { symbol:'HE4', name:'Helium-4',    category:'isotope', lotSize:500,  tickSize:0.05, marginPct:15, basePrice:92,  hub:'Amarr VIII – Emperor' },
  { symbol:'N15', name:'Nitrogen-15', category:'isotope', lotSize:500,  tickSize:0.05, marginPct:15, basePrice:78,  hub:'Rens VI – Moon 8' },
  { symbol:'O18', name:'Oxygen-18',   category:'isotope', lotSize:500,  tickSize:0.05, marginPct:15, basePrice:88,  hub:'Dodixie IX – Moon 20' },
  /* Exotic */
  { symbol:'RDB', name:'Reedstone',   category:'exotic',  lotSize:10,   tickSize:5.00, marginPct:25, basePrice:12000,hub:'Jita IV – Moon 4' },
  { symbol:'TCH', name:'Tachyon Salt', category:'exotic', lotSize:5,    tickSize:10.0, marginPct:30, basePrice:45000,hub:'Jita IV – Moon 4' },
];

/* ── Sparkline ── */
function Sparkline({ data, width = 80, height = 24, color = 'var(--green)' }) {
  const ref = useRef(null);
  useEffect(() => {
    const c = ref.current; if (!c || !data || data.length < 2) return;
    const ctx = c.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    c.width = width * dpr; c.height = height * dpr;
    ctx.scale(dpr, dpr);
    ctx.clearRect(0, 0, width, height);
    const min = Math.min(...data); const max = Math.max(...data);
    const range = max - min || 1;
    const step = width / (data.length - 1);
    ctx.beginPath();
    data.forEach((v, i) => {
      const x = i * step;
      const y = height - ((v - min) / range) * (height - 4) - 2;
      i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
    });
    ctx.strokeStyle = color;
    ctx.lineWidth = 1.5;
    ctx.lineJoin = 'round';
    ctx.stroke();
    const grad = ctx.createLinearGradient(0, 0, 0, height);
    const isGreen = color.includes('green');
    grad.addColorStop(0, isGreen ? 'rgba(34,197,94,0.15)' : 'rgba(239,68,68,0.15)');
    grad.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.lineTo(width, height); ctx.lineTo(0, height); ctx.closePath();
    ctx.fillStyle = grad; ctx.fill();
  }, [data, width, height, color]);
  return <canvas ref={ref} style={{ width, height, display: 'block' }} />;
}

/* ── Ticker Tape ── */
function TickerTape({ items }) {
  const [offset, setOffset] = useState(0);
  const raf = useRef(null);
  useEffect(() => {
    const speed = 0.5;
    const tick = () => {
      setOffset(o => { const n = o - speed; return n < -3000 ? 0 : n; });
      raf.current = requestAnimationFrame(tick);
    };
    raf.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf.current);
  }, []);
  const dup = [...items, ...items, ...items];
  return (
    <div style={{
      overflow: 'hidden', whiteSpace: 'nowrap',
      background: 'rgba(10,16,28,0.95)', borderBottom: '1px solid var(--border)',
      padding: '5px 0', fontFamily: 'var(--font-mono)', fontSize: '0.65rem',
    }}>
      <div style={{ display: 'inline-flex', transform: `translateX(${offset}px)`, willChange: 'transform' }}>
        {dup.map((t, i) => (
          <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: '5px', padding: '0 14px', borderRight: '1px solid var(--border)' }}>
            <span style={{ color: 'var(--fg-bright)', fontWeight: 600 }}>{t.symbol}</span>
            <span style={{ color: 'var(--fg-dim)' }}>₢{t.price.toLocaleString()}</span>
            <span style={{ color: t.change >= 0 ? 'var(--green)' : 'var(--red)', fontWeight: 600 }}>
              {t.change >= 0 ? '▲' : '▼'} {Math.abs(t.changePct).toFixed(1)}%
            </span>
          </span>
        ))}
      </div>
    </div>
  );
}

/* ── Category Tabs ── */
function CategoryTabs({ active, onChange }) {
  return (
    <div style={{
      display: 'flex', gap: '2px', padding: 'var(--sp-2) 0',
      borderBottom: '1px solid var(--border)', marginBottom: 'var(--sp-4)',
      overflowX: 'auto',
    }}>
      {CATEGORIES.map(cat => (
        <button key={cat.id} onClick={() => onChange(cat.id)} style={{
          padding: '6px 14px', borderRadius: 'var(--radius-md)',
          background: active === cat.id ? 'var(--accent-bg)' : 'transparent',
          color: active === cat.id ? 'var(--accent)' : 'var(--muted)',
          border: active === cat.id ? '1px solid var(--accent-border)' : '1px solid transparent',
          fontSize: '0.72rem', fontFamily: 'var(--font-mono)', cursor: 'pointer',
          transition: 'all var(--transition-fast)', whiteSpace: 'nowrap',
          fontWeight: active === cat.id ? 600 : 400,
          letterSpacing: '0.03em',
        }}>
          {cat.label}
        </button>
      ))}
    </div>
  );
}

/* ── Contract Board — main table ── */
function ContractBoard({ commodities, selected, onSelect, category }) {
  const filtered = category === 'all' ? commodities : commodities.filter(c => c.category === category);
  return (
    <div style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)', overflow: 'hidden',
    }}>
      {/* Table header */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: '90px 120px 80px 60px 70px 70px 80px 90px 70px',
        gap: '4px', alignItems: 'center',
        padding: '8px 12px', borderBottom: '1px solid var(--border)',
        background: 'var(--surface-raised)',
        fontFamily: 'var(--font-mono)', fontSize: '0.6rem', color: 'var(--muted)',
        textTransform: 'uppercase', letterSpacing: '0.05em',
      }}>
        <span>Ticker</span><span>Name</span><span>Last</span><span>Chg%</span>
        <span>Bid</span><span>Ask</span><span>Volume</span><span>Open Int.</span><span />
      </div>
      {/* Rows */}
      <div style={{ maxHeight: '380px', overflowY: 'auto', overscrollBehavior: 'contain' }}>
        {filtered.map(c => {
          const up = c.change >= 0;
          const isSel = selected === c.symbol;
          const spread = c.bestAsk - c.bestBid;
          return (
            <div key={c.symbol} onClick={() => onSelect(c.symbol)} style={{
              display: 'grid',
              gridTemplateColumns: '90px 120px 80px 60px 70px 70px 80px 90px 70px',
              gap: '4px', alignItems: 'center',
              padding: '7px 12px', cursor: 'pointer',
              background: isSel ? 'var(--surface-hover)' : 'transparent',
              borderLeft: isSel ? '2px solid var(--accent)' : '2px solid transparent',
              borderBottom: '1px solid var(--border)',
              transition: 'background var(--transition-fast)',
              fontSize: '0.75rem',
            }}>
              <span style={{ fontFamily: 'var(--font-mono)', fontWeight: 700, color: 'var(--accent)' }}>{c.symbol}</span>
              <span style={{ color: 'var(--fg-dim)', fontSize: '0.7rem', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.name}</span>
              <span style={{ fontFamily: 'var(--font-mono)', fontWeight: 700, color: 'var(--fg-bright)' }}>₢{c.price.toLocaleString()}</span>
              <span style={{
                fontFamily: 'var(--font-mono)', fontSize: '0.65rem', fontWeight: 600,
                color: up ? 'var(--green)' : 'var(--red)',
                background: up ? 'var(--green-bg)' : 'var(--red-bg)',
                padding: '1px 5px', borderRadius: 'var(--radius-pill)', display: 'inline-block',
              }}>
                {up ? '+' : ''}{c.changePct.toFixed(1)}%
              </span>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--green)' }}>₢{c.bestBid}</span>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--red)' }}>₢{c.bestAsk}</span>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--fg-dim)' }}>{(c.volume / 1000).toFixed(1)}K</span>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.7rem', color: 'var(--cyan)' }}>{(c.openInterest / 1000).toFixed(1)}K</span>
              <span><Sparkline data={c.history} width={60} height={18} color={up ? 'var(--green)' : 'var(--red)'} /></span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ── Contract Spec Panel ── */
function ContractSpec({ contract, commodity }) {
  if (!contract || !commodity) return null;
  const marginPerLot = Math.ceil(commodity.price * contract.lotSize * (contract.marginPct / 100));
  const notionalPerLot = commodity.price * contract.lotSize;
  return (
    <div style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)', overflow: 'hidden',
    }}>
      <div style={{
        padding: '10px 14px', borderBottom: '1px solid var(--border)',
        background: 'var(--surface-raised)',
        fontFamily: 'var(--font-mono)', fontSize: '0.65rem', color: 'var(--muted)',
        textTransform: 'uppercase', letterSpacing: '0.06em',
      }}>
        Contract Specification
      </div>
      <div style={{ padding: 'var(--sp-3) var(--sp-4)', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '6px 16px' }}>
        {[
          ['Ticker', contract.symbol, 'var(--accent)'],
          ['Unit', contract.name, 'var(--fg-bright)'],
          ['Lot Size', contract.lotSize.toLocaleString() + ' units', 'var(--fg-bright)'],
          ['Tick Size', '₢' + contract.tickSize, 'var(--fg-bright)'],
          ['Margin Req.', contract.marginPct + '%', 'var(--cyan)'],
          ['Margin / Lot', '₢' + marginPerLot.toLocaleString(), 'var(--cyan)'],
          ['Notional / Lot', '₢' +notionalPerLot.toLocaleString(), 'var(--fg-dim)'],
          ['Delivery', contract.hub, 'var(--fg-dim)'],
          ['Settlement', commodity.settlement ? '₢' + commodity.settlement : '—', 'var(--fg-dim)'],
          ['Expiry', '30 DTE', 'var(--muted)'],
          ['Supply', (commodity.supply / 1000).toFixed(0) + 'K/day', 'var(--green)'],
          ['Demand', (commodity.demand / 1000).toFixed(0) + 'K/day', commodity.demand > commodity.supply ? 'var(--red)' : 'var(--green)'],
        ].map(([label, value, color], i) => (
          <React.Fragment key={i}>
            <span style={{ fontSize: '0.65rem', color: 'var(--muted)', fontFamily: 'var(--font-mono)' }}>{label}</span>
            <span style={{ fontSize: '0.7rem', color, fontFamily: 'var(--font-mono)', fontWeight: 500, textAlign: 'right' }}>{value}</span>
          </React.Fragment>
        ))}
      </div>
      {/* Supply/Demand bar */}
      <div style={{ padding: '0 var(--sp-4) var(--sp-3)' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.6rem', color: 'var(--muted)', marginBottom: '3px', fontFamily: 'var(--font-mono)' }}>
          <span>SUPPLY</span>
          <span style={{ color: commodity.demand > commodity.supply ? 'var(--red)' : 'var(--green)' }}>
            {commodity.demand > commodity.supply ? 'DEFICIT' : 'SURPLUS'}: {Math.abs(commodity.supply - commodity.demand).toLocaleString()}
          </span>
          <span>DEMAND</span>
        </div>
        <div style={{ display: 'flex', height: '6px', borderRadius: '3px', overflow: 'hidden', background: 'var(--surface-raised)' }}>
          <div style={{ width: `${(commodity.supply / Math.max(commodity.supply, commodity.demand)) * 100}%`, background: 'var(--green-dim)', borderRadius: '3px 0 0 3px' }} />
          <div style={{ width: `${(commodity.demand / Math.max(commodity.supply, commodity.demand)) * 100}%`, background: 'var(--red-dim)', borderRadius: '0 3px 3px 0', opacity: 0.7 }} />
        </div>
      </div>
    </div>
  );
}

/* ── Depth Chart (canvas) ── */
function DepthChart({ bids, asks, midPrice }) {
  const ref = useRef(null);
  useEffect(() => {
    const c = ref.current; if (!c) return;
    const ctx = c.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    const W = c.clientWidth; const H = c.clientHeight;
    c.width = W * dpr; c.height = H * dpr;
    ctx.scale(dpr, dpr);
    ctx.clearRect(0, 0, W, H);

    if (!bids.length || !asks.length) return;

    const maxCum = Math.max(
      bids.reduce((s, b) => Math.max(s, b.cumulative), 0),
      asks.reduce((s, a) => Math.max(s, a.cumulative), 0)
    );

    const priceRange = midPrice * 0.06;
    const pMin = midPrice - priceRange;
    const pMax = midPrice + priceRange;
    const toX = p => ((p - pMin) / (pMax - pMin)) * W;
    const toY = cum => H - (cum / (maxCum * 1.1)) * H;

    /* Grid */
    ctx.strokeStyle = 'rgba(28,42,63,0.4)'; ctx.lineWidth = 0.5;
    for (let i = 0; i < 4; i++) {
      const y = (H / 3) * i;
      ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(W, y); ctx.stroke();
    }

    /* Bids (green area, left of mid) */
    ctx.beginPath();
    ctx.moveTo(toX(bids[0].price), H);
    bids.forEach(b => ctx.lineTo(toX(b.price), toY(b.cumulative)));
    ctx.lineTo(toX(bids[bids.length - 1].price), H);
    ctx.closePath();
    const bg = ctx.createLinearGradient(0, 0, 0, H);
    bg.addColorStop(0, 'rgba(34,197,94,0.25)'); bg.addColorStop(1, 'rgba(34,197,94,0.03)');
    ctx.fillStyle = bg; ctx.fill();

    /* Asks (red area, right of mid) */
    ctx.beginPath();
    ctx.moveTo(toX(asks[0].price), H);
    asks.forEach(a => ctx.lineTo(toX(a.price), toY(a.cumulative)));
    ctx.lineTo(toX(asks[asks.length - 1].price), H);
    ctx.closePath();
    const ag = ctx.createLinearGradient(0, 0, 0, H);
    ag.addColorStop(0, 'rgba(239,68,68,0.25)'); ag.addColorStop(1, 'rgba(239,68,68,0.03)');
    ctx.fillStyle = ag; ctx.fill();

    /* Mid line */
    const mx = toX(midPrice);
    ctx.setLineDash([3, 3]);
    ctx.beginPath(); ctx.moveTo(mx, 0); ctx.lineTo(mx, H);
    ctx.strokeStyle = 'var(--accent)'; ctx.lineWidth = 1; ctx.stroke();
    ctx.setLineDash([]);

    /* Price label */
    ctx.fillStyle = 'var(--accent)'; ctx.font = 'bold 9px var(--font-mono)';
    ctx.textAlign = 'center';
    ctx.fillText('₢' + midPrice.toFixed(0), mx, H - 4);
  }, [bids, asks, midPrice]);

  return <canvas ref={ref} style={{ width: '100%', height: '100px', display: 'block' }} />;
}

/* ── Order Book ── */
function OrderBook({ bids, asks, spread, spreadPct }) {
  const maxBid = Math.max(...bids.map(b => b.volume));
  const maxAsk = Math.max(...asks.map(a => a.volume));
  return (
    <div style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)', overflow: 'hidden',
    }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        padding: '8px 12px', borderBottom: '1px solid var(--border)',
        background: 'var(--surface-raised)',
      }}>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.65rem', color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>
          Market Depth
        </span>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.65rem', color: 'var(--accent)' }}>
          Spread: ₢{spread} ({spreadPct.toFixed(2)}%)
        </span>
      </div>
      <div style={{
        display: 'grid', gridTemplateColumns: '1fr 1fr 1fr',
        fontFamily: 'var(--font-mono)', fontSize: '0.58rem', color: 'var(--muted)',
        textTransform: 'uppercase', letterSpacing: '0.05em',
        padding: '5px 12px', borderBottom: '1px solid var(--border)',
      }}>
        <span>Price</span><span style={{ textAlign: 'center' }}>Size</span><span style={{ textAlign: 'right' }}>Cum</span>
      </div>
      {/* Asks (reversed) */}
      <div style={{ maxHeight: '160px', overflowY: 'auto', overscrollBehavior: 'contain' }}>
        {[...asks].reverse().map((a, i) => (
          <div key={`a${i}`} style={{ position: 'relative', display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', padding: '2px 12px', fontFamily: 'var(--font-mono)', fontSize: '0.68rem' }}>
            <div style={{ position: 'absolute', inset: 0, background: 'rgba(239,68,68,0.07)', width: `${(a.volume / maxAsk) * 100}%`, right: 0, left: 'auto' }} />
            <span style={{ color: 'var(--red)', position: 'relative' }}>₢{a.price}</span>
            <span style={{ color: 'var(--fg-dim)', textAlign: 'center', position: 'relative' }}>{a.volume.toLocaleString()}</span>
            <span style={{ color: 'var(--muted)', textAlign: 'right', position: 'relative' }}>{a.cumulative.toLocaleString()}</span>
          </div>
        ))}
      </div>
      {/* Mid */}
      <div style={{
        padding: '5px 12px', background: 'var(--surface-raised)',
        borderTop: '1px solid var(--border)', borderBottom: '1px solid var(--border)',
        display: 'flex', justifyContent: 'center', alignItems: 'center', gap: 'var(--sp-2)',
      }}>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.85rem', fontWeight: 700, color: 'var(--fg-bright)' }}>
          ₢{((bids[0]?.price || 0 + asks[0]?.price || 0) / 2).toLocaleString()}
        </span>
        <span style={{ fontSize: '0.58rem', color: 'var(--muted)' }}>MID</span>
      </div>
      {/* Bids */}
      <div style={{ maxHeight: '160px', overflowY: 'auto', overscrollBehavior: 'contain' }}>
        {bids.map((b, i) => (
          <div key={`b${i}`} style={{ position: 'relative', display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', padding: '2px 12px', fontFamily: 'var(--font-mono)', fontSize: '0.68rem' }}>
            <div style={{ position: 'absolute', inset: 0, background: 'rgba(34,197,94,0.07)', width: `${(b.volume / maxBid) * 100}%` }} />
            <span style={{ color: 'var(--green)', position: 'relative' }}>₢{b.price}</span>
            <span style={{ color: 'var(--fg-dim)', textAlign: 'center', position: 'relative' }}>{b.volume.toLocaleString()}</span>
            <span style={{ color: 'var(--muted)', textAlign: 'right', position: 'relative' }}>{b.cumulative.toLocaleString()}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ── Price Chart (canvas) ── */
function PriceChart({ data, symbol }) {
  const ref = useRef(null);
  useEffect(() => {
    const c = ref.current; if (!c || !data || data.length < 2) return;
    const ctx = c.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    const W = c.clientWidth; const H = c.clientHeight;
    c.width = W * dpr; c.height = H * dpr;
    ctx.scale(dpr, dpr);
    ctx.clearRect(0, 0, W, H);

    const prices = data.map(d => d.close);
    const highs = data.map(d => d.high);
    const lows = data.map(d => d.low);
    const volumes = data.map(d => d.volume);
    const allP = [...highs, ...lows];
    const minP = Math.min(...allP); const maxP = Math.max(...allP);
    const rangeP = maxP - minP || 1;
    const maxV = Math.max(...volumes);
    const chartH = H * 0.72; const volH = H * 0.22; const barW = Math.max(2, (W / data.length) - 1);

    /* Grid */
    ctx.strokeStyle = 'rgba(28,42,63,0.5)'; ctx.lineWidth = 0.5;
    for (let i = 0; i < 5; i++) {
      const y = (chartH / 4) * i;
      ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(W, y); ctx.stroke();
      ctx.fillStyle = 'var(--muted)'; ctx.font = '8px var(--font-mono)';
      ctx.fillText('₢' + (maxP - (rangeP / 4) * i).toFixed(0), W - 42, y + 9);
    }

    /* Volume bars */
    data.forEach((d, i) => {
      const x = (i / data.length) * W;
      const vh = (d.volume / maxV) * volH;
      ctx.fillStyle = d.close >= d.open ? 'rgba(34,197,94,0.18)' : 'rgba(239,68,68,0.18)';
      ctx.fillRect(x, H - vh, barW, vh);
    });

    /* Price line */
    ctx.beginPath();
    data.forEach((d, i) => {
      const x = (i / (data.length - 1)) * W;
      const y = chartH - ((d.close - minP) / rangeP) * (chartH - 10) - 5;
      i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
    });
    const lastC = data[data.length - 1].close;
    const firstC = data[0].close;
    const lineColor = lastC >= firstC ? '#22c55e' : '#ef4444';
    ctx.strokeStyle = lineColor; ctx.lineWidth = 1.8; ctx.lineJoin = 'round'; ctx.stroke();

    /* Area fill */
    const lastX = W;
    ctx.lineTo(lastX, chartH); ctx.lineTo(0, chartH); ctx.closePath();
    const grad = ctx.createLinearGradient(0, 0, 0, chartH);
    grad.addColorStop(0, lastC >= firstC ? 'rgba(34,197,94,0.10)' : 'rgba(239,68,68,0.10)');
    grad.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.fillStyle = grad; ctx.fill();

    /* Current price line */
    const curY = chartH - ((lastC - minP) / rangeP) * (chartH - 10) - 5;
    ctx.setLineDash([4, 4]);
    ctx.beginPath(); ctx.moveTo(0, curY); ctx.lineTo(W, curY);
    ctx.strokeStyle = lineColor; ctx.lineWidth = 1; ctx.stroke();
    ctx.setLineDash([]);

    ctx.fillStyle = lineColor;
    ctx.beginPath(); ctx.roundRect(W - 55, curY - 8, 52, 16, 3); ctx.fill();
    ctx.fillStyle = '#080c14'; ctx.font = 'bold 8px var(--font-mono)';
    ctx.fillText('₢' + lastC.toFixed(0), W - 52, curY + 3);
  }, [data, symbol]);

  return <canvas ref={ref} style={{ width: '100%', height: '240px', display: 'block' }} />;
}

/* ── Order Form (commodities-style: lots, margin, long/short) ── */
function OrderForm({ contract, commodity, credits, positions, onTrade }) {
  const [direction, setDirection] = useState('long'); // long or short
  const [orderType, setOrderType] = useState('market'); // market, limit, stop
  const [lots, setLots] = useState('');
  const [limitPrice, setLimitPrice] = useState('');
  const [error, setError] = useState('');
  const [confirmation, setConfirmation] = useState(null);

  if (!contract || !commodity) return null;

  const effectivePrice = orderType === 'market' ? commodity.price : (parseFloat(limitPrice) || commodity.price);
  const numLots = parseInt(lots) || 0;
  const totalUnits = numLots * contract.lotSize;
  const notional = totalUnits * effectivePrice;
  const marginRequired = Math.ceil(notional * (contract.marginPct / 100));
  const commission = Math.ceil(notional * 0.015);
  const pos = positions.find(p => p.symbol === contract.symbol);
  const existingDirection = pos ? pos.direction : null;
  const canAfford = marginRequired + commission <= credits;

  const handleSubmit = () => {
    if (numLots <= 0) { setError('Enter lot quantity'); return; }
    if (orderType !== 'market' && !limitPrice) { setError('Set limit/stop price'); return; }
    if (!canAfford) { setError('Insufficient margin + commission'); return; }
    setError('');
    setConfirmation({ direction, orderType, lots: numLots, price: effectivePrice, notional, marginRequired, commission, totalUnits });
  };

  const confirmTrade = () => {
    onTrade(direction, contract.symbol, effectivePrice, numLots, totalUnits, marginRequired, commission);
    setConfirmation(null); setLots(''); setLimitPrice(''); setError('');
  };

  return (
    <div style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)', overflow: 'hidden',
    }}>
      <div style={{
        padding: '8px 12px', borderBottom: '1px solid var(--border)',
        background: 'var(--surface-raised)',
        fontFamily: 'var(--font-mono)', fontSize: '0.65rem', color: 'var(--muted)',
        textTransform: 'uppercase', letterSpacing: '0.06em',
        display: 'flex', justifyContent: 'space-between',
      }}>
        <span>Place Order — {contract.symbol}</span>
        <span>Lot: {contract.lotSize.toLocaleString()} units</span>
      </div>
      <div style={{ padding: 'var(--sp-3) var(--sp-4)' }}>
        {/* Long / Short toggle */}
        <div style={{
          display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '3px',
          marginBottom: 'var(--sp-3)', background: 'var(--surface-raised)',
          borderRadius: 'var(--radius-md)', padding: '3px',
        }}>
          {['long', 'short'].map(d => (
            <button key={d} onClick={() => setDirection(d)} style={{
              padding: '7px', borderRadius: 'var(--radius-md)',
              background: direction === d ? (d === 'long' ? 'var(--green-bg)' : 'var(--red-bg)') : 'transparent',
              color: direction === d ? (d === 'long' ? 'var(--green)' : 'var(--red)') : 'var(--muted)',
              fontWeight: 600, fontSize: '0.75rem', cursor: 'pointer', fontFamily: 'var(--font-mono)',
              transition: 'all var(--transition-fast)',
              border: direction === d ? `1px solid ${d === 'long' ? 'rgba(34,197,94,0.3)' : 'rgba(239,68,68,0.3)'}` : '1px solid transparent',
            }}>
              {d === 'long' ? '▲ LONG' : '▼ SHORT'}
            </button>
          ))}
        </div>

        {/* Order type pills */}
        <div style={{ display: 'flex', gap: 'var(--sp-2)', marginBottom: 'var(--sp-3)' }}>
          {['market', 'limit', 'stop'].map(t => (
            <button key={t} onClick={() => setOrderType(t)} style={{
              padding: '3px 10px', border: `1px solid ${orderType === t ? 'var(--accent-border)' : 'var(--border)'}`,
              borderRadius: 'var(--radius-pill)', background: orderType === t ? 'var(--accent-bg)' : 'transparent',
              color: orderType === t ? 'var(--accent)' : 'var(--muted)',
              fontSize: '0.65rem', fontFamily: 'var(--font-mono)', cursor: 'pointer', transition: 'all var(--transition-fast)',
            }}>
              {t.toUpperCase()}
            </button>
          ))}
        </div>

        {/* Limit/Stop price */}
        {orderType !== 'market' && (
          <div style={{ marginBottom: 'var(--sp-3)' }}>
            <label style={{ fontSize: '0.6rem', color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em', display: 'block', marginBottom: '3px' }}>
              {orderType === 'limit' ? 'Limit Price' : 'Stop Price'}
            </label>
            <input type="number" value={limitPrice} onChange={e => setLimitPrice(e.target.value)}
              placeholder={`Spot: ₢${commodity.price}`}
              style={{
                width: '100%', padding: '7px 10px', background: 'var(--bg)',
                border: '1px solid var(--border)', borderRadius: 'var(--radius-md)',
                color: 'var(--fg)', fontFamily: 'var(--font-mono)', fontSize: '0.8rem',
                outline: 'none', boxSizing: 'border-box',
              }}
            />
          </div>
        )}

        {/* Lots */}
        <div style={{ marginBottom: 'var(--sp-3)' }}>
          <label style={{ fontSize: '0.6rem', color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em', display: 'block', marginBottom: '3px' }}>
            Lots (× {contract.lotSize.toLocaleString()} units)
          </label>
          <div style={{ display: 'flex', gap: '3px' }}>
            <input type="number" value={lots} onChange={e => setLots(e.target.value)}
              placeholder="0" min="1"
              style={{
                flex: 1, padding: '7px 10px', background: 'var(--bg)',
                border: '1px solid var(--border)', borderRadius: 'var(--radius-md)',
                color: 'var(--fg)', fontFamily: 'var(--font-mono)', fontSize: '0.8rem', outline: 'none',
              }}
            />
            {[1, 5, 10, 25].map(n => (
              <button key={n} onClick={() => setLots(String(n))} style={{
                padding: '7px 5px', border: '1px solid var(--border)',
                borderRadius: 'var(--radius-md)', background: 'var(--surface-raised)',
                color: 'var(--fg-dim)', fontSize: '0.6rem', fontFamily: 'var(--font-mono)',
                cursor: 'pointer', transition: 'all var(--transition-fast)',
              }}>{n}</button>
            ))}
          </div>
        </div>

        {/* Summary */}
        <div style={{
          fontFamily: 'var(--font-mono)', fontSize: '0.68rem', color: 'var(--fg-dim)',
          background: 'var(--bg)', borderRadius: 'var(--radius-md)', padding: 'var(--sp-3)',
          marginBottom: 'var(--sp-3)',
        }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '3px' }}>
            <span>Price / Unit</span><span style={{ color: 'var(--fg-bright)' }}>₢{effectivePrice.toLocaleString()}</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '3px' }}>
            <span>Total Units</span><span style={{ color: 'var(--fg-bright)' }}>{totalUnits.toLocaleString()}</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '3px' }}>
            <span>Notional Value</span><span style={{ color: 'var(--fg-bright)' }}>₢{notional.toLocaleString()}</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '3px' }}>
            <span>Margin ({contract.marginPct}%)</span><span style={{ color: 'var(--cyan)' }}>₢{marginRequired.toLocaleString()}</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '3px' }}>
            <span>Commission</span><span style={{ color: 'var(--accent)' }}>₢{commission.toLocaleString()}</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', paddingTop: '5px', borderTop: '1px solid var(--border)', fontWeight: 700 }}>
            <span>Required</span>
            <span style={{ color: direction === 'long' ? 'var(--green)' : 'var(--red)' }}>
              ₢{(marginRequired + commission).toLocaleString()}
            </span>
          </div>
        </div>

        {error && <div style={{ fontSize: '0.7rem', color: 'var(--red)', marginBottom: 'var(--sp-2)', padding: '5px 10px', background: 'var(--red-bg)', borderRadius: 'var(--radius-md)' }}>{error}</div>}

        <button onClick={handleSubmit} disabled={!lots || !canAfford} style={{
          width: '100%', padding: '9px', border: 'none', borderRadius: 'var(--radius-md)',
          background: direction === 'long' ? 'var(--green-dim)' : 'var(--red-dim)',
          color: 'var(--fg-bright)', fontWeight: 700, fontSize: '0.8rem',
          cursor: canAfford && lots ? 'pointer' : 'not-allowed',
          opacity: canAfford && lots ? 1 : 0.4,
          fontFamily: 'var(--font-mono)', transition: 'all var(--transition-fast)',
        }}>
          {direction === 'long' ? '▲ BUY' : '▼ SELL'} {numLots}× {contract.symbol}
        </button>
      </div>

      {/* Confirmation */}
      {confirmation && (
        <div style={{
          position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.7)',
          display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 2000,
        }} onClick={() => setConfirmation(null)}>
          <div style={{
            background: 'var(--surface)', border: '1px solid var(--border)',
            borderRadius: 'var(--radius-lg)', padding: 'var(--sp-5)', minWidth: 320,
          }} onClick={e => e.stopPropagation()}>
            <h3 style={{ marginBottom: 'var(--sp-4)', fontSize: '0.9rem' }}>Confirm {confirmation.orderType} Order</h3>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.78rem', lineHeight: 2 }}>
              <div><span style={{ color: 'var(--muted)' }}>Direction:</span> <span style={{ color: confirmation.direction === 'long' ? 'var(--green)' : 'var(--red)', fontWeight: 700 }}>{confirmation.direction.toUpperCase()}</span></div>
              <div><span style={{ color: 'var(--muted)' }}>Contract:</span> <span style={{ color: 'var(--fg-bright)' }}>{contract.symbol} ({contract.name})</span></div>
              <div><span style={{ color: 'var(--muted)' }}>Lots:</span> <span style={{ color: 'var(--fg-bright)' }}>{confirmation.lots} ({confirmation.totalUnits.toLocaleString()} units)</span></div>
              <div><span style={{ color: 'var(--muted)' }}>Price:</span> <span style={{ color: 'var(--fg-bright)' }}>₢{confirmation.price.toLocaleString()}/unit</span></div>
              <div><span style={{ color: 'var(--muted)' }}>Notional:</span> <span style={{ color: 'var(--fg-bright)' }}>₢{confirmation.notional.toLocaleString()}</span></div>
              <div><span style={{ color: 'var(--muted)' }}>Margin:</span> <span style={{ color: 'var(--cyan)' }}>₢{confirmation.marginRequired.toLocaleString()}</span></div>
              <div><span style={{ color: 'var(--muted)' }}>Commission:</span> <span style={{ color: 'var(--accent)' }}>₢{confirmation.commission.toLocaleString()}</span></div>
            </div>
            <div style={{ display: 'flex', gap: 'var(--sp-3)', marginTop: 'var(--sp-5)' }}>
              <button onClick={confirmTrade} style={{
                flex: 1, padding: '9px', border: 'none', borderRadius: 'var(--radius-md)',
                background: confirmation.direction === 'long' ? 'var(--green-dim)' : 'var(--red-dim)',
                color: 'var(--fg-bright)', fontWeight: 700, fontSize: '0.8rem', cursor: 'pointer',
                fontFamily: 'var(--font-mono)',
              }}>CONFIRM</button>
              <button onClick={() => setConfirmation(null)} style={{
                flex: 1, padding: '9px', border: '1px solid var(--border)', borderRadius: 'var(--radius-md)',
                background: 'var(--surface-raised)', color: 'var(--fg-dim)', fontSize: '0.8rem',
                cursor: 'pointer', fontFamily: 'var(--font-body)',
              }}>Cancel</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

/* ── Positions Panel (margin account + open positions) ── */
function PositionsPanel({ positions, commodities, credits, usedMargin }) {
  const totalUnrealized = positions.reduce((sum, p) => {
    const c = commodities.find(c => c.symbol === p.symbol);
    if (!c) return sum;
    const currentValue = c.price * p.totalUnits;
    const entryValue = p.avgEntry * p.totalUnits;
    const diff = p.direction === 'long' ? currentValue - entryValue : entryValue - currentValue;
    return sum + diff;
  }, 0);

  const totalPositionValue = positions.reduce((sum, p) => {
    const c = commodities.find(c => c.symbol === p.symbol);
    return sum + (c ? c.price * p.totalUnits : 0);
  }, 0);

  const marginUtilization = credits > 0 ? ((usedMargin / credits) * 100) : 0;

  return (
    <div style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)', overflow: 'hidden',
    }}>
      <div style={{
        padding: '8px 12px', borderBottom: '1px solid var(--border)',
        background: 'var(--surface-raised)',
        fontFamily: 'var(--font-mono)', fontSize: '0.65rem', color: 'var(--muted)',
        textTransform: 'uppercase', letterSpacing: '0.06em',
        display: 'flex', justifyContent: 'space-between',
      }}>
        <span>Open Positions</span>
        <span style={{ color: totalUnrealized >= 0 ? 'var(--green)' : 'var(--red)' }}>
          {totalUnrealized >= 0 ? '▲' : '▼'} ₢{Math.abs(totalUnrealized).toLocaleString()}
        </span>
      </div>

      {/* Account summary */}
      <div style={{ padding: 'var(--sp-3) var(--sp-4)' }}>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 'var(--sp-2)', marginBottom: 'var(--sp-3)' }}>
          <div style={{ background: 'var(--bg)', borderRadius: 'var(--radius-md)', padding: '8px 10px' }}>
            <div style={{ fontSize: '0.55rem', color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '1px' }}>Balance</div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.85rem', fontWeight: 700, color: 'var(--fg-bright)' }}>₢{credits.toLocaleString()}</div>
          </div>
          <div style={{ background: 'var(--bg)', borderRadius: 'var(--radius-md)', padding: '8px 10px' }}>
            <div style={{ fontSize: '0.55rem', color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '1px' }}>Used Margin</div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.85rem', fontWeight: 700, color: 'var(--cyan)' }}>₢{usedMargin.toLocaleString()}</div>
          </div>
          <div style={{ background: 'var(--bg)', borderRadius: 'var(--radius-md)', padding: '8px 10px' }}>
            <div style={{ fontSize: '0.55rem', color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: '1px' }}>Exposure</div>
            <div style={{ fontFamily: 'var(--font-mono)', fontSize: '0.85rem', fontWeight: 700, color: 'var(--accent)' }}>₢{totalPositionValue.toLocaleString()}</div>
          </div>
        </div>

        {/* Margin utilization bar */}
        <div style={{ marginBottom: 'var(--sp-3)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.55rem', color: 'var(--muted)', fontFamily: 'var(--font-mono)', marginBottom: '3px' }}>
            <span>MARGIN UTILIZATION</span>
            <span style={{ color: marginUtilization > 80 ? 'var(--red)' : marginUtilization > 50 ? 'var(--accent)' : 'var(--green)' }}>
              {marginUtilization.toFixed(1)}%
            </span>
          </div>
          <div style={{ height: '4px', background: 'var(--surface-raised)', borderRadius: '2px', overflow: 'hidden' }}>
            <div style={{
              height: '100%', borderRadius: '2px',
              width: `${Math.min(marginUtilization, 100)}%`,
              background: marginUtilization > 80 ? 'var(--red)' : marginUtilization > 50 ? 'var(--accent)' : 'var(--green)',
              transition: 'width 0.3s ease',
            }} />
          </div>
        </div>

        {/* Position rows */}
        {positions.length === 0 && (
          <div style={{ textAlign: 'center', padding: 'var(--sp-4)', color: 'var(--muted)', fontSize: '0.75rem' }}>
            No open positions
          </div>
        )}
        {positions.map((p, i) => {
          const c = commodities.find(c => c.symbol === p.symbol);
          if (!c) return null;
          const currentVal = c.price * p.totalUnits;
          const entryVal = p.avgEntry * p.totalUnits;
          const pnl = p.direction === 'long' ? currentVal - entryVal : entryVal - currentVal;
          const pnlPct = entryVal > 0 ? (pnl / p.margin) * 100 : 0;
          const contract = CONTRACTS.find(ct => ct.symbol === p.symbol);
          return (
            <div key={i} style={{
              padding: '6px 0', borderBottom: '1px solid var(--border)', fontSize: '0.72rem',
            }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: '3px' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--sp-2)' }}>
                  <span style={{ fontWeight: 700, color: 'var(--fg-bright)' }}>{p.symbol}</span>
                  <span style={{
                    fontSize: '0.55rem', fontFamily: 'var(--font-mono)', fontWeight: 600,
                    color: p.direction === 'long' ? 'var(--green)' : 'var(--red)',
                    background: p.direction === 'long' ? 'var(--green-bg)' : 'var(--red-bg)',
                    padding: '1px 5px', borderRadius: 'var(--radius-pill)',
                  }}>
                    {p.direction === 'long' ? 'LONG' : 'SHORT'}
                  </span>
                </div>
                <span style={{
                  fontFamily: 'var(--font-mono)', fontWeight: 700,
                  color: pnl >= 0 ? 'var(--green)' : 'var(--red)',
                }}>
                  {pnl >= 0 ? '+' : ''}₢{pnl.toLocaleString()}
                </span>
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--font-mono)', fontSize: '0.62rem', color: 'var(--muted)' }}>
                <span>{p.lots} lot{p.lots > 1 ? 's' : ''} ({p.totalUnits.toLocaleString()} u.) @ ₢{p.avgEntry}</span>
                <span>Margin: ₢{p.margin.toLocaleString()}</span>
              </div>
              <div style={{ marginTop: '3px', height: '3px', background: 'var(--surface-raised)', borderRadius: '2px', overflow: 'hidden' }}>
                <div style={{
                  height: '100%', borderRadius: '2px',
                  width: `${Math.min(Math.abs(pnlPct), 100)}%`,
                  background: pnl >= 0 ? 'var(--green)' : 'var(--red)',
                  opacity: 0.6,
                }} />
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ── Trade Feed ── */
function TradeFeed({ trades }) {
  return (
    <div style={{
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--radius-lg)', overflow: 'hidden',
    }}>
      <div style={{
        padding: '8px 12px', borderBottom: '1px solid var(--border)',
        background: 'var(--surface-raised)',
        fontFamily: 'var(--font-mono)', fontSize: '0.65rem', color: 'var(--muted)',
        textTransform: 'uppercase', letterSpacing: '0.06em',
      }}>
        Market Trades
      </div>
      <div style={{ maxHeight: '180px', overflowY: 'auto', overscrollBehavior: 'contain' }}>
        {trades.map((t, i) => (
          <div key={i} style={{
            display: 'grid', gridTemplateColumns: '42px 1fr 70px 50px',
            padding: '4px 12px', fontFamily: 'var(--font-mono)', fontSize: '0.65rem',
            borderBottom: '1px solid var(--border)',
            background: i < 2 ? (t.side === 'long' ? 'rgba(34,197,94,0.03)' : 'rgba(239,68,68,0.03)') : 'transparent',
          }}>
            <span style={{ color: 'var(--muted)' }}>{t.time}</span>
            <span style={{ color: 'var(--fg-dim)' }}>{t.lots}× {t.symbol}</span>
            <span style={{ color: 'var(--fg-bright)', textAlign: 'right' }}>₢{t.price.toLocaleString()}</span>
            <span style={{ color: t.side === 'long' ? 'var(--green)' : 'var(--red)', textAlign: 'right', fontWeight: 600, fontSize: '0.58rem' }}>
              {t.side === 'long' ? 'BID' : 'ASK'}
            </span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ──────────────────────────────────────────────
   Main MarketDemo component
   ────────────────────────────────────────────── */
export function MarketDemo() {
  const [credits, setCredits] = useState(250000);
  const { session: sliceSession, emit } = useGameSliceSession();
  const [selectedSymbol, setSelectedSymbol] = useState('VLD');
  const [category, setCategory] = useState('all');
  const [notifications, setNotifications] = useState([]);

  /* Generate live commodity data */
  const [commodities, setCommodities] = useState(() => {
    return CONTRACTS.map(ct => {
      const history = []; let p = ct.basePrice;
      for (let i = 0; i < 60; i++) {
        p = Math.max(ct.basePrice * 0.7, Math.min(ct.basePrice * 1.3, p + (Math.random() - 0.48) * ct.basePrice * 0.04));
        history.push(Math.round(p * 100) / 100);
      }
      const price = history[history.length - 1];
      const prev = history[history.length - 2];
      const settlement = history[Math.floor(history.length / 2)];
      const bestBid = Math.round((price - ct.basePrice * 0.005) * 100) / 100;
      const bestAsk = Math.round((price + ct.basePrice * 0.005) * 100) / 100;
      return {
        ...ct,
        price, prevPrice: prev,
        change: price - prev,
        changePct: ((price - prev) / prev) * 100,
        history, settlement, bestBid, bestAsk,
        volume: Math.floor(Math.random() * 80000 + 5000),
        openInterest: Math.floor(Math.random() * 200000 + 10000),
        open: history[0],
        high: Math.max(...history),
        low: Math.min(...history),
        supply: Math.floor(Math.random() * 50000 + 10000),
        demand: Math.floor(Math.random() * 60000 + 8000),
      };
    });
  });

  /* Open positions */
  const [positions, setPositions] = useState([
    { symbol: 'VLD', direction: 'long', lots: 5, totalUnits: 5000, avgEntry: 13.20, margin: 5280 },
    { symbol: 'TRI', direction: 'long', lots: 3, totalUnits: 15000, avgEntry: 4.80, margin: 2160 },
    { symbol: 'ARK', direction: 'short', lots: 2, totalUnits: 100, avgEntry: 635, margin: 25400 },
  ]);

  /* Order book for selected */
  const selected = commodities.find(c => c.symbol === selectedSymbol) || commodities[0];
  const selectedContract = CONTRACTS.find(c => c.symbol === selectedSymbol) || CONTRACTS[0];
  const orderBook = useMemo(() => {
    const p = selected.price;
    const bids = []; const asks = [];
    let bidCum = 0; let askCum = 0;
    for (let i = 0; i < 10; i++) {
      const bv = Math.floor(Math.random() * 12000 + 500); bidCum += bv;
      bids.push({ price: Math.max(0.01, Math.round((p - (i + 1) * selectedContract.tickSize * 3) * 100) / 100), volume: bv, cumulative: bidCum });
      const av = Math.floor(Math.random() * 12000 + 500); askCum += av;
      asks.push({ price: Math.round((p + (i + 1) * selectedContract.tickSize * 3) * 100) / 100, volume: av, cumulative: askCum });
    }
    return { bids, asks };
  }, [selected.price, selectedSymbol, selectedContract.tickSize]);

  const usedMargin = positions.reduce((s, p) => s + p.margin, 0);

  /* Price chart data */
  const chartData = useMemo(() => {
    return selected.history.map((c, i) => {
      const noise = selected.price * 0.01;
      return {
        open: selected.history[Math.max(0, i - 1)] || c,
        high: c + Math.random() * noise * 2,
        low: Math.max(0.01, c - Math.random() * noise * 2),
        close: c,
        volume: Math.floor(Math.random() * 5000 + 500),
      };
    });
  }, [selected]);

  /* Trade feed */
  const [tradeFeed, setTradeFeed] = useState(() => {
    const feed = [];
    const syms = CONTRACTS.map(c => c.symbol);
    for (let i = 0; i < 20; i++) {
      const sym = syms[Math.floor(Math.random() * syms.length)];
      const ct = CONTRACTS.find(c => c.symbol === sym);
      const c = commodities.find(c => c.symbol === sym);
      feed.push({
        time: `${14}:${String(22 + i).padStart(2, '0')}`,
        symbol: sym,
        lots: Math.floor(Math.random() * 10 + 1),
        price: c ? Math.round(c.price * 100) / 100 : ct.basePrice,
        side: Math.random() > 0.5 ? 'long' : 'short',
      });
    }
    return feed.reverse();
  });

  /* Live price ticks */
  useEffect(() => {
    const interval = setInterval(() => {
      setCommodities(prev => prev.map(c => {
        const ct = CONTRACTS.find(x => x.symbol === c.symbol);
        const delta = (Math.random() - 0.48) * c.price * 0.006;
        const newPrice = Math.max(0.01, Math.round((c.price + delta) * 100) / 100);
        const history = [...c.history.slice(1), newPrice];
        const change = newPrice - c.prevPrice;
        const spread = ct.basePrice * 0.005;
        return {
          ...c, price: newPrice, history,
          volume: c.volume + Math.floor(Math.random() * 300),
          change, changePct: c.prevPrice > 0 ? (change / c.prevPrice) * 100 : 0,
          high: Math.max(c.high, newPrice), low: Math.min(c.low, newPrice),
          bestBid: Math.round((newPrice - spread) * 100) / 100,
          bestAsk: Math.round((newPrice + spread) * 100) / 100,
          openInterest: c.openInterest + Math.floor(Math.random() * 200 - 80),
          supply: c.supply + Math.floor(Math.random() * 200 - 100),
          demand: c.demand + Math.floor(Math.random() * 200 - 80),
        };
      }));
    }, 2500);
    return () => clearInterval(interval);
  }, []);

  /* New trades in feed */
  useEffect(() => {
    const interval = setInterval(() => {
      const syms = CONTRACTS.map(c => c.symbol);
      const sym = syms[Math.floor(Math.random() * syms.length)];
      const c = commodities.find(c => c.symbol === sym);
      const ct = CONTRACTS.find(c => c.symbol === sym);
      const now = new Date();
      setTradeFeed(prev => [{
        time: `${now.getHours()}:${String(now.getMinutes()).padStart(2, '0')}`,
        symbol: sym,
        lots: Math.floor(Math.random() * 15 + 1),
        price: c ? c.price : ct.basePrice,
        side: Math.random() > 0.5 ? 'long' : 'short',
      }, ...prev].slice(0, 40));
    }, 3000);
    return () => clearInterval(interval);
  }, [commodities]);

  const addNotif = (msg, color) => {
    const id = Date.now();
    setNotifications(prev => [...prev, { id, msg, color }]);
    setTimeout(() => setNotifications(prev => prev.filter(n => n.id !== id)), 3500);
  };

  const handleTrade = (direction, symbol, price, lots, totalUnits, marginRequired, commission) => {
    /* Deduct commission + margin from credits */
    setCredits(prev => prev - commission - marginRequired);

    setPositions(prev => {
      const existing = prev.find(p => p.symbol === symbol && p.direction === direction);
      if (existing) {
        /* Merge into existing position — weighted average entry */
        const newUnits = existing.totalUnits + totalUnits;
        const newAvg = Math.round(((existing.avgEntry * existing.totalUnits) + (price * totalUnits)) / newUnits * 100) / 100;
        const newMargin = existing.margin + marginRequired;
        return prev.map(p => p.symbol === symbol && p.direction === direction
          ? { ...p, lots: p.lots + lots, totalUnits: newUnits, avgEntry: newAvg, margin: newMargin }
          : p);
      }
      return [...prev, { symbol, direction, lots, totalUnits, avgEntry: price, margin: marginRequired }];
    });

    addNotif(
      `${direction === 'long' ? 'LONG' : 'SHORT'} ${lots}× ${symbol} (${totalUnits.toLocaleString()} u.) @ ₢${price}`,
      direction === 'long' ? 'var(--green)' : 'var(--red)'
    );

    const now = new Date();
    setTradeFeed(prev => [{
      time: `${now.getHours()}:${String(now.getMinutes()).padStart(2, '0')}`,
      symbol, lots, price, side: direction,
    }, ...prev].slice(0, 40));
  };

  const handleSliceSell = (cargoItem) => {
    if (!sliceSession?.dockedStationPoiId) return;
    const isk = cargoItem.quantity * cargoItem.unitPrice;
    emit({ type: 'market.sold', item: cargoItem.item, quantity: cargoItem.quantity, isk });
    emit({ type: 'xp.awarded', skill: 'Trade', amount: 30 });
    emit({ type: 'zora.observed', trigger: 'market.sold' });
    addNotif(`Sold ${cargoItem.quantity.toLocaleString()} ${cargoItem.item} for ₢${isk.toLocaleString()}.`, 'var(--green)');
  };

  /* Market stats */
  const totalVolume = commodities.reduce((s, c) => s + c.volume, 0);
  const totalOI = commodities.reduce((s, c) => s + c.openInterest, 0);
  const advancers = commodities.filter(c => c.change >= 0).length;
  const decliners = commodities.length - advancers;
  const tickerItems = commodities.slice(0, 12).map(c => ({
    symbol: c.symbol, price: c.price, change: c.change, changePct: c.changePct,
  }));

  const spread = selectedContract ? Math.round((selected.bestAsk - selected.bestBid) * 100) / 100 : 0;
  const spreadPct = selected.bestBid > 0 ? (spread / selected.bestBid) * 100 : 0;
  const midPrice = Math.round(((selected.bestBid + selected.bestAsk) / 2) * 100) / 100;

  return (
    <div className="mx-auto max-w-content" style={{ maxWidth: '1260px' }}>
      <a href="/docs/overview" style={{ display: 'inline-flex', alignItems: 'center', gap: '4px', fontSize: '0.75rem', fontFamily: 'var(--font-mono)', color: 'var(--muted)', textDecoration: 'none', marginBottom: 'var(--sp-2)', transition: 'color 0.15s' }} onMouseEnter={e => e.currentTarget.style.color='var(--fg-bright)'} onMouseLeave={e => e.currentTarget.style.color='var(--muted)'}>← Back to Docs</a>
      {/* Ticker */}
      <TickerTape items={tickerItems} />

      {/* Header bar */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 'var(--sp-3)',
        padding: 'var(--sp-3) 0', fontFamily: 'var(--font-mono)', fontSize: '0.7rem',
        borderBottom: '1px solid var(--border)', marginBottom: 'var(--sp-3)',
        flexWrap: 'wrap',
      }}>
        <span style={{ fontWeight: 700, color: 'var(--fg-bright)', fontSize: '0.85rem', letterSpacing: '0.03em' }}>COMMODITIES EXCHANGE</span>
        <div style={{ width: 1, height: 14, background: 'var(--border)' }} />
        <span style={{ color: 'var(--muted)' }}>SESSION</span>
        <span style={{ color: 'var(--green)', fontWeight: 600 }}>OPEN</span>
        <div style={{ width: 1, height: 14, background: 'var(--border)' }} />
        <span style={{ color: 'var(--green)' }}>{advancers} ▲</span>
        <span style={{ color: 'var(--red)' }}>{decliners} ▼</span>
        <div style={{ width: 1, height: 14, background: 'var(--border)' }} />
        <span style={{ color: 'var(--muted)' }}>TOTAL VOL</span>
        <span style={{ color: 'var(--fg-bright)' }}>{(totalVolume / 1e6).toFixed(2)}M</span>
        <div style={{ width: 1, height: 14, background: 'var(--border)' }} />
        <span style={{ color: 'var(--muted)' }}>OPEN INT.</span>
        <span style={{ color: 'var(--cyan)' }}>{(totalOI / 1e6).toFixed(1)}M</span>
        <div style={{ width: 1, height: 14, background: 'var(--border)' }} />
        <span style={{ color: 'var(--muted)' }}>ACCOUNT (₢ = ISK)</span>
        <span style={{ color: 'var(--accent)', fontWeight: 600 }}>₢{credits.toLocaleString()}</span>
      </div>

      {/* Category tabs */}
      <CategoryTabs active={category} onChange={setCategory} />

      {sliceSession && (
        <div style={{ marginBottom: 'var(--sp-4)', background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--radius-lg)', overflow: 'hidden' }}>
          <div style={{ padding: '8px 14px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 'var(--sp-3)', fontFamily: 'var(--font-mono)', fontSize: '0.7rem' }}>
            <strong style={{ color: 'var(--accent)' }}>SLICE CARGO SALES</strong>
            <span style={{ color: 'var(--muted)' }}>Station: {sliceSession.dockedStationName || 'Undocked'}</span>
            <span style={{ marginLeft: 'auto', color: 'var(--green)' }}>Wallet ₢{sliceSession.wallet.toLocaleString()}</span>
            <button onClick={() => { window.location.href = withGameSliceSession('/docs/demos/game-loop', sliceSession.id); }}>Return to Loop</button>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 8, padding: 10 }}>
            {sellableCargo(sliceSession.cargo).length === 0 && (
              <div style={{ color: 'var(--muted)', fontSize: '0.82rem' }}>No sellable slice cargo.</div>
            )}
            {sellableCargo(sliceSession.cargo).map(item => (
              <div key={`${item.category}-${item.item}`} style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 8, alignItems: 'center', padding: 10, background: 'var(--surface-raised)', border: '1px solid var(--border)', borderRadius: 'var(--radius-md)' }}>
                <div>
                  <div style={{ color: 'var(--fg-bright)' }}>{item.item}</div>
                  <div style={{ color: 'var(--muted)', fontFamily: 'var(--font-mono)', fontSize: '0.68rem' }}>{item.quantity.toLocaleString()} × ₢{item.unitPrice}</div>
                </div>
                <button disabled={!sliceSession.dockedStationPoiId} onClick={() => handleSliceSell(item)}>
                  {sliceSession.dockedStationPoiId ? `Sell ₢${(item.quantity * item.unitPrice).toLocaleString()}` : 'Dock Required'}
                </button>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Notifications */}
      <div style={{ position: 'fixed', top: 'var(--sp-4)', right: 'var(--sp-4)', zIndex: 1000, display: 'flex', flexDirection: 'column', gap: 'var(--sp-2)' }}>
        {notifications.map(n => (
          <div key={n.id} style={{
            background: 'var(--surface)', border: `1px solid ${n.color}40`,
            borderRadius: 'var(--radius-md)', padding: 'var(--sp-2) var(--sp-4)',
            fontSize: '0.72rem', color: n.color, fontFamily: 'var(--font-mono)',
            boxShadow: 'var(--shadow-md)',
          }}>
            {n.msg}
          </div>
        ))}
      </div>

      {/* Main grid: Left (board + chart + feed) | Right (specs + depth + order + positions) */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 380px', gap: 'var(--sp-4)', alignItems: 'start' }}>

        {/* Left column */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--sp-4)' }}>
          {/* Contract board */}
          <ContractBoard commodities={commodities} selected={selectedSymbol} onSelect={setSelectedSymbol} category={category} />

          {/* Price chart */}
          <div style={{
            background: 'var(--surface)', border: '1px solid var(--border)',
            borderRadius: 'var(--radius-lg)', overflow: 'hidden',
          }}>
            <div style={{
              padding: '8px 14px', borderBottom: '1px solid var(--border)',
              display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            }}>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 'var(--sp-2)' }}>
                <span style={{ fontWeight: 700, color: 'var(--accent)', fontSize: '0.9rem', fontFamily: 'var(--font-mono)' }}>{selected.symbol}</span>
                <span style={{ fontSize: '0.7rem', color: 'var(--fg-dim)' }}>{selected.name}</span>
              </div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 'var(--sp-3)' }}>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: '0.65rem', color: 'var(--muted)' }}>
                  O:₢{selected.open} H:₢{selected.high} L:₢{selected.low}
                </span>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: '1.1rem', fontWeight: 700, color: 'var(--fg-bright)' }}>
                  ₢{selected.price.toLocaleString()}
                </span>
                <span style={{
                  fontFamily: 'var(--font-mono)', fontSize: '0.7rem', fontWeight: 600,
                  color: selected.change >= 0 ? 'var(--green)' : 'var(--red)',
                }}>
                  {selected.change >= 0 ? '+' : ''}{selected.change.toFixed(2)} ({selected.changePct >= 0 ? '+' : ''}{selected.changePct.toFixed(2)}%)
                </span>
              </div>
            </div>
            <div style={{ padding: 'var(--sp-3)' }}>
              <PriceChart data={chartData} symbol={selectedSymbol} />
            </div>
          </div>

          {/* Trade feed */}
          <TradeFeed trades={tradeFeed} />
        </div>

        {/* Right column */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--sp-4)', position: 'sticky', top: 'var(--sp-4)' }}>
          {/* Contract spec */}
          <ContractSpec contract={selectedContract} commodity={selected} />

          {/* Depth chart */}
          <div style={{
            background: 'var(--surface)', border: '1px solid var(--border)',
            borderRadius: 'var(--radius-lg)', overflow: 'hidden',
            padding: 'var(--sp-3)',
          }}>
            <div style={{
              fontFamily: 'var(--font-mono)', fontSize: '0.6rem', color: 'var(--muted)',
              textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 'var(--sp-2)',
            }}>
              Depth of Market
            </div>
            <DepthChart bids={orderBook.bids} asks={orderBook.asks} midPrice={midPrice} />
          </div>

          {/* Order book */}
          <OrderBook
            bids={orderBook.bids} asks={orderBook.asks}
            spread={spread} spreadPct={spreadPct}
          />

          {/* Order form */}
          <OrderForm
            contract={selectedContract}
            commodity={selected}
            credits={credits}
            positions={positions}
            onTrade={handleTrade}
          />

          {/* Positions */}
          <PositionsPanel
            positions={positions}
            commodities={commodities}
            credits={credits}
            usedMargin={usedMargin}
          />
        </div>
      </div>
    </div>
  );
}
