// roulette.jsx — European wheel, multi-bet (place chips on several outcomes)

const ROULETTE_ORDER = [0,32,15,19,4,21,2,25,17,34,6,27,13,36,11,30,8,23,10,5,24,16,33,1,20,14,31,9,22,18,29,7,28,12,35,3,26];
const RED = new Set([1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36]);
const numColor = (n) => n === 0 ? 'green' : RED.has(n) ? 'red' : 'black';

const SPIN_DURATION = 6800;

// Bet kinds: red, black, even, odd, low (1-18), high (19-36), zero (n=0)
function evalBet(kind, winningNum) {
  const c = numColor(winningNum);
  switch (kind) {
    case 'red':   return { win: c === 'red',   mult: 1 };
    case 'black': return { win: c === 'black', mult: 1 };
    case 'even':  return { win: winningNum !== 0 && winningNum % 2 === 0, mult: 1 };
    case 'odd':   return { win: winningNum % 2 === 1, mult: 1 };
    case 'low':   return { win: winningNum >= 1 && winningNum <= 18, mult: 1 };
    case 'high':  return { win: winningNum >= 19 && winningNum <= 36, mult: 1 };
    case 'zero':  return { win: winningNum === 0, mult: 35 };
    default:      return { win: false, mult: 1 };
  }
}
const KIND_LABEL = { red:'red', black:'black', even:'even', odd:'odd', low:'1–18', high:'19–36', zero:'0' };

