/* ============================================================
   rail.jsx — coaching rail, header, settings modal
   ============================================================ */
const E2 = window.Engine;
const fmt2 = window.UI.fmt;
const MixBar = window.UI.MixBar;

/* ---------- Header ---------- */
function Header({ mode, setMode, styleKey, session, onSettings, onMenu, muted, onToggleSound }) {
  const style = window.GTO.STYLES[styleKey];
  const acc = session.decisions > 0 ? Math.round((session.optimal / session.decisions) * 100) : null;
  return (
    <header className="header">
      {onMenu && <button className="iconbtn" onClick={onMenu} aria-label="Main menu" title="Main menu">{"☰"}</button>}
      <div className="brand">
        <div className="name"><span className="dot" />GTO HEADS-UP</div>
        <div className="sub">heads-up no-limit trainer</div>
      </div>
      <div className="seg" role="tablist">
        <button className={mode === "play" ? "on" : ""} onClick={() => setMode("play")}>Play</button>
        <button className={mode === "study" ? "on" : ""} onClick={() => setMode("study")}>Study</button>
      </div>
      <div className="hspace" />
      <button className="pill" onClick={onSettings} title="Opponent style">
        <span className="k">VS</span>{style.label}
      </button>
      <div className="stat-pill">
        <span className="v" style={{ color: acc == null ? "var(--text-3)" : acc >= 75 ? "var(--good)" : acc >= 55 ? "var(--ok)" : "var(--warn)" }}>
          {acc == null ? "\u2014" : acc + "%"}
        </span>
        <span className="l">GTO acc.</span>
      </div>
      <div className="stat-pill">
        <span className="v mono" style={{ color: session.bb >= 0 ? "var(--good)" : "var(--bad)" }}>
          {session.bb >= 0 ? "+" : ""}{fmt2(session.bb)}
        </span>
        <span className="l">bb won</span>
      </div>
      {onToggleSound && <button className="iconbtn" onClick={onToggleSound} title={muted ? "Unmute" : "Mute"}>{muted ? "\ud83d\udd07" : "\ud83d\udd0a"}</button>}
      <button className="iconbtn" onClick={onSettings} aria-label="Settings">{"\u2699"}</button>
    </header>
  );
}

/* ---------- Coach rail ---------- */
function CoachRail({ open, onClose, tab, setTab, spot, lastFb, session, hand, mode, reviews }) {
  return (
    <aside className={"rail" + (open ? " open" : "")}>
      <button className="iconbtn rail-close" onClick={onClose}>{"\u2715"}</button>
      <div className="rail-tabs">
        {["Spot", "Ranges", "Review", "Session", "Log"].map((t) => (
          <button key={t} className={tab === t ? "on" : ""} onClick={() => setTab(t)}>{t}</button>
        ))}
      </div>
      <div className="rail-body">
        {tab === "Spot" && <SpotPanel spot={spot} lastFb={lastFb} mode={mode} hand={hand} />}
        {tab === "Ranges" && <RangePanel />}
        {tab === "Review" && <ReviewPanel reviews={reviews} />}
        {tab === "Session" && <SessionPanel session={session} />}
        {tab === "Log" && <LogPanel hand={hand} />}
      </div>
    </aside>
  );
}

/* ---------- Hand-history / leak finder ---------- */
function ReviewRow({ r }) {
  const Hole = window.UI.Hole;
  const cls = r.color === "good" ? "var(--good)" : r.color === "ok" ? "var(--ok)" : r.color === "warn" ? "var(--warn)" : "var(--bad)";
  return (
    <div className="rev-row">
      <span className="rev-dot" style={{ background: cls }} />
      <div className="rev-main">
        <div className="rev-top">
          <span className="rev-sit">{r.situation}</span>
          <span className="rev-cards"><Hole cards={r.hole} tiny /></span>
        </div>
        <div className="rev-sub">
          {r.correct
            ? <span style={{ color: "var(--text-3)" }}>{r.optimalLabel}</span>
            : <><span style={{ color: "var(--bad)" }}>{r.chosenLabel}</span><span className="rev-arrow"> {"\u2192"} </span><span style={{ color: "var(--accent)" }}>{r.optimalLabel}</span></>}
        </div>
      </div>
      <span className="rev-ev mono" style={{ color: r.evLoss > 0 ? "var(--bad)" : "var(--text-3)" }}>
        {r.evLoss > 0 ? "\u2212" + fmt2(r.evLoss) : "0"}
      </span>
    </div>
  );
}

