// Statasaurus dashboard — main app
const { useState, useMemo, useEffect } = React;

// Bot channel — subscribers join here:
const TELEGRAM_URL = "https://t.me/STATASAURUS_BOT";

// Join-via-Telegram CTA — pixel button, sized to sit beside the THIS WEEK / ALL TIME toggle
function TelegramButton() {
  return (
    <a className="tg-btn" href={TELEGRAM_URL} target="_blank" rel="noopener noreferrer">
      <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M2 21l21-9L2 3v7l15 2-15 2z" /></svg>
      Join via Telegram
    </a>);
}

// ------------------------------------------------------------------
// Tweaks defaults
// ------------------------------------------------------------------
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "density": "comfortable",
  "pixel": "medium"
} /*EDITMODE-END*/;

// ------------------------------------------------------------------
// Sidebar
// ------------------------------------------------------------------
function Sidebar({ view, setView, selectedWeekId, setSelectedWeekId }) {
  const months = window.STATTO.MONTHS;
  const allTime = window.STATTO.ALL_TIME;
  // Mobile: history list is collapsed by default; the brand row toggles it.
  // On desktop the rule that hides .side-scroll is media-gated, so this has no effect.
  const [historyOpen, setHistoryOpen] = useState(false);

  return (
    <aside className={`sidebar ${historyOpen ? "history-open" : "history-closed"}`}>
      <button
        type="button"
        className="brand brand-toggle"
        onClick={() => setHistoryOpen((v) => !v)}
        aria-expanded={historyOpen}
        aria-controls="sidebar-history">
        <MascotPixel size={40} />
        <div className="brand-text">
          <div className="pixel brand-name px-wordmark">STATTO</div>
          <div className="brand-tag">STATASAURUS DASHBOARD</div>
        </div>
        <span className="brand-toggle-hint" aria-hidden="true">
          <span className="pixel brand-toggle-label">ALERT HISTORY</span>
          <span className="brand-chevron">▾</span>
        </span>
      </button>

      <div className="side-scroll" id="sidebar-history">
        <div className="side-section-label">ALERT HISTORY</div>
        {months.map((m) =>
        <div key={m.key}>
            <div className="month-row">
              <span className="m-name">{m.label}</span>
              <span className="m-stat">
                {m.summary.total} alerts · {Math.round(m.summary.strike * 100)}%
              </span>
            </div>
            {m.weeks.map((w) => {
            const s = window.STATTO.summarize(w.alerts);
            const pct = Math.round(s.strike * 100);
            const cls = pct >= 65 ? "good" : pct < 50 ? "bad" : "";
            const active = view === "history" && selectedWeekId === w.id;
            return (
              <div
                key={w.id}
                className={`week-row ${active ? "active" : ""}`}
                onClick={() => {setView("history");setSelectedWeekId(w.id);}}>
                
                  <div>
                    <div className="wk-label">
                      {w.isCurrent ? "This Week" : w.label}
                    </div>
                    <div className="wk-sub">
                      {w.isCurrent ? w.label : `${s.total} alerts`}
                    </div>
                  </div>
                  <span className={`wk-badge ${cls}`}>{pct}%</span>
                </div>);

          })}
          </div>
        )}
      </div>
    </aside>);

}