function Roulette({ onBack, onHistory, onRules, onTip }) {
  const { balance, settle } = useStore();
  const [chip, setChipState] = React.useState(null); // currently selected chip denomination
  const [bets, setBets] = React.useState({});        // { red: 50, black: 0, ... } — funded
  const [armed, setArmed] = React.useState(() => new Set()); // bet kinds tapped without chip
  const [spinning, setSpinning] = React.useState(false);
  const [result, setResult] = React.useState(null);
  const [wheelAngle, setWheelAngle] = React.useState(0);
  const [ballAngle, setBallAngle] = React.useState(0);

  const SLICE = 360 / 37;
  const SIZE = 280;

  const total = Object.values(bets).reduce((a, b) => a + b, 0);
  const remaining = balance - total;

  // Selecting a chip applies its value to any "armed" bets (tapped without chip).
  const setChip = (c) => {
    setChipState(c);
    try { if (typeof sounds !== 'undefined') sounds.tick(); } catch (e) {}
    if (armed.size > 0 && c) {
      setBets((b) => {
        const newBets = { ...b };
        let used = 0;
        const armedList = Array.from(armed);
        for (const kind of armedList) {
          if (total + used + c > balance) break; // skip if exceeds balance
          newBets[kind] = (newBets[kind] || 0) + c;
          used += c;
        }
        return newBets;
      });
      setArmed(new Set());
    }
  };

  const placeBet = (kind) => {
    if (spinning) return;
    if (!chip) {
      // No chip selected → toggle armed (visual pre-selection)
      setArmed((s) => {
        const next = new Set(s);
        if (next.has(kind)) next.delete(kind);
        else next.add(kind);
        return next;
      });
      try { if (typeof sounds !== 'undefined') sounds.tick(); } catch (e) {}
      setResult(null);
      return;
    }
    if (chip > remaining) return;
    setBets((b) => ({ ...b, [kind]: (b[kind] || 0) + chip }));
    setResult(null);
    try { if (typeof sounds !== 'undefined') sounds.tick(); } catch (e) {}
  };
  const clearBets = () => {
    if (spinning) return;
    setBets({});
    setArmed(new Set());
    setResult(null);
  };

  const spin = () => {
    if (spinning || total <= 0 || total > balance) return;
    setSpinning(true); setResult(null);
    try { if (typeof sounds !== 'undefined') sounds.rollingDecel(6800, 900, 200, 0.035); } catch (e) {}
    const winningNum = Math.floor(Math.random() * 37);
    const winningIdx = ROULETTE_ORDER.indexOf(winningNum);

    const wheelExtra = 360 * 8;
    setWheelAngle((a) => {
      const newWheel = a + wheelExtra;
      const targetBall = winningIdx * SLICE + newWheel;
      const currentBall = ballAngle;
      let nextBall = targetBall;
      while (nextBall > currentBall - 360 * 10) nextBall -= 360;
      setBallAngle(nextBall);
      return newWheel;
    });

    setTimeout(() => {
      const c = numColor(winningNum);
      let delta = 0;
      const winners = [];
      Object.entries(bets).forEach(([kind, amt]) => {
        if (amt <= 0) return;
        const { win, mult } = evalBet(kind, winningNum);
        if (win) { delta += amt * mult; winners.push(KIND_LABEL[kind]); }
        else     { delta -= amt; }
      });
      const detail = `${winningNum} · ${c}` + (winners.length ? ` · won ${winners.join(', ')}` : '');
      settle('Roulette', delta, detail);
      setResult({ delta, num: winningNum, color: c });
      setSpinning(false);
      setBets({});
      setArmed(new Set());
    }, SPIN_DURATION);
  };

  return (
    <>
      <TopBar onBack={onBack} title="ROULETTE" balance={balance} onRules={onRules} onTip={onTip} />
      <div className="stage">
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', gap: 18, padding: '8px 0' }}>
          <Wheel size={SIZE} wheelAngle={wheelAngle} ballAngle={ballAngle} spinning={spinning} />
          <div style={{ height: 22, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 16 }}>
            {result && !spinning ? (
              <>
                <span style={{
                  display: 'inline-block', width: 26, height: 26, borderRadius: '50%',
                  border: '1px solid var(--line-2)',
                  background: result.color === 'red' ? '#7a2820' : result.color === 'green' ? '#1f4a30' : '#1a1a1a',
                  color: 'var(--text)', fontSize: 12, lineHeight: '24px', textAlign: 'center',
                  fontVariantNumeric: 'tabular-nums', fontFamily: 'var(--font-mono)',
                }}>{result.num}</span>
                <span style={{
                  fontSize: 11, letterSpacing: '0.22em', textTransform: 'uppercase',
                  color: result.delta > 0 ? 'var(--win)' : result.delta < 0 ? 'var(--text-3)' : 'var(--text-3)',
                  fontFamily: 'var(--font-mono)',
                }}>{result.delta > 0 ? `+ ${result.delta.toLocaleString('en-US')}` : result.delta < 0 ? `— ${Math.abs(result.delta).toLocaleString('en-US')}` : '± 0'}</span>
              </>
            ) : <span className="eyebrow">{spinning ? 'spinning…' : total > 0 ? `${Object.keys(bets).filter(k => bets[k] > 0).length} bets · ${total.toLocaleString('en-US')}` : 'place chips on any outcome'}</span>}
          </div>
        </div>

        <div style={{ padding: '0 24px 12px' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10 }}>
            <span className="eyebrow">Bets</span>
            <span className="eyebrow press" style={{
              cursor: total > 0 && !spinning ? 'pointer' : 'default',
              opacity: total > 0 && !spinning ? 1 : 0.3,
              color: 'var(--text-3)',
            }} onClick={clearBets}>clear</span>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 6, marginBottom: 6 }}>
            <BetCell label="Red" stake={bets.red} armed={armed.has('red')} onClick={() => placeBet('red')} swatch="#7a2820" />
            <BetCell label="Black" stake={bets.black} armed={armed.has('black')} onClick={() => placeBet('black')} swatch="#0e0e0e" />
            <BetCell label="0 · 35×" stake={bets.zero} armed={armed.has('zero')} onClick={() => placeBet('zero')} swatch="#1f4a30" />
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gap: 6 }}>
            <BetCell small label="Even" stake={bets.even} armed={armed.has('even')} onClick={() => placeBet('even')} />
            <BetCell small label="Odd" stake={bets.odd} armed={armed.has('odd')} onClick={() => placeBet('odd')} />
            <BetCell small label="1–18" stake={bets.low} armed={armed.has('low')} onClick={() => placeBet('low')} />
            <BetCell small label="19–36" stake={bets.high} armed={armed.has('high')} onClick={() => placeBet('high')} />
          </div>
        </div>

        <div style={{ padding: '0 0 16px' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', padding: '0 24px 10px' }}>
            <span className="eyebrow">Chip</span>
            <span className="mono" style={{ fontSize: 11, color: 'var(--text-4)', letterSpacing: '0.06em' }}>
              {remaining.toLocaleString('en-US')} left
            </span>
          </div>
          <BetSelector value={chip} onChange={setChip} />
        </div>
        <div style={{ padding: '8px 24px 24px', borderTop: '1px solid var(--line)' }}>
          <button className="btn" onClick={spin} disabled={spinning || !chip || total <= 0 || total > balance}
            style={{ width: '100%', height: 56, letterSpacing: '0.3em' }}>
            {spinning ? '· · ·' :
             !chip && armed.size > 0 ? 'Pick a chip' :
             !chip ? 'Pick a chip & bet' :
             total <= 0 ? 'Place a bet' :
             `Spin · ${total.toLocaleString('en-US')}`}
          </button>
        </div>
      </div>
    </>
  );
}

