/* ============================================================
   Dinasty Control — EA Matrix screen
   ============================================================ */

/* heatmap helpers — blend a tint over the row's zebra base to a SOLID color,
   so sticky/frozen cells stay opaque and zebra stays visible under the heat. */
const ZEBRA = { even: [11, 58, 45], odd: [14, 69, 54] };
const GREEN = [54, 217, 143], RED = [242, 92, 98];
function blend(base, tint, a) {
  const c = base.map((b, i) => Math.round(b * (1 - a) + tint[i] * a));
  return `rgb(${c[0]},${c[1]},${c[2]})`;
}
function plHeat(pl, parity) {
  const base = ZEBRA[parity];
  const n = Math.max(-1, Math.min(1, pl / 2200));
  return n >= 0 ? blend(base, GREEN, 0.05 + 0.30 * n) : blend(base, RED, 0.05 + 0.30 * -n);
}
function pfHeat(pf, parity) {
  const base = ZEBRA[parity];
  const n = Math.max(-1, Math.min(1, (pf - 1) / 1.1));
  return n >= 0 ? blend(base, GREEN, 0.04 + 0.26 * n) : blend(base, RED, 0.06 + 0.34 * -n);
}

function Chip({ label, count, active, tone, onClick }) {
  return (
    <button className={`chip ${active ? "active" : ""} ${tone ? "chip-" + tone : ""}`} onClick={onClick}>
      {label}{count != null && <span className="chip-count">{count}</span>}
    </button>
  );
}

function WinBar({ wr }) {
  const tone = wr >= 55 ? "pos" : wr >= 45 ? "warn" : "neg";
  return (
    <div className="winwrap">
      <span className="win-val mono">{wr.toFixed(1)}%</span>
      <span className="win-track"><span className={`win-fill win-${tone}`} style={{ width: wr + "%" }}></span></span>
    </div>
  );
}

