/* =====================================================
   Betting Tracker — Analytics
   Everything on this page is computed live from the
   loaded record: CLV (%, units, closing prob), EV/edge,
   drawdown, Kelly staking discipline, calibration
   (Brier / log-loss / AUC), risk-adjusted metrics,
   Monte-Carlo bands, segment ROI, per-model evaluation
   and player-prop analytics. Math lives in quant.js.
   ===================================================== */

function oddsBucket(o) {
  if (o < 1.6) return "< 1.60";
  if (o < 2.0) return "1.60–2.00";
  if (o < 2.5) return "2.00–2.50";
  if (o < 3.5) return "2.50–3.50";
  return "3.50+";
}

/* small stat card (real values, no preview stripes) */
function AdvCard({ val, name, note, tone }) {
  return (
    <div className="trk-advcard trk-advcard--real">
      <div className={"trk-advcard__val" + (tone ? " " + tone : "")}>{val == null ? "\u2014" : val}</div>
      <div className="trk-advcard__name">{name}</div>
      <div className="trk-advcard__note">{note}</div>
    </div>
  );
}

/* labelled group divider — splits the page into basics / advanced */
function AnGroup({ label, sub }) {
  return (
    <div className="trk-angroup">
      <div className="trk-angroup__row"><span>{label}</span></div>
      {sub && <p>{sub}</p>}
    </div>
  );
}