function BetCell({ label, stake, armed, onClick, swatch, small }) {
  const has = stake && stake > 0;
  // Border priority: funded (white) > armed (dashed accent) > default (hairline)
  const border = has
    ? '1px solid var(--text)'
    : armed
      ? '1px dashed var(--accent)'
      : '1px solid var(--line-2)';
  const bg = has
    ? 'rgba(255,255,255,0.04)'
    : armed
      ? 'rgba(255,255,255,0.025)'
      : 'transparent';
  return (
    <button className="press" onClick={onClick} style={{
      appearance: 'none', cursor: 'pointer', position: 'relative',
      background: bg,
      color: 'var(--text-2)',
      border: border,
      height: small ? 36 : 44,
      fontFamily: 'var(--font-sans)', fontSize: small ? 11 : 12,
      letterSpacing: '0.18em', textTransform: 'uppercase',
      display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      transition: 'border-color 0.15s, background 0.15s',
    }}>
      {swatch && (
        <span style={{
          width: 10, height: 10, borderRadius: '50%',
          background: swatch, border: '0.5px solid rgba(255,255,255,0.2)',
        }} />
      )}
      <span style={{ color: has || armed ? 'var(--text)' : 'var(--text-2)' }}>{label}</span>
      {has && (
        <span className="mono" style={{
          marginLeft: 'auto',
          position: 'absolute', top: small ? 3 : 4, right: small ? 6 : 8,
          fontSize: small ? 9 : 10, letterSpacing: '0.04em',
          color: 'var(--accent)', fontVariantNumeric: 'tabular-nums',
          textTransform: 'none',
        }}>{stake.toLocaleString('en-US')}</span>
      )}
      {!has && armed && (
        <span className="mono" style={{
          position: 'absolute', top: small ? 3 : 4, right: small ? 6 : 8,
          fontSize: small ? 9 : 10, letterSpacing: '0.04em',
          color: 'var(--accent)', textTransform: 'none',
        }}>·</span>
      )}
    </button>
  );
}

function Wheel({ size, wheelAngle, ballAngle, spinning }) {
  const SLICE = 360 / 37;
  const r = size / 2;
  const innerR = r - 2;
  const numR = r - 18;
  const ballR = r - 14;

  const slices = ROULETTE_ORDER.map((n, i) => {
    const a0 = i * SLICE - 90 - SLICE/2;
    const a1 = a0 + SLICE;
    const x0 = r + Math.cos(a0 * Math.PI / 180) * innerR;
    const y0 = r + Math.sin(a0 * Math.PI / 180) * innerR;
    const x1 = r + Math.cos(a1 * Math.PI / 180) * innerR;
    const y1 = r + Math.sin(a1 * Math.PI / 180) * innerR;
    const fill = n === 0 ? '#1f4a30' : RED.has(n) ? '#7a2820' : '#0a0a0a';
    return (
      <path key={n}
        d={`M ${r} ${r} L ${x0} ${y0} A ${innerR} ${innerR} 0 0 1 ${x1} ${y1} Z`}
        fill={fill}
        stroke="rgba(255,255,255,0.06)"
        strokeWidth="0.5"
      />
    );
  });

  const numbers = ROULETTE_ORDER.map((n, i) => {
    const a = (i * SLICE - 90) * Math.PI / 180;
    const x = r + Math.cos(a) * numR;
    const y = r + Math.sin(a) * numR;
    return (
      <text key={n} x={x} y={y}
        fill="#f4f4f4"
        fontFamily="ui-monospace, monospace" fontSize="9"
        textAnchor="middle" dominantBaseline="middle"
        transform={`rotate(${i * SLICE} ${x} ${y})`}
      >{n}</text>
    );
  });

  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <div style={{
        position: 'absolute', inset: 0, borderRadius: '50%',
        background: '#0a0a0a',
        border: '1px solid rgba(255,255,255,0.18)',
      }} />
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{
        position: 'absolute', inset: 0,
        transform: `rotate(${wheelAngle}deg)`,
        transition: `transform ${SPIN_DURATION}ms cubic-bezier(.12,.62,.18,1)`,
      }}>
        <circle cx={r} cy={r} r={innerR} fill="#0a0a0a" />
        {slices}
        {numbers}
        <circle cx={r} cy={r} r={r - 38} fill="none" stroke="rgba(255,255,255,0.1)" strokeWidth="0.5" />
        <circle cx={r} cy={r} r={r - 60} fill="#0a0a0a" stroke="rgba(255,255,255,0.18)" strokeWidth="0.5" />
        <circle cx={r} cy={r} r={r - 90} fill="#050505" />
        <circle cx={r} cy={r} r={r - 100} fill="none" stroke="rgba(255,255,255,0.18)" strokeWidth="0.5" />
        <text x={r} y={r+2} fill="rgba(255,255,255,0.4)" fontFamily="serif" fontStyle="italic" fontSize="14"
          textAnchor="middle" dominantBaseline="middle">M</text>
      </svg>
      <div style={{
        position: 'absolute', inset: 0,
        transform: `rotate(${ballAngle}deg)`,
        transition: `transform ${SPIN_DURATION}ms cubic-bezier(.15,.55,.2,1)`,
      }}>
        <div style={{
          position: 'absolute', left: r - 4, top: r - ballR - 4,
          width: 8, height: 8, borderRadius: '50%',
          background: '#f4f1e8',
          boxShadow: '0 0 6px rgba(255,255,255,0.35)',
        }} />
      </div>
      <div style={{
        position: 'absolute', top: -2, left: '50%', transform: 'translateX(-50%)',
        width: 0, height: 0, borderLeft: '5px solid transparent', borderRight: '5px solid transparent',
        borderTop: '8px solid var(--text)', zIndex: 5,
      }} />
    </div>
  );
}

Object.assign(window, { Roulette });