// ------------------------------------------------------------------
// Week view (current OR a past week)
// ------------------------------------------------------------------
function WeekView({ week, isCurrent }) {
  const alerts = week.alerts;
  const s = window.STATTO.summarize(alerts);
  const days = window.STATTO.dailyBreakdown(alerts, week.start);

  const corners = alerts.filter((a) => a.type === "Corners");
  const goals = alerts.filter((a) => a.type === "Goals");
  const cs = window.STATTO.summarize(corners);
  const gs = window.STATTO.summarize(goals);

  const strikePct = Math.round(s.strike * 100);
  const wPct = s.total ? Math.round(s.w / s.total * 100) : 0;

  return (
    <div>
      {/* Hero KPI band — mirrors the all-time layout */}
      <div className="bigstat-grid">
        <div className="hero" style={{ gridColumn: "span 2" }}>
          <div className="hero-label" style={{ fontSize: "8px" }}>{isCurrent ? "THIS WEEK · WIN + REFUND RATE" : "WIN + REFUND RATE"}</div>
          <div className="hero-num px-num" style={{ fontSize: "60px" }}>{strikePct}%</div>
        </div>

        <div className="card">
          <div className="card-head">
            <span className="col-tag corners">CORNERS</span>
          </div>
          <div className="kpi">
            <div className="kpi-num px-num" style={{ color: "var(--blue)" }}>{Math.round(cs.strike * 100)}%</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <span className="col-tag goals">GOALS</span>
          </div>
          <div className="kpi">
            <div className="kpi-num px-num" style={{ color: "var(--pink)" }}>{Math.round(gs.strike * 100)}%</div>
          </div>
        </div>
      </div>

      {/* W / R / L / Alerts breakdown tiles */}
      <div className="bigstat-grid">
        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">WINS</div>
            </div>
            <span className="dot win" />
          </div>
          <div className="kpi win">
            <div className="kpi-num px-num">{s.w}</div>
            <div className="kpi-foot">{s.total ? Math.round(s.w / s.total * 100) : 0}% of alerts</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">REFUNDS</div>
            </div>
            <span className="dot refund" />
          </div>
          <div className="kpi refund">
            <div className="kpi-num px-num">{s.r}</div>
            <div className="kpi-foot">{s.total ? Math.round(s.r / s.total * 100) : 0}% of alerts</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">LOSSES</div>
            </div>
            <span className="dot loss" />
          </div>
          <div className="kpi loss">
            <div className="kpi-num px-num">{s.l}</div>
            <div className="kpi-foot">{s.total ? Math.round(s.l / s.total * 100) : 0}% of alerts</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">ALERTS</div>
            </div>
            <span className="dot" style={{ background: "var(--ink)" }} />
          </div>
          <div className="kpi">
            <div className="kpi-num px-num">{s.total}</div>
            <div className="kpi-foot">{isCurrent ? "this week so far" : "this week"}</div>
          </div>
        </div>
      </div>

      {/* Two-column: per-type outcome splits ABOVE alert lists */}
      <div className="grid-bottom alert-pair" style={{ marginBottom: "var(--gap)" }}>
        <div style={{ display: "flex", flexDirection: "column", gap: "var(--gap)" }}>
          <div className="card">
            <div className="card-head">
              <div>
                <div className="card-title px px-heading">CORNERS · OUTCOME SPLIT</div>
              </div>
              <span className="col-tag corners" style={{ padding: "4px 6px", fontSize: 8 }}>C</span>
            </div>
            <Donut w={cs.w} r={cs.r} l={cs.l} />
          </div>
          <AlertColumn title="CORNERS" kind="corners" alerts={corners} />
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: "var(--gap)" }}>
          <div className="card">
            <div className="card-head">
              <div>
                <div className="card-title px px-heading">GOALS · OUTCOME SPLIT</div>
              </div>
              <span className="col-tag goals" style={{ padding: "4px 6px", fontSize: 8 }}>G</span>
            </div>
            <Donut w={gs.w} r={gs.r} l={gs.l} />
          </div>
          <AlertColumn title="GOALS" kind="goals" alerts={goals} />
        </div>
      </div>

      <PnLCard alerts={alerts} />

      <LineBreakdownCard alerts={alerts} />

      {/* League performance */}
      <div className="card" style={{ marginTop: "var(--gap)" }}>
        <div className="card-head">
          <div>
            <div className="card-title px px-heading">LEAGUE PERFORMANCE</div>
          </div>
        </div>
        <LeagueBoard alerts={alerts} />
      </div>

      <StreaksCard alerts={alerts} />
    </div>);

}