function Analytics() {
  const { state, t, lang } = useTracker();
  const cur = state.settings.currency;
  const st = state.settings;

  /* scope filter — narrows every metric on this page */
  const [flt, setFlt] = useState({ source: "all", sport: "", league: "", market: "", model: "", book: "", result: "", tag: "", day: "" });
  const setF = (k, v) => setFlt((p) => ({ ...p, [k]: v }));
  const fltActive = flt.source !== "all" || flt.sport || flt.league || flt.market || flt.model || flt.book || flt.result || flt.tag || flt.day;
  const clearF = () => setFlt({ source: "all", sport: "", league: "", market: "", model: "", book: "", result: "", tag: "", day: "" });

  const sportOpts = state.settings.sports || TRK.SPORTS;
  const bookOpts = TRK.bookOptions(state);
  const leagues = state.bets.map((b) => b.league).filter((v, i, a) => v && a.indexOf(v) === i);
  const dayOpts = [1, 2, 3, 4, 5, 6, 0].map((i) => ({
    value: String(i),
    label: new Date(Date.UTC(2024, 0, 7 + i)).toLocaleDateString(lang === "pt" ? "pt-BR" : "en-US", { weekday: "long", timeZone: "UTC" })
  }));

  const bets = state.bets.filter((b) => {
    if (flt.source === "own" && TRK.betSource(b) !== "own") return false;
    if (flt.source === "tipsters" && TRK.betSource(b) !== "tipster") return false;
    if (flt.model && b.tipster !== flt.model) return false;
    if (flt.sport && b.sport !== flt.sport) return false;
    if (flt.league && b.league !== flt.league) return false;
    if (flt.market && b.market !== flt.market) return false;
    if (flt.book && b.book !== flt.book) return false;
    if (flt.result && b.result !== flt.result) return false;
    if (flt.tag && !(b.tags || []).includes(flt.tag)) return false;
    if (flt.day !== "" && String(new Date(b.date + "T00:00:00").getDay()) !== flt.day) return false;
    return true;
  });
  const settled = bets.filter(TRK.isSettled);

  /* CLV */
  const clv = TRK.avgCLV(bets);
  const beat = TRK.beatCloseRate(bets);
  const withClose = bets.filter((b) => TRK.betCLV(b) != null).length;
  const clvMoney = TRKQ.clvMoney(bets);
  const closeProb = TRKQ.avgCloseProb(bets);

  /* EV */
  const edges = bets.map(TRK.betEdge).filter((v) => v != null);
  const avgEdge = edges.length ? TRK.round(edges.reduce((a, b) => a + b, 0) / edges.length, 2) : null;
  const evs = bets.map(TRK.betEV).filter((v) => v != null);
  const avgEV = evs.length ? TRK.round(evs.reduce((a, b) => a + b, 0) / evs.length, 2) : null;
  const sum = TRK.summarize(bets);
  const realRoi = sum.roi;

  /* bankroll, drawdown, risk */
  const startBank = TRK.netDeposits(state);
  const eq = TRK.equitySeries(bets, startBank);
  const bank = TRK.bankrollBalance(state);
  const risk = TRKQ.riskStats(bets, bank);
  const cal = TRKQ.calib(bets);
  const kel = TRKQ.kellyStats(bets, state, st.kellyFraction);

  /* Monte Carlo — resamples the scoped record */
  const mc = React.useMemo(
    () => TRKQ.monteCarlo(bets, bank, 200, 400),
    [state.bets, flt.source, flt.model, flt.sport, flt.market, bank]
  );

  /* segments */
  const [segMode, setSegMode] = useState("sport");
  const [segSort, setSegSort] = useState("roi");
  const keyFns = {
    sport: (b) => b.sport || "\u2014", league: (b) => b.league || "\u2014",
    market: (b) => b.market || "\u2014", odds: (b) => oddsBucket(b.odds),
    tipster: (b) => b.tipster || "\u2014", book: (b) => b.book || "\u2014",
    day: (b) => TRKQ.dayName(b.date, lang),
    tod: (b) => t(TRKQ.todKey(b.time)),
    favdog: (b) => t(b.odds < 2 ? "seg.fav" : "seg.dog"),
    live: (b) => t(b.live ? "seg.live" : "seg.pre")
  };
  const segOpts = [
    { value: "sport", label: t("an.by.sport") }, { value: "league", label: t("an.by.league") },
    { value: "market", label: t("an.by.market") }, { value: "odds", label: t("an.by.odds") },
    { value: "tipster", label: t("an.by.tipster") }, { value: "book", label: t("an.by.book") },
    { value: "day", label: t("an.by.day") }, { value: "tod", label: t("an.by.tod") },
    { value: "favdog", label: t("an.by.favdog") }, { value: "live", label: t("an.by.live") }
  ];
  const segRows = TRK.groupProfit(bets, keyFns[segMode]).sort((a, b) => b[segSort] - a[segSort]);

  /* model evaluation — full record per model */
  const modelRows = state.models.map((m) => {
    const mb = state.bets.filter((b) => b.tipster === m.name);
    const sm = TRK.summarize(mb);
    const mevs = mb.map(TRK.betEV).filter((v) => v != null);
    const medges = mb.map(TRK.betEdge).filter((v) => v != null);
    const mrisk = TRKQ.riskStats(mb, 0);
    const mcal = TRKQ.calib(mb);
    return {
      name: m.name, n: sm.settledCount, roi: sm.roi, profit: sm.profit,
      ev: mevs.length ? TRK.round(mevs.reduce((a, b) => a + b, 0) / mevs.length, 1) : null,
      clv: TRK.avgCLV(mb),
      edge: medges.length ? TRK.round(medges.reduce((a, b) => a + b, 0) / medges.length, 1) : null,
      sharpe: mrisk.sharpe, pf: mrisk.profitFactor, maxDD: TRKQ.maxDDMoney(mb),
      brier: mcal.brier, logloss: mcal.logloss, auc: mcal.auc
    };
  }).filter((r) => r.n > 0).sort((a, b) => b.roi - a.roi);

  /* player props */
  const props_ = TRKQ.propStats(bets);
  const propRows = TRK.groupProfit(bets.filter((b) => b.player), (b) => b.player).sort((a, b) => b.roi - a.roi);

  const num = (v, dp) => (v == null ? null : v.toFixed(dp == null ? 2 : dp));
  const tone = (v) => (v == null ? "" : v >= 0 ? "trk-pos" : "trk-neg");

  return (
    <div className="trk-page">
      <SectionHead title={t("an.title")} sub={t("an.sub")}
        right={fltActive ? <span className="trk-scopetag">{settled.length} {t("an.scoped")}</span> : null} />

      {/* scope filter */}
      <Panel pad={16} className="trk-anfilter">
        <div className="trk-anfilter__top">
          <span className="trk-anfilter__lbl"><Icon name="filter" size={15} /> {t("an.filter")}</span>
          <Segmented size="sm" value={flt.source} onChange={(v) => setF("source", v)}
            options={[{ value: "all", label: t("an.src.all") }, { value: "own", label: t("an.src.own") }, { value: "tipsters", label: t("an.src.tipsters") }]} />
          {fltActive && <button className="trk-textlink trk-textlink--sm" onClick={clearF}>{t("bets.clear")}</button>}
        </div>
        <div className="trk-anfilter__grid">
          <Select value={flt.model} onChange={(v) => setF("model", v)} options={state.models.map((m) => m.name)} placeholder={t("an.all.model")} />
          <Select value={flt.sport} onChange={(v) => setF("sport", v)} options={sportOpts} placeholder={t("an.all.sport")} />
          <Select value={flt.league} onChange={(v) => setF("league", v)} options={leagues} placeholder={t("an.all.league")} />
          <Select value={flt.market} onChange={(v) => setF("market", v)} options={TRK.marketOptions(state)} placeholder={t("an.all.market")} />
          <Select value={flt.book} onChange={(v) => setF("book", v)} options={bookOpts} placeholder={t("an.all.book")} />
          <Select value={flt.result} onChange={(v) => setF("result", v)} options={TRK.RESULTS.map((r) => ({ value: r, label: t("res." + r) }))} placeholder={t("an.all.result")} />
          <Select value={flt.tag} onChange={(v) => setF("tag", v)} options={TRK.TAGS} placeholder={t("an.all.tag")} />
          <Select value={flt.day} onChange={(v) => setF("day", v)} options={dayOpts} placeholder={t("an.all.day")} />
        </div>
      </Panel>

      {/* ===== THE BASICS ===== */}
      <AnGroup label={t("an.grp.basics")} sub={t("an.grp.basics.sub")} />

      {/* overview + drawdown */}
      <div className="trk-grid2">
        <Panel pad={24} className="trk-metricpanel">
          <div className="trk-metricpanel__head"><div className="icon-tile"><Icon name="check" size={18} /></div>
            <div><h3>{t("an.basic.title")}</h3><p>{t("an.basic.sub")}</p></div></div>
          <div className="trk-minigrid2">
            <AdvCard val={sum.winRate + "%"} name={t("dash.winrate")} note={sum.won + "\u2013" + sum.lost + (sum.push ? "\u2013" + sum.push : "")} />
            <AdvCard val={TRK.fmtMoney(sum.profit, cur)} name={t("dash.profit")} note={"ROI " + TRK.fmtSignedPct(sum.roi, 1)} tone={tone(sum.profit)} />
            <AdvCard val={TRK.fmtMoney(sum.staked, cur)} name={t("dash.turnover")} note={sum.settledCount + " " + t("dash.settled").toLowerCase()} />
            <AdvCard val={TRK.fmtOdds(sum.avgOdds)} name={t("dash.avgodds")} note={t("an.basic.avgstake") + " " + TRK.fmtMoney(sum.settledCount ? TRK.round(sum.staked / sum.settledCount, 0) : 0, cur)} />
          </div>
        </Panel>

        <Panel pad={24} className="trk-metricpanel">
          <div className="trk-metricpanel__head"><div className="icon-tile"><Icon name="analytics" size={18} /></div>
            <div><h3>{t("an.dd.title")}</h3><p>{t("an.dd.sub")}</p></div></div>
          <div className="trk-metricpanel__big">
            <span className="trk-neg">−{eq.maxDrawdown}%</span>
            <small>{t("an.dd.max")}</small>
          </div>
          <div className="trk-metricpanel__rows">
            <div><span>{t("an.dd.peak")}</span><b>{TRK.fmtMoney(eq.peak, cur)}</b></div>
            <div><span>{t("an.dd.current")}</span><b>{eq.peak ? TRK.fmtSignedPct(-(eq.peak - eq.end) / eq.peak * 100, 1) : "\u2014"}</b></div>
          </div>
          {eq.points.length > 1 ? <EquityCurve series={eq} currency={cur} height={110} /> : <Placeholder label="needs settled bets" height={110} />}
        </Panel>
      </div>

      {/* segment breakdown — where the profit comes from */}
      <Panel pad={26}>
        <SectionHead title={t("an.perf.title")} sub={t("an.perf.sub")}
          right={<>
            <Select value={segMode} onChange={setSegMode} options={segOpts} />
            <Segmented size="sm" value={segSort} onChange={setSegSort}
              options={[{ value: "roi", label: t("an.roi") }, { value: "profit", label: t("an.profit") }]} />
          </>} />
        {segRows.length ? <SegmentBars rows={segRows} currency={cur} valueKey={segSort} metric={segSort} dual /> : <Placeholder label="no settled bets" height={120} />}
      </Panel>

      {/* ===== ADVANCED ===== */}
      <AnGroup label={t("an.grp.adv")} sub={t("an.grp.adv.sub")} />

      {/* CLV + EV */}
      <div className="trk-grid2">
        <Panel pad={24} className="trk-metricpanel">
          <div className="trk-metricpanel__head"><div className="icon-tile"><Icon name="target" size={18} /></div>
            <div><h3>{t("an.clv.title")}</h3><p>{t("an.clv.sub")}</p></div></div>
          <div className="trk-metricpanel__big">
            <span className={clv != null && clv >= 0 ? "trk-pos" : "trk-neg"}>{clv == null ? "\u2014" : TRK.fmtSignedPct(clv, 2)}</span>
            <small>{t("an.clv.avg")} · {withClose}/{bets.length} {t("an.clv.bets")}</small>
          </div>
          <div className="trk-metricpanel__rows">
            <div><span>{t("an.clv.beat")}</span><b>{beat == null ? "\u2014" : beat + "%"}</b></div>
            <div><span>{t("an.clv.units")}</span><b className={clvMoney == null ? "" : tone(clvMoney)}>{clvMoney == null ? "\u2014" : TRK.fmtUnits(TRK.round(clvMoney / st.unitSize, 2))}</b></div>
            <div><span>{t("an.clv.closeprob")}</span><b>{closeProb == null ? "\u2014" : closeProb + "%"}</b></div>
          </div>
          <CLVBars bets={bets} height={110} />
        </Panel>

        <Panel pad={24} className="trk-metricpanel">
          <div className="trk-metricpanel__head"><div className="icon-tile"><Icon name="chart" size={18} /></div>
            <div><h3>{t("an.ev.title")}</h3><p>{t("an.ev.sub")}</p></div></div>
          <div className="trk-metricpanel__big">
            <span className={avgEV != null && avgEV >= 0 ? "trk-pos" : "trk-neg"}>{avgEV == null ? "\u2014" : TRK.fmtSignedPct(avgEV, 1)}</span>
            <small>{t("an.ev.ev")}</small>
          </div>
          <div className="trk-metricpanel__rows">
            <div><span>{t("an.ev.edge")}</span><b className={tone(avgEdge)}>{avgEdge == null ? "\u2014" : TRK.fmtSignedPct(avgEdge, 2)}</b></div>
            <div><span>{t("an.ev.real")}</span><b className={tone(realRoi)}>{TRK.fmtSignedPct(realRoi, 1)}</b></div>
          </div>
          <div className="trk-evbar">
            <div className="trk-evbar__row"><label>{t("an.ev.ev")}</label><div className="trk-evbar__track"><div className="trk-evbar__fill" style={{ width: Math.min(100, Math.abs(avgEV || 0) * 6) + "%" }}></div></div></div>
            <div className="trk-evbar__row"><label>{t("an.ev.real")}</label><div className="trk-evbar__track"><div className="trk-evbar__fill is-alt" style={{ width: Math.min(100, Math.abs(realRoi) * 6) + "%" }}></div></div></div>
          </div>
        </Panel>
      </div>

      {/* Kelly staking + model calibration */}
      <div className="trk-grid2">
        <Panel pad={24} className="trk-metricpanel">
          <div className="trk-metricpanel__head"><div className="icon-tile"><Icon name="wallet" size={18} /></div>
            <div><h3>{t("an.kelly.title")}</h3><p>{t("an.kelly.sub")}</p></div></div>
          {kel.n ? (
            <React.Fragment>
              <div className="trk-metricpanel__big">
                <span className={kel.avgActual != null && kel.avgFull != null && kel.avgActual > kel.avgFull ? "trk-neg" : "trk-pos"}>
                  {kel.avgActual == null ? "\u2014" : kel.avgActual.toFixed(2) + "%"}</span>
                <small>{t("an.kelly.actual")} · {t("an.kelly.of")}</small>
              </div>
              <div className="trk-metricpanel__rows">
                <div><span>{t("an.kelly.full")}</span><b>{num(kel.avgFull)}%</b></div>
                <div><span>{t("an.kelly.target")} ({st.kellyFraction}×)</span><b>{num(kel.avgTarget)}%</b></div>
                <div><span>{t("an.kelly.over")}</span><b className={kel.overShare > 30 ? "trk-neg" : "trk-pos"}>{kel.overShare}%</b></div>
                <div><span>{t("an.kelly.overavg")}</span><b>{kel.avgOver == null ? "\u2014" : "+" + kel.avgOver.toFixed(2) + " pp"}</b></div>
                <div><span>{t("an.kelly.underavg")}</span><b>{kel.avgUnder == null ? "\u2014" : "\u2212" + kel.avgUnder.toFixed(2) + " pp"}</b></div>
              </div>
            </React.Fragment>
          ) : <EmptyState icon="wallet" title={t("an.kelly.none")} />}
        </Panel>

        <Panel pad={24} className="trk-metricpanel">
          <div className="trk-metricpanel__head"><div className="icon-tile"><Icon name="target" size={18} /></div>
            <div><h3>{t("an.cal.title")}</h3><p>{t("an.cal.sub")}</p></div></div>
          {cal.brier != null ? (
            <React.Fragment>
              <div className="trk-calgrid">
                <AdvCard val={num(cal.brier, 3)} name={t("an.cal.brier")} note={t("an.cal.brier.n")}
                  tone={cal.brier < 0.25 ? "trk-pos" : "trk-neg"} />
                <AdvCard val={num(cal.logloss, 3)} name={t("an.cal.logloss")} note={t("an.cal.logloss.n")}
                  tone={cal.logloss < 0.693 ? "trk-pos" : "trk-neg"} />
                <AdvCard val={cal.auc == null ? null : num(cal.auc, 3)} name={t("an.cal.auc")} note={t("an.cal.auc.n")}
                  tone={cal.auc != null && cal.auc > 0.5 ? "trk-pos" : "trk-neg"} />
              </div>
              <div className="trk-advnote"><Icon name="check" size={13} /> {cal.n} {t("an.cal.n")}</div>
            </React.Fragment>
          ) : <EmptyState icon="target" title={t("an.cal.none")} />}
        </Panel>
      </div>

      {/* risk & risk-adjusted — real, computed */}
      <Panel pad={26}>
        <SectionHead title={t("an.risk.title")} sub={t("an.risk.sub")} />
        <div className="trk-advgrid">
          <AdvCard val={num(risk.sharpe)} name={t("an.risk.sharpe")} note={t("an.risk.sharpe.n")} tone={tone(risk.sharpe)} />
          <AdvCard val={num(risk.sortino)} name={t("an.risk.sortino")} note={t("an.risk.sortino.n")} tone={tone(risk.sortino)} />
          <AdvCard val={num(risk.profitFactor)} name={t("an.risk.pf")} note={t("an.risk.pf.n")}
            tone={risk.profitFactor == null ? "" : risk.profitFactor >= 1 ? "trk-pos" : "trk-neg"} />
          <AdvCard val={num(risk.recovery)} name={t("an.risk.recovery")} note={t("an.risk.recovery.n")} tone={tone(risk.recovery)} />
          <AdvCard val={num(risk.infoRatio)} name={t("an.risk.ir")} note={t("an.risk.ir.n")} tone={tone(risk.infoRatio)} />
          <AdvCard val={risk.ror == null ? null : (risk.ror * 100 < 0.1 ? "< 0.1%" : (risk.ror * 100).toFixed(1) + "%")}
            name={t("an.risk.ror")} note={t("an.risk.ror.n")}
            tone={risk.ror == null ? "" : risk.ror <= 0.05 ? "trk-pos" : "trk-neg"} />
          <AdvCard val={risk.vol == null ? null : Math.round(risk.vol * 100) + "%"} name={t("an.risk.vol")} note={t("an.risk.vol.n")} />
          <AdvCard val={risk.lossStreak == null ? null : risk.lossStreak + "L"} name={t("an.risk.streak")} note={t("an.risk.streak.n")} />
        </div>
        {risk.n < 10 && <div className="trk-advnote"><Icon name="lock" size={13} /> {t("an.risk.needs")}</div>}
      </Panel>

      {/* Monte Carlo */}
      <Panel pad={26}>
        <SectionHead title={t("an.mc.title")} sub={t("an.mc.sub")} />
        {mc ? (
          <div className="trk-mc">
            <div>
              <MCBands mc={mc} currency={cur} height={250} startLab={t("an.mc.today")} betsLab={t("an.mc.bets")} />
              <div className="trk-mc__legend">
                <span><i style={{ background: "rgba(58,208,127,0.14)" }}></i>{t("an.mc.band")}</span>
                <span><i style={{ background: "rgba(58,208,127,0.32)" }}></i>{t("an.mc.mid")}</span>
                <span><i style={{ background: "#3ad07f", height: 3, borderRadius: 2 }}></i>{t("an.mc.medianline")}</span>
              </div>
            </div>
            <div className="trk-mc__rows">
              <div className="trk-mc__row"><span>{t("an.mc.median")}</span><b className={tone(mc.finals.p50 - mc.start)}>{TRK.fmtMoney(mc.finals.p50, cur)}</b></div>
              <div className="trk-mc__row"><span>{t("an.mc.p5")}</span><b className="trk-neg">{TRK.fmtMoney(mc.finals.p5, cur)}</b></div>
              <div className="trk-mc__row"><span>{t("an.mc.p95")}</span><b className="trk-pos">{TRK.fmtMoney(mc.finals.p95, cur)}</b></div>
              <div className="trk-mc__row"><span>{t("an.mc.pprofit")}</span><b className={mc.probProfit >= 50 ? "trk-pos" : "trk-neg"}>{mc.probProfit}%</b></div>
              <div className="trk-mc__row"><span>{t("an.mc.pruin")}</span><b className={mc.probRuin <= 5 ? "trk-pos" : "trk-neg"}>{mc.probRuin}%</b></div>
            </div>
          </div>
        ) : <EmptyState icon="analytics" title={t("an.mc.needs")} />}
      </Panel>

      {/* model evaluation */}
      <Panel pad={26}>
        <SectionHead title={t("an.model.title")} sub={t("an.model.sub")} />
        {modelRows.length ? (
          <div className="table-wrap trk-tablewrap">
            <table className="table trk-table">
              <thead>
                <tr>
                  <th style={{ textAlign: "left" }}>{t("col.tipster")}</th>
                  <th>{t("an.n")}</th>
                  <th>{t("an.roi")}</th>
                  <th>{t("an.col.ev")}</th>
                  <th>{t("an.profit")}</th>
                  <th>CLV</th>
                  <th>{t("an.ev.edge")}</th>
                  <th>{t("an.col.sharpe")}</th>
                  <th>{t("an.col.pf")}</th>
                  <th>{t("an.col.dd")}</th>
                  <th>{t("an.col.brier")}</th>
                  <th>{t("an.col.ll")}</th>
                  <th style={{ textAlign: "right" }}>{t("an.col.auc")}</th>
                </tr>
              </thead>
              <tbody>
                {modelRows.map((r) => (
                  <tr key={r.name} style={{ cursor: "default" }}>
                    <td style={{ textAlign: "left", fontWeight: 600, whiteSpace: "nowrap" }}>{r.name}</td>
                    <td className="trk-cellsub2">{r.n}</td>
                    <td style={{ fontWeight: 700 }} className={tone(r.roi)}>{TRK.fmtSignedPct(r.roi, 1)}</td>
                    <td className={r.ev == null ? "trk-cellsub2" : tone(r.ev)}>{r.ev == null ? "\u2014" : TRK.fmtSignedPct(r.ev, 1)}</td>
                    <td className={tone(r.profit)}>{TRK.fmtMoney(r.profit, cur)}</td>
                    <td className={r.clv == null ? "trk-cellsub2" : tone(r.clv)}>{r.clv == null ? "\u2014" : TRK.fmtSignedPct(r.clv, 2)}</td>
                    <td className={r.edge == null ? "trk-cellsub2" : tone(r.edge)}>{r.edge == null ? "\u2014" : TRK.fmtSignedPct(r.edge, 1)}</td>
                    <td className={r.sharpe == null ? "trk-cellsub2" : tone(r.sharpe)}>{r.sharpe == null ? "\u2014" : r.sharpe.toFixed(2)}</td>
                    <td className={r.pf == null ? "trk-cellsub2" : r.pf >= 1 ? "trk-pos" : "trk-neg"}>{r.pf == null ? "\u2014" : r.pf.toFixed(2)}</td>
                    <td className={r.maxDD > 0 ? "trk-neg" : "trk-cellsub2"}>{r.maxDD > 0 ? "\u2212" + TRK.fmtMoney(r.maxDD, cur).replace("\u2212", "") : "\u2014"}</td>
                    <td className="trk-cellsub2">{r.brier == null ? "\u2014" : r.brier.toFixed(3)}</td>
                    <td className="trk-cellsub2">{r.logloss == null ? "\u2014" : r.logloss.toFixed(3)}</td>
                    <td style={{ textAlign: "right" }} className="trk-cellsub2">{r.auc == null ? "\u2014" : r.auc.toFixed(3)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ) : <Placeholder label="no models with settled bets" height={100} />}
      </Panel>

      {/* player props */}
      <Panel pad={26} className="trk-metricpanel">
        <div className="trk-metricpanel__head"><div className="icon-tile"><Icon name="target" size={18} /></div>
          <div><h3>{t("an.props.title")}</h3><p>{t("an.props.sub")}</p></div></div>
        {props_.n ? (
          <React.Fragment>
            <div className="trk-propstats">
              <AdvCard val={props_.n} name={t("an.props.bets")} note={"ROI " + TRK.fmtSignedPct(props_.roi, 1)} tone={tone(props_.roi)} />
              <AdvCard val={props_.lineMove == null ? null : TRK.fmtSignedPct(props_.lineMove, 2)} name={t("an.props.linemove")} note={t("an.clv.sub")} tone={tone(props_.lineMove)} />
              <AdvCard val={props_.projDiff == null ? null : (props_.projDiff >= 0 ? "+" : "\u2212") + Math.abs(props_.projDiff).toFixed(1)} name={t("an.props.projdiff")} note={t("form.projection")} />
              <AdvCard val={props_.projErr == null ? null : "\u00b1" + props_.projErr.toFixed(1)} name={t("an.props.projerr")} note={props_.withProj + " " + t("an.props.hint")} />
            </div>
            {propRows.length > 0 && <SegmentBars rows={propRows} currency={cur} valueKey="roi" metric="roi" />}
          </React.Fragment>
        ) : <EmptyState icon="bets" title={t("an.props.none")} />}
      </Panel>
    </div>
  );
}

Object.assign(window, { Analytics });