function ReviewPanel({ reviews }) {
  reviews = reviews || [];
  if (!reviews.length) {
    return (
      <div className="panel"><h3>Leak Finder</h3>
        <div className="empty">Play some hands. Every graded decision lands here, and your most expensive spots float to the top.</div>
      </div>
    );
  }
  // aggregate by situation to surface the biggest leaks (ranked by total bb bled)
  const groups = {};
  for (const r of reviews) {
    const g = groups[r.situation] || (groups[r.situation] = { situation: r.situation, n: 0, errs: 0, ev: 0 });
    g.n++; if (r.color === "warn" || r.color === "bad") g.errs++; g.ev += r.evLoss;
  }
  const leaks = Object.values(groups).filter((g) => g.ev > 0.01).sort((a, b) => b.ev - a.ev).slice(0, 3);
  const maxEv = leaks.length ? leaks[0].ev : 1;
  return (
    <>
      <div className="panel">
        <h3>Top leaks</h3>
        {leaks.length ? leaks.map((g) => (
          <div className="leak" key={g.situation}>
            <div className="leak-top">
              <span className="leak-sit">{g.situation}</span>
              <span className="leak-ev mono">{"\u2212" + fmt2(g.ev)} bb</span>
            </div>
            <div className="leak-bar"><i style={{ width: Math.max(6, (g.ev / maxEv) * 100) + "%" }} /></div>
            <div className="leak-sub">{g.errs} slip{g.errs === 1 ? "" : "s"} in {g.n} decision{g.n === 1 ? "" : "s"}</div>
          </div>
        )) : <div className="empty">No leaks yet — clean play. Keep going.</div>}
      </div>
      <div className="panel">
        <h3>Recent decisions</h3>
        <div className="rev-list">
          {reviews.slice(0, 40).map((r) => <ReviewRow key={r.id} r={r} />)}
        </div>
      </div>
    </>
  );
}

function SpotPanel({ spot, lastFb, mode, hand }) {
  return (
    <>
      <div className="panel">
        <h3>Live Read</h3>
        {spot && spot.showEquity ? (
          <>
            <div className="metric"><span className="l">Your equity</span><span className="v" style={{ color: "var(--accent)" }}>{fmt2(spot.equity)}%</span></div>
            <div className="eqbar"><i style={{ width: spot.equity + "%" }} /></div>
            <div style={{ height: 8 }} />
            {spot.potOdds > 0 && <div className="metric"><span className="l">Pot odds (need)</span><span className="v">{fmt2(spot.potOdds)}%</span></div>}
            <div className="metric"><span className="l">Pot</span><span className="v">{fmt2(spot.pot)} bb</span></div>
            <div className="metric"><span className="l">SPR</span><span className="v">{spot.spr == null ? "\u2014" : fmt2(spot.spr)}</span></div>
          </>
        ) : (
          <div className="empty">
            {mode === "play"
              ? "Equity is hidden in Play mode \u2014 trust your reads. Switch to Study to see live numbers."
              : "Live equity appears here on your turn."}
          </div>
        )}
      </div>
      <div className="panel">
        <h3>Last Decision</h3>
        {lastFb ? <FeedbackBody fb={lastFb} /> : <div className="empty">Make a decision to see GTO feedback.</div>}
      </div>
    </>
  );
}