// ------------------------------------------------------------------
// All-time view
// ------------------------------------------------------------------
function AllTimeView() {
  const all = window.STATTO.ALL_ALERTS;
  const summary = window.STATTO.ALL_TIME;
  const weeks = window.STATTO.ALL_WEEKS;
  const months = window.STATTO.MONTHS;

  const corners = all.filter((a) => a.type === "Corners");
  const goals = all.filter((a) => a.type === "Goals");
  const cs = window.STATTO.summarize(corners);
  const gs = window.STATTO.summarize(goals);

  // Day-of-week aggregation across all alerts
  const dowLabels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
  const dowRows = dowLabels.map((label, idx) => {
    const subset = all.filter((a) => (a.ts.getDay() + 6) % 7 === idx);
    return { label, ...window.STATTO.summarize(subset) };
  });

  // Weekly cumulative line — running win+refund rate from oldest -> newest
  const orderedWeeks = [...weeks].reverse(); // oldest first
  let cumW = 0,cumR = 0,cumL = 0;
  const weeklyPoints = orderedWeeks.map((w) => {
    const s = window.STATTO.summarize(w.alerts);
    cumW += s.w;cumR += s.r;cumL += s.l;
    const settled = cumW + cumR + cumL;
    return {
      label: w.label,
      weekly: s.strike,
      cum: settled ? (cumW + cumR) / settled : null,
      total: s.total,
      w: s.w, r: s.r, l: s.l
    };
  });

  // Months for table
  const wPct = summary.total ? Math.round(summary.w / summary.total * 100) : 0;

  return (
    <div>
      {/* Big stats band */}
      <div className="bigstat-grid">
        <div className="hero" style={{ gridColumn: "span 2" }}>
          <div className="hero-label" style={{ fontSize: "8px" }}>ALL TIME · WIN & REFUND RATE</div>
          <div className="hero-num px-num" style={{ fontSize: "60px" }}>{Math.round(summary.strike * 100)}%</div>
        </div>

        <div className="card">
          <div className="card-head">
            <span className="col-tag corners">CORNERS</span>
          </div>
          <div className="kpi">
            <div className="kpi-num px-num" style={{ color: "var(--blue)" }}>{Math.round(cs.strike * 100)}%</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <span className="col-tag goals">GOALS</span>
          </div>
          <div className="kpi">
            <div className="kpi-num px-num" style={{ color: "var(--pink)" }}>{Math.round(gs.strike * 100)}%</div>
          </div>
        </div>
      </div>
      {/* W / R / L / Total breakdown tiles */}
      <div className="bigstat-grid">
        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">WINS</div>
            </div>
            <span className="dot win" />
          </div>
          <div className="kpi win">
            <div className="kpi-num px-num">{summary.w}</div>
            <div className="kpi-foot">{summary.total ? Math.round(summary.w / summary.total * 100) : 0}% of alerts</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">REFUNDS</div>
            </div>
            <span className="dot refund" />
          </div>
          <div className="kpi refund">
            <div className="kpi-num px-num">{summary.r}</div>
            <div className="kpi-foot">{summary.total ? Math.round(summary.r / summary.total * 100) : 0}% of alerts</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">LOSSES</div>
            </div>
            <span className="dot loss" />
          </div>
          <div className="kpi loss">
            <div className="kpi-num px-num">{summary.l}</div>
            <div className="kpi-foot">{summary.total ? Math.round(summary.l / summary.total * 100) : 0}% of alerts</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">ALERTS</div>
            </div>
            <span className="dot" style={{ background: "var(--ink)" }} />
          </div>
          <div className="kpi">
            <div className="kpi-num px-num">{summary.total}</div>
            <div className="kpi-foot">{(() => {
                const first = all.reduce((min, a) => !min || a.ts < min ? a.ts : min, null);
                if (!first) return "no alerts yet";
                const days = Math.max(0, Math.floor((Date.now() - first.getTime()) / 86400000));
                return `${days} days since first alert`;
              })()}</div>
          </div>
        </div>
      </div>

      {/* Per-type outcome splits side by side */}
      <div className="grid-bottom">
        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">CORNERS · OUTCOME SPLIT</div>
            </div>
            <span className="col-tag corners" style={{ padding: "4px 6px", fontSize: 8 }}>C</span>
          </div>
          <Donut w={cs.w} r={cs.r} l={cs.l} size={200} />
        </div>
        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title px px-heading">GOALS · OUTCOME SPLIT</div>
            </div>
            <span className="col-tag goals" style={{ padding: "4px 6px", fontSize: 8 }}>G</span>
          </div>
          <Donut w={gs.w} r={gs.r} l={gs.l} size={200} />
        </div>
      </div>

      <PnLCard alerts={all} />

      <div style={{ marginTop: "var(--gap)" }}>
        <DailyBreakdownCard alerts={all} />
      </div>

      <MonthlyBreakdownCard months={months} />

      <LineBreakdownCard alerts={all} />

      {/* League leaderboard all time */}
      <div className="card" style={{ marginTop: "var(--gap)" }}>
        <div className="card-head">
          <div>
            <div className="card-title px px-heading">LEAGUE PERFORMANCE</div>
          </div>
        </div>
        <LeagueBoard alerts={all} />
      </div>

      <StreaksCard alerts={all} />
    </div>);

}

// ---- Filter toggle (used by Daily & Monthly cards) -----
function TypeToggle({ value, onChange, includeAll = true }) {
  return (
    <div className="lb-toggle">
      {includeAll &&
      <button
        className={`lb-tog ${value === "all" ? "active" : ""}`}
        onClick={() => onChange("all")}>ALL</button>
      }
      <button
        className={`lb-tog corners ${value === "Corners" ? "active" : ""}`}
        onClick={() => onChange("Corners")}>CORNERS</button>
      <button
        className={`lb-tog goals ${value === "Goals" ? "active" : ""}`}
        onClick={() => onChange("Goals")}>GOALS</button>
    </div>);
}