function Matrix({ rows, positions, onOpenSet }) {
  const [vps, setVps] = useState(null);
  const [acct, setAcct] = useState(null);
  const [mode, setMode] = useState(null);
  const [riskyOnly, setRiskyOnly] = useState(false);
  const [rec, setRec] = useState(null);
  const [q, setQ] = useState("");
  const [sel, setSel] = useState(null);

  const accounts = useMemo(() => [...new Set(rows.map((r) => r.account))], [rows]);

  const filtered = useMemo(() => {
    const qq = q.trim().toUpperCase();
    return rows.filter((r) => {
      if (vps && r.vps !== vps) return false;
      if (acct && r.account !== acct) return false;
      if (mode && r.mode !== mode) return false;
      if (rec && r.rec !== rec) return false;
      if (riskyOnly && !r.risky) return false;
      if (qq && !(r.id.includes(qq) || r.symbol.includes(qq))) return false;
      return true;
    });
  }, [rows, vps, acct, mode, rec, riskyOnly, q]);

  const counts = useMemo(() => {
    const c = { risky: 0, NORMAL: 0, REDUCE: 0, PAUSE: 0, REVERSAL: 0, byVps: {}, byAcct: {} };
    for (const r of rows) {
      if (r.risky) c.risky++;
      c[r.rec]++;
      if (r.mode === "REVERSAL") c.REVERSAL++;
      c.byVps[r.vps] = (c.byVps[r.vps] || 0) + 1;
      c.byAcct[r.account] = (c.byAcct[r.account] || 0) + 1;
    }
    return c;
  }, [rows]);

  const anyFilter = vps || acct || mode || rec || riskyOnly || q;
  const reset = () => { setVps(null); setAcct(null); setMode(null); setRec(null); setRiskyOnly(false); setQ(""); };

  return (
    <div className="screen screen-matrix">
      <div className="screen-head">
        <div className="screen-title">EA Matrix</div>
        <div className="screen-sub">Showing <b className="mono">{filtered.length}</b> of <span className="mono">{rows.length}</span> sets</div>
      </div>

      {/* filter rail */}
      <div className="filters">
        <div className="filter-grp">
          <span className="filter-lbl">VPS</span>
          <Chip label="VPS-1" count={counts.byVps["VPS-1"]} active={vps === "VPS-1"} onClick={() => setVps(vps === "VPS-1" ? null : "VPS-1")} />
          <Chip label="VPS-2" count={counts.byVps["VPS-2"]} active={vps === "VPS-2"} onClick={() => setVps(vps === "VPS-2" ? null : "VPS-2")} />
        </div>
        <div className="filter-grp">
          <span className="filter-lbl">Account</span>
          {accounts.map((a) => (
            <Chip key={a} label={a} active={acct === a} onClick={() => setAcct(acct === a ? null : a)} />
          ))}
        </div>
        <div className="filter-grp">
          <span className="filter-lbl">Mode</span>
          <Chip label="NORMAL" active={mode === "NORMAL"} onClick={() => setMode(mode === "NORMAL" ? null : "NORMAL")} />
          <Chip label="REVERSAL" count={counts.REVERSAL} active={mode === "REVERSAL"} onClick={() => setMode(mode === "REVERSAL" ? null : "REVERSAL")} />
        </div>
        <div className="filter-grp">
          <span className="filter-lbl">AI</span>
          <Chip label="REDUCE" count={counts.REDUCE} tone="reduce" active={rec === "REDUCE"} onClick={() => setRec(rec === "REDUCE" ? null : "REDUCE")} />
          <Chip label="PAUSE" count={counts.PAUSE} tone="pause" active={rec === "PAUSE"} onClick={() => setRec(rec === "PAUSE" ? null : "PAUSE")} />
        </div>
        <div className="filter-grp">
          <Chip label="⚠ Risky" count={counts.risky} tone="risk" active={riskyOnly} onClick={() => setRiskyOnly(!riskyOnly)} />
        </div>
        <div className="filter-spacer"></div>
        <input className="search mono" placeholder="filter SetID / symbol…" value={q} onChange={(e) => setQ(e.target.value)} />
        {anyFilter ? <button className="reset" onClick={reset}>Reset</button> : null}
      </div>

      {/* table */}
      <div className="tablewrap">
        <table className="matrix">
          <thead>
            <tr>
              <th className="c-set sticky-h sticky-c">SetID</th>
              <th className="c-vps sticky-h">VPS</th>
              <th className="c-acct sticky-h">Account</th>
              <th className="c-role sticky-h">Slot Role</th>
              <th className="c-mode sticky-h">Mode</th>
              <th className="c-pos sticky-h">Open Pos</th>
              <th className="c-pl sticky-h r">P/L</th>
              <th className="c-wr sticky-h r">Winrate</th>
              <th className="c-pf sticky-h r">PF</th>
              <th className="c-rec sticky-h">AI Recommendation</th>
            </tr>
          </thead>
          <tbody>
            {filtered.map((r, i) => (
              <tr key={r.id} className={`mrow clickable ${i % 2 ? "odd" : "even"} ${r.risky ? "risky" : ""} ${sel && sel.id === r.id ? "selrow" : ""}`} onClick={() => setSel(r)}>
                <td className="c-set sticky-c"><span className="setid mono">{r.id}</span></td>
                <td className="c-vps"><span className={`mini-dot ${r.vps === "VPS-2" ? "dot-warn" : "dot-ok"}`}></span>{r.vps}</td>
                <td className="c-acct mono dim">{r.account}</td>
                <td className="c-role"><span className={`role role-${r.role.toLowerCase()}`}>{r.role}</span></td>
                <td className="c-mode"><span className={`mode mode-${r.mode.toLowerCase()}`}>{r.mode}</span></td>
                <td className="c-pos">
                  {r.openPos > 0 ? (
                    <span className="pos">
                      <span className="pos-n mono">{r.openPos}</span>
                      <span className="pos-sym mono">{r.symbol}</span>
                      <span className={`pos-side ${r.side === "BUY" ? "pos-buy" : "pos-sell"}`}>{r.side === "BUY" ? "▲" : "▼"}</span>
                    </span>
                  ) : (
                    <span className="pos-flat mono">— flat</span>
                  )}
                </td>
                <td className="c-pl r heat" style={{ background: plHeat(r.pl, i % 2 ? "odd" : "even") }}><Num value={r.pl} money /></td>
                <td className="c-wr r"><WinBar wr={r.winrate} /></td>
                <td className="c-pf r heat" style={{ background: pfHeat(r.pf, i % 2 ? "odd" : "even") }}>
                  <span className={`mono pf ${r.pf < 1 ? "pf-bad" : ""}`}>{r.pf.toFixed(2)}</span>
                </td>
                <td className="c-rec"><RecPill rec={r.rec} /></td>
              </tr>
            ))}
            {filtered.length === 0 && (
              <tr><td colSpan="10" className="empty">No sets match the current filters.</td></tr>
            )}
          </tbody>
        </table>
      </div>

      {sel && <EADetail row={sel} positions={positions} onClose={() => setSel(null)} onOpenSet={onOpenSet} />}
    </div>
  );
}