function FeedbackBody({ fb }) {
  const cls = fb.color === "good" ? "fb-good" : fb.color === "ok" ? "fb-ok" : fb.color === "warn" ? "fb-warn" : "fb-bad";
  return (
    <div className="feedback-card" style={{ border: "none", padding: 0 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
        <span className={"fb-badge " + cls}>{window.UI.ratingIcon(fb.color)} {fb.ratingLabel}</span>
        <span className="mono" style={{ color: "var(--text-3)", fontSize: 12 }}>{fb.evLoss > 0 ? `\u2212${fmt2(fb.evLoss)} bb` : "0 bb"}</span>
      </div>
      <div className="fb-line"><span>You played</span><span className="mono">{fb.chosenLabel}</span></div>
      <div className="fb-line"><span>GTO play</span><span className="mono" style={{ color: "var(--accent)" }}>{fb.optimalLabel}</span></div>
      {fb.mixLabel && <MixBar mix={fb.mix} />}
      {fb.mixLabel && <div className="fb-line"><span>{fb.mixSource === "solver" ? "Solver mix" : "GTO mix"}</span><span className="mono">{fb.mixLabel}</span></div>}
      <div className="fb-line"><span>Equity</span><span className="mono">{fmt2(fb.equity)}%</span></div>
      {fb.potOdds > 0 && <div className="fb-line"><span>Pot odds</span><span className="mono">{fmt2(fb.potOdds)}%</span></div>}
      <div className="fb-note">{fb.note}</div>
    </div>
  );
}

function SessionPanel({ session }) {
  const acc = session.decisions > 0 ? (session.optimal / session.decisions) * 100 : 0;
  const rows = [
    ["Hands played", session.hands],
    ["Decisions", session.decisions],
    ["GTO-optimal", session.decisions ? `${session.optimal} (${Math.round(acc)}%)` : "\u2014"],
    ["bb won/lost", (session.bb >= 0 ? "+" : "") + fmt2(session.bb)],
    ["EV lost to errors", fmt2(session.evLost) + " bb"],
  ];
  const breakdown = [
    ["Optimal", session.tally.good, "var(--good)"],
    ["Fine", session.tally.ok, "var(--ok)"],
    ["Inaccuracy", session.tally.warn, "var(--warn)"],
    ["Mistake / Blunder", session.tally.bad, "var(--bad)"],
  ];
  return (
    <>
      <div className="panel">
        <h3>This Session</h3>
        {rows.map((r) => (
          <div className="metric" key={r[0]}><span className="l">{r[0]}</span><span className="v">{r[1]}</span></div>
        ))}
      </div>
      <div className="panel">
        <h3>Decision Quality</h3>
        {breakdown.map((b) => (
          <div className="metric" key={b[0]}>
            <span className="l" style={{ display: "flex", alignItems: "center", gap: 8 }}>
              <span style={{ width: 8, height: 8, borderRadius: 2, background: b[2] }} />{b[0]}
            </span>
            <span className="v">{b[1]}</span>
          </div>
        ))}
      </div>
    </>
  );
}

function LogPanel({ hand }) {
  if (!hand) return <div className="empty">No hand in progress.</div>;
  const streetName = { preflop: "PREFLOP", flop: "FLOP", turn: "TURN", river: "RIVER", showdown: "SHOWDOWN", done: "" };
  const rows = hand.history.map((a, idx) => {
    const who = a.player === hand.heroIdx ? "You" : "Bot";
    let desc = a.type.toUpperCase();
    if (a.type === "call" || a.type === "bet" || a.type === "raise") desc += " " + fmt2(a.to) + "bb";
    return (
      <div className="hist-row" key={idx}>
        <span className="tag" style={{ background: a.player === hand.heroIdx ? "var(--accent)" : "var(--text-3)" }} />
        <span className="desc">{who} &middot; {streetName[a.street]}</span>
        <span className="amt">{desc}</span>
      </div>
    );
  });
  return (
    <div className="panel">
      <h3>Action Log</h3>
      {rows.length ? rows : <div className="empty">New hand — no actions yet.</div>}
    </div>
  );
}

/* ---------- Range-grid viewer (live CFR solve) ---------- */
function GridCell({ node, code }) {
  const S = window.Solver, COLOR = window.UI.ACT_COLOR;
  const st = S.strategy(node), f = st && st.freq[code];
  if (!f) return <div className="gcell"><span className="lab">{code}</span></div>;
  const order = ["raise", "bet", "call", "check", "fold"];
  const segs = order.map((a) => { const idx = st.names.indexOf(a); return idx >= 0 ? { action: a, freq: f[idx] } : null; })
    .filter((x) => x && x.freq > 0.005);
  const title = code + " — " + segs.map((s) => s.action + " " + Math.round(s.freq * 100) + "%").join(", ");
  return (
    <div className="gcell" title={title}>
      <div className="bg">{segs.map((s, k) => <i key={k} style={{ width: (s.freq * 100) + "%", background: COLOR[s.action] || "var(--line-2)" }} />)}</div>
      <span className="lab">{code}</span>
    </div>
  );
}

function RangePanel() {
  const S = window.Solver;
  const ready = S && S.isReady && S.isReady();
  const [node, setNode] = React.useState("SB_open");
  const [, force] = React.useState(0);
  React.useEffect(() => {
    if (ready) return;
    const t = setInterval(() => force((x) => x + 1), 400);
    return () => clearInterval(t);
  }, [ready]);
  if (!ready) return <div className="panel"><h3>GTO Ranges</h3><div className="empty">Solving the preflop equilibrium…<br />(live CFR — a moment on first load)</div></div>;

  const RK = window.Engine.RANKS;
  const rows = [];
  for (let i = 12; i >= 0; i--) {
    const cells = [];
    for (let j = 12; j >= 0; j--) {
      const code = i === j ? RK[i] + RK[i] : i > j ? RK[i] + RK[j] + "s" : RK[j] + RK[i] + "o";
      cells.push(<GridCell key={j} node={node} code={code} />);
    }
    rows.push(<React.Fragment key={i}>{cells}</React.Fragment>);
  }
  return (
    <>
      <div className="panel">
        <h3>GTO Ranges — live CFR solve</h3>
        <div className="range-node-tabs">
          {S.NODES.map((n) => (
            <button key={n} className={node === n ? "on" : ""} onClick={() => setNode(n)}>{S.NODE_LABELS[n]}</button>
          ))}
        </div>
        <div className="grid13">{rows}</div>
        <div className="legend">
          <span><i style={{ background: "var(--accent)" }} />Raise</span>
          <span><i style={{ background: "var(--ok)" }} />Call</span>
          <span><i style={{ background: "var(--bad)" }} />Fold</span>
        </div>
        <div className="fb-note" style={{ marginTop: 10 }}>Suited = upper-right, offsuit = lower-left, pairs = diagonal. Hover a cell for exact frequencies. Bars show the solved mix.</div>
      </div>
      <div className="panel">
        <h3>Cross-check with a real solver</h3>
        <div className="ext-links">
          <a className="ext-link" href="https://app.gtowizard.com/" target="_blank" rel="noopener">GTO Wizard — solutions <span className="arr">↗</span></a>
          <a className="ext-link" href="https://gtowizard.com/poker-preflop-charts/" target="_blank" rel="noopener">GTO Wizard — free preflop charts <span className="arr">↗</span></a>
          <a className="ext-link" href="https://wasm-postflop.pages.dev/" target="_blank" rel="noopener">WASM Postflop — free open-source solver <span className="arr">↗</span></a>
        </div>
        <div className="fb-note" style={{ marginTop: 10 }}>This grid is the app's own CFR solve (fixed sizings, ~100bb, open-or-fold). For exact frequencies across all sizings and for postflop, study in GTO Wizard or a full solver.</div>
      </div>
    </>
  );
}

/* ---------- Settings modal ---------- */
const DRILLS = [
  ["sb_open", "SB open (RFI)", "You're first-in on the button — open or fold."],
  ["bb_vs_open", "Defend BB vs open", "SB raises to 2.5bb — 3-bet, call, or fold."],
  ["sb_vs_3bet", "SB vs 3-bet", "You open, BB 3-bets to 9bb — 4-bet, call, or fold."],
  ["cbet_defense", "Defend vs c-bet", "BB call preflop, then face a ~½-pot flop c-bet."],
];
function SettingsModal({ open, onClose, styleKey, setStyle, stack, setStack, onReset, onDrill }) {
  if (!open) return null;
  const styles = window.GTO.STYLES;
  return (
    <div className="modal-bg" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
          <div>
            <h2>Table Settings</h2>
            <div className="msub">Pick an opponent to train against. Exploit styles teach you to deviate from GTO.</div>
          </div>
          <button className="iconbtn" onClick={onClose}>{"\u2715"}</button>
        </div>
        <div className="style-grid">
          {Object.keys(styles).map((k) => (
            <button key={k} className={"style-card" + (styleKey === k ? " on" : "")} onClick={() => setStyle(k)}>
              <div className="sn">
                {k === "gto" && <span className="dot" style={{ width: 8, height: 8, borderRadius: "50%", background: "var(--accent)" }} />}
                {styles[k].label}
              </div>
              <div className="sd">{styles[k].desc}</div>
            </button>
          ))}
        </div>
        <div className="field">
          <label>Starting stacks <span className="val">{stack} bb</span></label>
          <input type="range" min={20} max={200} step={5} value={stack} onChange={(e) => setStack(parseInt(e.target.value))} />
        </div>
        {onDrill && (
          <>
            <h2 style={{ fontSize: 15, marginTop: 18, marginBottom: 4 }}>Practice a spot</h2>
            <div className="msub">Jump straight into a specific decision and drill it against the solver.</div>
            <div className="drill-grid">
              {DRILLS.map((d) => (
                <button key={d[0]} className="drill-card" onClick={() => onDrill(d[0])}>
                  <div className="dn">{d[1]}</div>
                  <div className="dd">{d[2]}</div>
                </button>
              ))}
            </div>
          </>
        )}
        <div style={{ display: "flex", gap: 10, marginTop: 18 }}>
          <button className="ghost-btn" style={{ flex: 1 }} onClick={onReset}>Reset session stats</button>
          <button className="next-btn" style={{ flex: 1 }} onClick={onClose}>Done</button>
        </div>
      </div>
    </div>
  );
}

window.UI2 = { Header, CoachRail, SettingsModal };