// ---- Daily breakdown -----
function DailyBreakdownCard({ alerts }) {
  const [filter, setFilter] = useState("all");
  const filtered = useMemo(() =>
  filter === "all" ? alerts : alerts.filter((a) => a.type === filter),
  [alerts, filter]);
  const dowLabels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
  const rows = dowLabels.map((label, idx) => {
    const subset = filtered.filter((a) => (a.ts.getDay() + 6) % 7 === idx);
    return { label, ...window.STATTO.summarize(subset) };
  });
  return (
    <div className="card">
      <div className="card-head">
        <div>
          <div className="card-title px px-heading">DAILY BREAKDOWN</div>
        </div>
      </div>
      <TypeToggle value={filter} onChange={setFilter} />
      <table className="league-table">
          <colgroup>
            <col className="c-name" />
            <col className="c-num-sm" />
            <col className="c-num-sm" />
            <col className="c-num-sm" />
            <col className="c-num-sm" />
            <col className="c-split" />
            <col className="c-rate" />
          </colgroup>
          
        <thead>
          <tr>
            <th>Day</th>
            <th className="num">A</th>
            <th className="num">W</th>
            <th className="num">R</th>
            <th className="num">L</th>
            <th>Split</th>
            <th className="num">W+R Rate</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((d) => {
            const wp = d.total ? d.w / d.total * 100 : 0;
            const rp = d.total ? d.r / d.total * 100 : 0;
            const lp = d.total ? d.l / d.total * 100 : 0;
            return (
              <tr key={d.label}>
                <td>{d.label}</td>
                <td className="num">{d.total}</td>
                <td className="num" style={{ color: "var(--win)" }}>{d.w}</td>
                <td className="num" style={{ color: "var(--refund)" }}>{d.r}</td>
                <td className="num" style={{ color: "var(--loss)" }}>{d.l}</td>
                <td>
                  <span className="mini-bar">
                    <div style={{ width: wp + "%" }} />
                    <div style={{ width: rp + "%" }} />
                    <div style={{ width: lp + "%" }} />
                  </span>
                </td>
                <td className="num">{d.total ? Math.round(d.strike * 100) + "%" : "—"}</td>
              </tr>);
          })}
        </tbody>
      </table>
    </div>);
}

// ---- Monthly breakdown -----
function MonthlyBreakdownCard({ months }) {
  const [filter, setFilter] = useState("all");
  const rows = useMemo(() => months.map((m) => {
    const monthAlerts = m.weeks.flatMap((w) => w.alerts);
    const subset = filter === "all" ? monthAlerts : monthAlerts.filter((a) => a.type === filter);
    return { key: m.key, label: m.label, summary: window.STATTO.summarize(subset) };
  }), [months, filter]);
  return (
    <div className="card" style={{ marginTop: "var(--gap)" }}>
      <div className="card-head">
        <div>
          <div className="card-title px px-heading">MONTHLY BREAKDOWN</div>
        </div>
      </div>
      <TypeToggle value={filter} onChange={setFilter} />
      <table className="league-table">
          <colgroup>
            <col className="c-name" />
            <col className="c-num-sm" />
            <col className="c-num-sm" />
            <col className="c-num-sm" />
            <col className="c-num-sm" />
            <col className="c-split" />
            <col className="c-rate" />
          </colgroup>
          
        <thead>
          <tr>
            <th>Month</th>
            <th className="num">A</th>
            <th className="num">W</th>
            <th className="num">R</th>
            <th className="num">L</th>
            <th>Split</th>
            <th className="num">W+R Rate</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((m) => {
            const s = m.summary;
            const wp = s.total ? s.w / s.total * 100 : 0;
            const rp = s.total ? s.r / s.total * 100 : 0;
            const lp = s.total ? s.l / s.total * 100 : 0;
            return (
              <tr key={m.key}>
                <td>{m.label}</td>
                <td className="num">{s.total}</td>
                <td className="num" style={{ color: "var(--win)" }}>{s.w}</td>
                <td className="num" style={{ color: "var(--refund)" }}>{s.r}</td>
                <td className="num" style={{ color: "var(--loss)" }}>{s.l}</td>
                <td>
                  <span className="mini-bar">
                    <div style={{ width: wp + "%" }} />
                    <div style={{ width: rp + "%" }} />
                    <div style={{ width: lp + "%" }} />
                  </span>
                </td>
                <td className="num">{s.total ? Math.round(s.strike * 100) + "%" : "—"}</td>
              </tr>);
          })}
        </tbody>
      </table>
    </div>);
}

// ---- Streaks card -----
function StreaksCard({ alerts }) {
  const [filter, setFilter] = useState("all");

  const filtered = useMemo(() => {
    const subset = filter === "all" ? alerts : alerts.filter((a) => a.type === filter);
    // chronological (oldest -> newest) for streak math
    return [...subset].sort((a, b) => a.ts - b.ts);
  }, [alerts, filter]);

  // compute current + longest run for a predicate
  function streakStats(predicate) {
    let longest = 0,longestEndTs = null;
    let run = 0,runStartTs = null,runEndTs = null;
    for (const a of filtered) {
      if (predicate(a.outcome)) {
        if (run === 0) runStartTs = a.ts;
        run++;
        runEndTs = a.ts;
        if (run > longest) {longest = run;longestEndTs = a.ts;}
      } else {
        run = 0;runStartTs = null;
      }
    }
    return { current: run, longest, currentStart: runStartTs, currentEnd: runEndTs, longestEnd: longestEndTs };
  }

  const wr = streakStats((o) => o === "W" || o === "R");
  const wins = streakStats((o) => o === "W");
  const loss = streakStats((o) => o === "L");

  const items = [
  { key: "wr", label: "WIN & REFUND", color: "var(--win)", s: wr },
  { key: "win", label: "WIN", color: "var(--win)", s: wins },
  { key: "loss", label: "LOSS", color: "var(--loss)", s: loss }];


  return (
    <div className="card" style={{ marginTop: "var(--gap)" }}>
      <div className="card-head">
        <div>
          <div className="card-title px px-heading">STREAKS</div>
        </div>
      </div>
      <TypeToggle value={filter} onChange={setFilter} />
      <div className="streaks-grid">
        {items.map((it) =>
        <div key={it.key} className="streak-tile">
            <div className="streak-label" style={{ color: it.color }}>{it.label}</div>
            <div className="streak-sub">LONGEST</div>
            <div className="streak-num" style={{ color: it.color }}>{it.s.longest}</div>
          </div>
        )}
      </div>
    </div>);
}