/* ---------- EA detail slide-in panel (lightweight drill-down) ---------- */
function EADetail({ row, positions, onClose, onOpenSet }) {
  const pos = positions.filter((p) => p.set === row.id);
  const stat = (label, node) => (
    <div className="ead-stat"><span className="ead-stat-lbl">{label}</span><span className="ead-stat-val">{node}</span></div>
  );
  return (
    <>
      <div className="ead-scrim" onClick={onClose}></div>
      <aside className="ead">
        <div className="ead-head">
          <div className="ead-id">
            <span className="setid mono">{row.id}</span>
            <span className={`mode mode-${row.mode.toLowerCase()}`}>{row.mode}</span>
            {row.risky && <span className="ead-risk">⚠ RISK</span>}
          </div>
          <button className="ead-close" onClick={onClose}>✕</button>
        </div>

        <div className="ead-meta mono">
          <span><span className={`mini-dot ${row.vps === "VPS-2" ? "dot-warn" : "dot-ok"}`}></span>{row.vps}</span>
          <span className="dim">{row.account}</span>
          <span className={`role role-${row.role.toLowerCase()}`}>{row.role}</span>
        </div>

        <div className="ead-grid">
          {stat("P/L (today)", <Num value={row.pl} money />)}
          {stat("Floating", <Num value={row.floating} money />)}
          {stat("Profit Factor", <span className={`mono ${row.pf < 1 ? "pf-bad" : "pos"}`}>{row.pf.toFixed(2)}</span>)}
          {stat("Winrate", <span className="mono">{row.winrate.toFixed(1)}%</span>)}
          {stat("Drawdown", <span className="mono" style={{ color: row.drawdown > 9 ? "var(--warn)" : "var(--text)" }}>−{row.drawdown}%</span>)}
          {stat("Loss streak", <span className="mono" style={{ color: row.lossStreak >= 4 ? "var(--neg)" : "var(--text)" }}>{row.lossStreak}</span>)}
        </div>

        <div className="ead-ai">
          <span className="ead-stat-lbl">AI Recommendation</span>
          <div className="ead-ai-row"><RecPill rec={row.rec} /><span className="ead-why">{aiReason(row)}</span></div>
        </div>

        <div className="ead-pos-head">
          <span className="panel-title">Open Positions</span>
          <span className="panel-meta mono">{pos.length} active</span>
        </div>
        <div className="ead-pos">
          {pos.length === 0 && <div className="ead-flat mono">— no open positions (flat)</div>}
          {pos.map((p) => (
            <div key={p.ticket} className="ead-poscard">
              <div className="ead-poscard-l">
                <span className="mono">{p.symbol}</span>
                <span className={`mode ${p.side === "BUY" ? "side-buy" : "side-sell"}`}>{p.side === "BUY" ? "▲ BUY" : "▼ SELL"}</span>
                <span className="dim mono ead-lots">{p.lots.toFixed(2)} lots</span>
              </div>
              <div className="ead-poscard-r">
                <span className="dim mono ead-px">{p.entry} → {p.cur}</span>
                <Num value={p.pl} money />
              </div>
            </div>
          ))}
        </div>

        {pos.length > 0 && (
          <button className="ead-open" onClick={() => onOpenSet(row.id)}>Open in Positions blotter →</button>
        )}
      </aside>
    </>
  );
}
function aiReason(r) {
  if (r.rec === "PAUSE") return r.pf < 0.85 ? `PF ${r.pf.toFixed(2)} below floor — trading halted.` : `Drawdown ${r.drawdown}% — capital protection halt.`;
  if (r.rec === "REDUCE") return r.lossStreak >= 4 ? `Loss streak ${r.lossStreak} — lots scaled 0.5×.` : `Thin edge (PF ${r.pf.toFixed(2)}) — entries gated.`;
  return `Healthy: PF ${r.pf.toFixed(2)}, WR ${r.winrate.toFixed(0)}%. Full size.`;
}

window.Matrix = Matrix;