// ---- Implied odds + P&L helpers -----
// Average implied odds — assume 1.85 across all lines (asian lines: W = stake*(odds-1), R = 0, L = -stake)
const IMPLIED_ODDS_AVG = 1.85;
function oddsFor(a) {return IMPLIED_ODDS_AVG;}
function pnlFor(a) {
  if (a.outcome === "W") return oddsFor(a) - 1;
  if (a.outcome === "R") return 0;
  if (a.outcome === "L") return -1;
  return 0;
}

// ---- Line breakdown -----
function LineBreakdownCard({ alerts }) {
  // group by type|line
  const rows = useMemo(() => {
    const map = new Map();
    for (const a of alerts) {
      const key = `${a.type}|${a.line}`;
      if (!map.has(key)) map.set(key, { type: a.type, line: a.line, alerts: [] });
      map.get(key).alerts.push(a);
    }
    return [...map.values()].
    map((r) => ({ ...r, summary: window.STATTO.summarize(r.alerts) })).
    sort((a, b) => {
      // Corners before Goals; then ascending line
      if (a.type !== b.type) return a.type === "Corners" ? -1 : 1;
      return a.line - b.line;
    });
  }, [alerts]);

  return (
    <div className="card" style={{ marginTop: "var(--gap)" }}>
      <div className="card-head">
        <div>
          <div className="card-title px px-heading">LINE BREAKDOWN</div>
        </div>
      </div>
      <table className="league-table">
        <colgroup>
          <col className="c-name" />
          <col className="c-num-sm" />
          <col className="c-num-sm" />
          <col className="c-num-sm" />
          <col className="c-num-sm" />
          <col className="c-num-sm" />
          <col className="c-split" />
          <col className="c-rate" />
        </colgroup>
        <thead>
          <tr>
            <th>Alert</th>
            <th className="num">Line</th>
            <th className="num">A</th>
            <th className="num">W</th>
            <th className="num">R</th>
            <th className="num">L</th>
            <th>Split</th>
            <th className="num">W+R Rate</th>
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 &&
          <tr><td colSpan="8" style={{ textAlign: "center", color: "var(--ink-3)", padding: "20px 0" }}>No alerts</td></tr>
          }
          {rows.map((r) => {
            const s = r.summary;
            const wp = s.total ? s.w / s.total * 100 : 0;
            const rp = s.total ? s.r / s.total * 100 : 0;
            const lp = s.total ? s.l / s.total * 100 : 0;
            const isCorners = r.type === "Corners";
            return (
              <tr key={`${r.type}-${r.line}`}>
                <td>
                  <span
                    className={`col-tag ${isCorners ? "corners" : "goals"}`}
                    style={{ padding: "4px 8px", fontSize: 8 }}>
                    {isCorners ? "CORNERS" : "GOALS"}
                  </span>
                </td>
                <td className="num">{r.line}+</td>
                <td className="num">{s.total}</td>
                <td className="num" style={{ color: "var(--win)" }}>{s.w}</td>
                <td className="num" style={{ color: "var(--refund)" }}>{s.r}</td>
                <td className="num" style={{ color: "var(--loss)" }}>{s.l}</td>
                <td>
                  <span className="mini-bar">
                    <div style={{ width: wp + "%" }} />
                    <div style={{ width: rp + "%" }} />
                    <div style={{ width: lp + "%" }} />
                  </span>
                </td>
                <td className="num">{s.total ? Math.round(s.strike * 100) + "%" : "—"}</td>
              </tr>);
          })}
        </tbody>
      </table>
    </div>);
}

// ---- Implied unit P&L -----
// W = +1, R = 0, L = -1  (used by the chart + UNIT CHANGE tile)
function netFor(a) {
  if (a.outcome === "W") return 1;
  if (a.outcome === "L") return -1;
  return 0;
}
function PnLChart({ points, height = 220 }) {
  if (points.length < 2) {
    return <div className="empty-state">Not enough settled alerts yet</div>;
  }
  const W = 1000,H = height;
  const padL = 44,padR = 24,padT = 18,padB = 28;
  const innerW = W - padL - padR;
  const innerH = H - padT - padB;

  const ys_vals = points.map((p) => p.cum);
  const rawMin = Math.min(0, ...ys_vals);
  const rawMax = Math.max(0, ...ys_vals);
  // pick an evenly-spaced step that yields ~3-5 intervals across the data range
  const rawRange = Math.max(1, rawMax - rawMin);
  const niceSteps = [1, 2, 5, 10, 20, 25, 50, 100];
  let step = 1;
  for (const s of niceSteps) {
    if (rawRange / s <= 5) { step = s; break; }
  }
  const yMin = Math.floor(rawMin / step) * step;
  const yMax = Math.ceil(rawMax / step) * step;
  const range = Math.max(step, yMax - yMin);
  const N = points.length;
  const xs = (i) => padL + (N <= 1 ? innerW / 2 : i / (N - 1) * innerW);
  const ys = (v) => padT + (1 - (v - yMin) / range) * innerH;

  const path = points.map((p, i) => `${i === 0 ? "M" : "L"} ${xs(i)} ${ys(p.cum)}`).join(" ");
  const zeroY = ys(0);
  const lastPt = points[points.length - 1];
  const lineColor = lastPt.cum >= 0 ? "var(--green-deep)" : "var(--loss)";
  const areaColor = lastPt.cum >= 0 ? "url(#pnlPos)" : "url(#pnlNeg)";
  const area = `${path} L ${xs(N - 1)} ${zeroY} L ${xs(0)} ${zeroY} Z`;

  // evenly-spaced integer ticks from yMin to yMax (step chosen above)
  const ticks = [];
  for (let t = yMin; t <= yMax; t += step) ticks.push(t);

  return (
    <svg className="line-chart" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" style={{ height }}>
      <defs>
        <linearGradient id="pnlPos" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor="#2f7a3a" stopOpacity="0.28" />
          <stop offset="100%" stopColor="#2f7a3a" stopOpacity="0" />
        </linearGradient>
        <linearGradient id="pnlNeg" x1="0" x2="0" y1="1" y2="0">
          <stop offset="0%" stopColor="#c5333e" stopOpacity="0.28" />
          <stop offset="100%" stopColor="#c5333e" stopOpacity="0" />
        </linearGradient>
      </defs>
      <g className="grid">
        {ticks.map((t, i) =>
        <line key={i} x1={padL} x2={W - padR} y1={ys(t)} y2={ys(t)} />
        )}
      </g>
      <g className="axis">
        {ticks.map((t, i) =>
        <text key={i} x={padL - 8} y={ys(t) + 4} textAnchor="end">
            {(t > 0 ? "+" : "") + Math.round(t)}
          </text>
        )}
        {/* x-axis date ticks — first, last, and ~4 evenly spaced in between */}
        {(() => {
          const labels = [];
          const tickCount = Math.min(6, N);
          const fmt = (d) => d.toLocaleDateString("en-GB", { day: "numeric", month: "short" });
          for (let k = 0; k < tickCount; k++) {
            const i = Math.round(k * (N - 1) / Math.max(1, tickCount - 1));
            const p = points[i];
            if (!p || !p.ts) continue;
            const anchor = k === 0 ? "start" : k === tickCount - 1 ? "end" : "middle";
            labels.push(
              <text key={`x-${k}`} x={xs(i)} y={H - 8} textAnchor={anchor}>
                {fmt(p.ts)}
              </text>
            );
          }
          return labels;
        })()}
      </g>
      {/* zero line */}
      <line x1={padL} x2={W - padR} y1={zeroY} y2={zeroY} stroke="var(--ink-3)" strokeWidth="1" opacity="0.4" />
      <path d={area} fill={areaColor} />
      <path d={path} fill="none" stroke={lineColor} strokeWidth="2.5" />
      <circle cx={xs(N - 1)} cy={ys(lastPt.cum)} r="5" fill="var(--paper)" stroke={lineColor} strokeWidth="2" />
    </svg>);
}

function PnLCard({ alerts }) {
  const [filter, setFilter] = useState("all");

  // Total alerts matching the filter (incl. pending) — drives "Alert Volume" tile
  const filteredAll = useMemo(() => {
    return filter === "all" ? alerts : alerts.filter((a) => a.type === filter);
  }, [alerts, filter]);

  const filtered = useMemo(() => {
    // Only include settled bets (W / R / L) — pending alerts have no P&L impact yet
    const settledOnly = filteredAll.filter((a) => a.outcome === "W" || a.outcome === "R" || a.outcome === "L");
    return [...settledOnly].sort((a, b) => a.ts - b.ts);
  }, [filteredAll]);

  // running net-wins counter for the chart (W=+1, R=0, L=-1).
  const data = useMemo(() => {
    let cumNet = 0;
    let wins = 0, refunds = 0, losses = 0;
    const points = [];
    if (filtered.length) {
      // anchor a zero point one minute before the first alert
      const firstTs = filtered[0].ts;
      const startTs = firstTs instanceof Date ?
      new Date(firstTs.getTime() - 60 * 1000) :
      new Date(+firstTs - 60 * 1000);
      points.push({ ts: startTs, cum: 0 });
    }
    filtered.forEach((a) => {
      cumNet += netFor(a);
      if (a.outcome === "W") wins++;
      else if (a.outcome === "R") refunds++;
      else if (a.outcome === "L") losses++;
      points.push({ ts: a.ts, cum: cumNet });
    });
    return {
      points,
      netChange: cumNet,
      settled: filtered.length,
      volume: filteredAll.length,
      winsRefunds: wins + refunds,
      losses
    };
  }, [filtered, filteredAll]);

  const fmtNet = (v) => (v > 0 ? "+" : "") + v;
  const netColor = data.netChange >= 0 ? "var(--win)" : "var(--loss)";

  return (
    <div className="card" style={{ marginTop: "var(--gap)" }}>
      <div className="card-head">
        <div>
          <div className="card-title px px-heading">ALERT PERFORMANCE</div>
        </div>
        <TypeToggle value={filter} onChange={setFilter} />
      </div>

      <div className="pnl-summary">
        <div className="pnl-stat">
          <div className="pnl-lbl">WINS + REFUNDS</div>
          <div className="pnl-num" style={{ color: "var(--win)" }}>
            {data.settled ? data.winsRefunds : "—"}
          </div>
        </div>
        <div className="pnl-stat">
          <div className="pnl-lbl">LOSSES</div>
          <div className="pnl-num" style={{ color: "var(--loss)" }}>
            {data.settled ? data.losses : "—"}
          </div>
        </div>
        <div className="pnl-stat">
          <div className="pnl-lbl">NET RESULT</div>
          <div className="pnl-num" style={{ color: netColor }}>
            {data.settled ? fmtNet(data.netChange) : "—"}
          </div>
        </div>
        <div className="pnl-stat">
          <div className="pnl-lbl">ALERT VOLUME</div>
          <div className="pnl-num" style={{ color: "var(--ink)" }}>{data.volume}</div>
        </div>
      </div>

      <PnLChart points={data.points} />

      <div className="pnl-foot">
        win = +1 · refund = 0 · loss = −1
      </div>
    </div>);
}

// ---- All time line chart (many points) -----
function AllTimeLineChart({ points, target = 0.65, height = 220 }) {
  const W = 1000,H = height;
  const padL = 36,padR = 24,padT = 18,padB = 28;
  const innerW = W - padL - padR;
  const innerH = H - padT - padB;
  const N = points.length;
  const xs = (i) => padL + (N <= 1 ? innerW / 2 : i / (N - 1) * innerW);
  const ys = (v) => padT + (1 - v) * innerH;

  const cumPts = points.map((p, i) => p.cum == null ? null : { x: xs(i), y: ys(p.cum), v: p.cum }).filter(Boolean);
  const weekPts = points.map((p, i) => ({ x: xs(i), y: ys(p.weekly), v: p.weekly }));

  const cumPath = cumPts.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
  const area = cumPts.length ? `${cumPath} L ${cumPts[cumPts.length - 1].x} ${padT + innerH} L ${cumPts[0].x} ${padT + innerH} Z` : "";

  return (
    <svg className="line-chart" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" style={{ height }}>
      <defs>
        <linearGradient id="areaGrad" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor="#2f7a3a" stopOpacity="0.25" />
          <stop offset="100%" stopColor="#2f7a3a" stopOpacity="0" />
        </linearGradient>
      </defs>
      <g className="grid">
        {[0, 0.25, 0.5, 0.75, 1].map((t) =>
        <line key={t} x1={padL} x2={W - padR} y1={ys(t)} y2={ys(t)} />
        )}
      </g>
      <g className="axis">
        {[0, 0.5, 1].map((t) =>
        <text key={t} x={padL - 8} y={ys(t) + 4} textAnchor="end">{Math.round(t * 100)}%</text>
        )}
        {points.map((p, i) => (i % Math.ceil(N / 8) === 0 || i === N - 1) &&
        <text key={i} x={xs(i)} y={H - 8} textAnchor="middle">{p.label.split(" – ")[0]}</text>
        )}
      </g>

      {/* weekly dots */}
      {weekPts.map((p, i) =>
      <circle key={i} cx={p.x} cy={p.y} r="2.5" fill="var(--ink-3)" opacity="0.6" />
      )}

      <line className="target" x1={padL} x2={W - padR} y1={ys(target)} y2={ys(target)} />
      <text className="target-label" x={W - padR - 4} y={ys(target) - 6} textAnchor="end">TARGET {Math.round(target * 100)}%</text>

      {cumPts.length > 1 && <path className="area" d={area} />}
      {cumPts.length > 1 && <path className="line" d={cumPath} />}
      {cumPts.length && <circle className="point" cx={cumPts[cumPts.length - 1].x} cy={cumPts[cumPts.length - 1].y} r="5" />}
    </svg>);

}

// ------------------------------------------------------------------
// App root
// ------------------------------------------------------------------

function SyncPill() {
  const [now, setNow] = useState(Date.now());
  useEffect(() => {
    const onSync = () => setNow(Date.now());
    window.addEventListener("statto:sync", onSync);
    const id = setInterval(() => setNow(Date.now()), 30_000);
    return () => {
      window.removeEventListener("statto:sync", onSync);
      clearInterval(id);
    };
  }, []);
  const last = window.__STATTO_LAST_SYNC || now;
  const lastDate = new Date(last);
  // green dot when fresh (within 10m), amber otherwise
  const ageSec = Math.max(0, Math.floor((now - last) / 1000));
  const dotClass = ageSec < 10 * 60 ? "dot win" : "dot refund";
  // Format: HH:MM (24h)
  const hh = String(lastDate.getHours()).padStart(2, "0");
  const mm = String(lastDate.getMinutes()).padStart(2, "0");
  const stamp = `${hh}:${mm}`;
  return (
    <span className="pill" title={lastDate.toLocaleString()}>
      <span className={dotClass} /> Live · synced {stamp}
    </span>);
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [view, setView] = useState("current"); // current | history | alltime
  const currentWeek = window.STATTO.ALL_WEEKS[0];
  const [selectedWeekId, setSelectedWeekId] = useState(currentWeek.id);

  useEffect(() => {
    document.documentElement.setAttribute("data-density", t.density);
    document.documentElement.setAttribute("data-pixel", t.pixel);
  }, [t.density, t.pixel]);

  const week = useMemo(() => {
    if (view === "current") return currentWeek;
    return window.STATTO.ALL_WEEKS.find((w) => w.id === selectedWeekId) || currentWeek;
  }, [view, selectedWeekId]);

  const isCurrent = view === "current" || view === "history" && week.id === currentWeek.id;

  return (
    <div className="app">
      <Sidebar
        view={view}
        setView={setView}
        selectedWeekId={selectedWeekId}
        setSelectedWeekId={setSelectedWeekId} />
      
      <main className="main">
        <div className="topbar">
          <div className="topbar-lead">
            <div className="top-tabs">
              <button
                className={`top-tab ${view !== "alltime" && isCurrent ? "active" : ""}`}
                onClick={() => setView("current")}>
                THIS WEEK</button>
              <button
                className={`top-tab ${view === "alltime" ? "active" : ""}`}
                onClick={() => setView("alltime")}>
                ALL TIME</button>
            </div>
            {view === "history" && !isCurrent &&
            <span className="topbar-ctx">{week.label}</span>}
          </div>
          <TelegramButton />
        </div>

        {view === "alltime" ?
        <AllTimeView /> :
        <WeekView week={week} isCurrent={isCurrent} />}

        <Footer />
      </main>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Aesthetic" />
        <TweakRadio
          label="Pixel intensity"
          value={t.pixel}
          options={[
          { value: "subtle", label: "Subtle" },
          { value: "medium", label: "Medium" },
          { value: "heavy", label: "Heavy" }]
          }
          onChange={(v) => setTweak("pixel", v)} />
        
        <TweakRadio
          label="Density"
          value={t.density}
          options={[
          { value: "compact", label: "Compact" },
          { value: "comfortable", label: "Comfy" }]
          }
          onChange={(v) => setTweak("density", v)} />
        
      </TweaksPanel>
    </div>);

}

// ------------------------------------------------------------------
// Footer — privacy/transparency line for subscribers
// ------------------------------------------------------------------
function Footer() {
  const year = new Date().getFullYear();
  return (
    <footer className="site-footer">
      <div className="foot-row">
        <span className="foot-brand px-heading">STATTO DASH</span>
        <SyncPill />
      </div>
      <p className="foot-fine">
        This dashboard sets no cookies and tracks nothing. Figures shown are
        general performance statistics for informational purposes only — past
        results do not guarantee future outcomes. 18+
      </p>
      <p className="foot-copy">© {year} Statto Dash · Not affiliated with any bookmaker.</p>
    </footer>);
}

const __root = ReactDOM.createRoot(document.getElementById("root"));
function __renderApp() {__root.render(<App />);}
function __renderError(msg) {
  document.getElementById("root").innerHTML =
  `<div style="padding:40px;font-family:system-ui;color:#7a2530;background:#f1ead7;min-height:100vh">
       <h2 style="margin:0 0 12px">Couldn't load alerts</h2>
       <p style="margin:0 0 12px">${msg}</p>
       <p style="color:#7a8270;font-size:13px;margin:0">Check ENDPOINT and TOKEN in data.live.js, and that the Apps Script is deployed.</p>
     </div>`;
}
window.STATTO_PROMISE.
then(__renderApp).
catch((e) => __renderError(e.message || String(e)));
setInterval(() => {
  window.STATTO_LOAD().then(__renderApp).catch((e) => console.error("Refresh failed:", e));
}, 60_000);