/* ============================================================
   Season — scorecard stats + handicaps for every member.
   Visible to ALL members. Sortable columns (click a header).
   Aggregates every POSTED weekend's stats (stored on the season
   doc) plus the live current weekend. Managers also get the
   "post this weekend" control.
   ============================================================ */
function SeasonScreen({ ctx }) {
  const Y = window.YCC;
  const { seasonDoc, accountMembers, tour, scores, sideResults, gameConfig, postWeekendResults, clearWeekendResults, isManagerUser, member } = ctx;
  const ENG = window.YCC_SCORING;
  const fullName = (m) => `${m.first_name || ""} ${m.last_name || ""}`.trim() || m.email;
  const initials = (n) => (n || "?").trim().split(/\s+/).map((s) => s[0]).join("").slice(0, 2).toUpperCase();

  const [sort, setSort] = useState({ key: "wins", dir: "desc" });

  // ---- aggregate per-member stats across the season ----
  const postedStats = (seasonDoc && seasonDoc.stats) || {};
  const live = ENG.weekendStats ? ENG.weekendStats({ tour, scores, sideResults, gameConfig }) : {};
  const NUM_KEYS = ["eagles", "birdies", "pars", "bogeys", "doubles", "bogeyPlus", "holes", "strokes", "toPar", "rounds", "ctp", "longDrive", "wins"];
  const agg = {};
  const blank = () => { const o = { weekendsWon: 0 }; NUM_KEYS.forEach((k) => (o[k] = 0)); return o; };
  const addWeekend = (byName) => {
    Object.entries(byName || {}).forEach(([name, s]) => {
      const a = agg[name] || (agg[name] = blank());
      NUM_KEYS.forEach((k) => { a[k] += (s[k] || 0); });
      if ((s.wins || 0) > 0) a.weekendsWon += 1;
    });
  };
  Object.entries(postedStats).forEach(([wk, byName]) => addWeekend(byName));
  // include the live current weekend only if it isn't already posted (avoids double count)
  const liveIncluded = !postedStats[tour.satISO];
  if (liveIncluded) addWeekend(live);

  // handicap lookup (current index) by member name
  const hiByName = {};
  (accountMembers || []).forEach((m) => { const n = fullName(m); if (m.handicap_index != null) hiByName[n] = m.handicap_index; });
  if (member && member.name && member.handicapIndex != null && hiByName[member.name] == null) hiByName[member.name] = member.handicapIndex;

  // universe of names: every account member + anyone with stats
  const names = new Set();
  (accountMembers || []).forEach((m) => names.add(fullName(m)));
  Object.keys(agg).forEach((n) => names.add(n));
  if (member && member.name) names.add(member.name);

  const rows = Array.from(names).map((name) => {
    const a = agg[name] || blank();
    const avg = a.holes ? Math.round((a.strokes / a.holes) * 18) : null;
    return {
      name, hi: hiByName[name] != null ? hiByName[name] : null,
      rounds: a.rounds, eagles: a.eagles, birdies: a.birdies, pars: a.pars,
      bogeys: a.bogeys, doubles: a.doubles, bogeyPlus: a.bogeyPlus,
      avg, ctp: a.ctp, longDrive: a.longDrive, wins: a.wins, weekendsWon: a.weekendsWon,
      played: a.holes > 0,
    };
  });

  // ---- sorting ----
  const COLS = [
    { key: "name", label: "Member", text: true },
    { key: "hi", label: "HI", hint: "Handicap Index" },
    { key: "rounds", label: "Rds", hint: "Rounds played" },
    { key: "eagles", label: "Eagles" },
    { key: "birdies", label: "Birdies" },
    { key: "pars", label: "Pars" },
    { key: "bogeys", label: "Bogeys" },
    { key: "doubles", label: "Dbl", hint: "Double bogeys" },
    { key: "bogeyPlus", label: "Bgy+", hint: "Triple bogey or worse" },
    { key: "avg", label: "Avg", hint: "Scoring average per 18 holes", lowGood: true },
    { key: "ctp", label: "CTP", hint: "Closest to the pin" },
    { key: "longDrive", label: "Long Dr", hint: "Longest drive" },
    { key: "wins", label: "Wins", hint: "Game wins (most wins by day)" },
    { key: "weekendsWon", label: "Wknds", hint: "Weekends won" },
  ];
  function clickSort(key) {
    const col = COLS.find((c) => c.key === key);
    setSort((s) => s.key === key ? { key, dir: s.dir === "asc" ? "desc" : "asc" } : { key, dir: col && col.text ? "asc" : "desc" });
  }
  const sorted = [...rows].sort((a, b) => {
    const { key, dir } = sort;
    if (key === "name") return dir === "asc" ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
    let av = a[key], bv = b[key];
    av = (typeof av === "number" && isFinite(av)) ? av : null;
    bv = (typeof bv === "number" && isFinite(bv)) ? bv : null;
    if (av == null && bv == null) return a.name.localeCompare(b.name);
    if (av == null) return 1;
    if (bv == null) return -1;
    if (av === bv) return a.name.localeCompare(b.name);
    return dir === "asc" ? av - bv : bv - av;
  });

  // ---- summary tiles ----
  const seasonWeeks = Object.keys(postedStats).length;
  const totalBirdiesEagles = rows.reduce((n, r) => n + r.eagles + r.birdies, 0);
  const totalRounds = rows.reduce((n, r) => n + r.rounds, 0);
  const winLeader = [...rows].filter((r) => r.wins > 0).sort((a, b) => b.wins - a.wins)[0];

  const numCellStyle = (highlight) => ({ padding: "10px 12px", textAlign: "center", fontWeight: 600, fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap", color: highlight ? "var(--brand)" : "var(--ink)" });

  return (
    <div className="page fade-in">
      <div className="page-head" style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", flexWrap: "wrap", gap: 16 }}>
        <div>
          <div className="eyebrow">DIV Tour</div>
          <h1 style={{ marginTop: 6 }}>Season</h1>
          <p>Every member's scorecard stats and handicap across the season. {liveIncluded ? "Includes this weekend's live scores. " : ""}Tap any column heading to sort.</p>
        </div>
      </div>

      {/* summary */}
      <div className="grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(150px,1fr))", marginBottom: 20 }}>
        <StatTile value={seasonWeeks} label="Weekends posted" sub="this season" />
        <StatTile value={winLeader ? winLeader.name.split(" ")[0] : "—"} label="Most wins" sub={winLeader ? `${winLeader.wins} win${winLeader.wins > 1 ? "s" : ""}` : "no wins yet"} accent />
        <StatTile value={totalBirdiesEagles} label="Birdies + eagles" sub="season total" />
        <StatTile value={totalRounds} label="Rounds logged" />
      </div>

      {/* posting to the season is done from the Manager · Tour Setup tab (rounds must be certified first) */}

      {/* stats table */}
      <div className="card" style={{ overflow: "hidden" }}>
        <div className="card-head">
          <h3>Member stats</h3>
          <span className="faint" style={{ fontSize: 12 }}>Sorted by {COLS.find((c) => c.key === sort.key).label} {sort.dir === "asc" ? "↑" : "↓"}</span>
        </div>
        <div className="scroll-x">
          <table style={{ borderCollapse: "collapse", width: "100%", minWidth: 880, fontSize: 13.5 }}>
            <thead>
              <tr style={{ background: "var(--surface-2)" }}>
                {COLS.map((c) => {
                  const active = sort.key === c.key;
                  const stub = c.key === "name";
                  return (
                    <th key={c.key} onClick={() => clickSort(c.key)} title={c.hint || c.label}
                      style={{
                        padding: "11px 12px", fontSize: 11, fontWeight: 700, letterSpacing: ".04em", textTransform: "uppercase",
                        color: active ? "var(--brand)" : "var(--ink-soft)", whiteSpace: "nowrap", cursor: "pointer", userSelect: "none",
                        textAlign: stub ? "left" : "center", position: stub ? "sticky" : "static", left: stub ? 0 : "auto",
                        background: "var(--surface-2)", zIndex: stub ? 2 : 1, borderBottom: active ? "2px solid var(--accent)" : "2px solid transparent",
                      }}>
                      <span style={{ display: "inline-flex", alignItems: "center", gap: 4, justifyContent: stub ? "flex-start" : "center" }}>
                        {c.label}
                        <span style={{ fontSize: 10, opacity: active ? 1 : 0.3 }}>{active ? (sort.dir === "asc" ? "▲" : "▼") : "↕"}</span>
                      </span>
                    </th>
                  );
                })}
              </tr>
            </thead>
            <tbody>
              {sorted.map((r, i) => {
                const leader = i === 0 && sort.key !== "name";
                return (
                  <tr key={r.name} style={{ borderTop: "1px solid var(--line)", background: r.name === (member && member.name) ? "color-mix(in srgb,var(--accent) 8%,transparent)" : "transparent" }}>
                    <td style={{ padding: "10px 12px", position: "sticky", left: 0, background: r.name === (member && member.name) ? "color-mix(in srgb,var(--accent) 8%,var(--surface))" : "var(--surface)", zIndex: 1, whiteSpace: "nowrap" }}>
                      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                        <Avatar initials={initials(r.name)} size={28} tone={r.name === (member && member.name) ? "accent" : "brand"} />
                        <span style={{ fontWeight: 700 }}>{r.name === (member && member.name) ? r.name + " (you)" : r.name}</span>
                      </div>
                    </td>
                    <td style={numCellStyle()}>{r.hi == null ? <span className="faint">—</span> : r.hi}</td>
                    <td style={numCellStyle()}>{r.rounds || <span className="faint">—</span>}</td>
                    <td style={numCellStyle(r.eagles > 0)}>{r.eagles || <span className="faint">—</span>}</td>
                    <td style={numCellStyle(r.birdies > 0)}>{r.birdies || <span className="faint">—</span>}</td>
                    <td style={numCellStyle()}>{r.pars || <span className="faint">—</span>}</td>
                    <td style={numCellStyle()}>{r.bogeys || <span className="faint">—</span>}</td>
                    <td style={numCellStyle()}>{r.doubles || <span className="faint">—</span>}</td>
                    <td style={numCellStyle()}>{r.bogeyPlus || <span className="faint">—</span>}</td>
                    <td style={numCellStyle()}>{r.avg == null ? <span className="faint">—</span> : r.avg}</td>
                    <td style={numCellStyle(r.ctp > 0)}>{r.ctp ? <span className="pill pill-accent" style={{ padding: "2px 8px" }}>{r.ctp}</span> : <span className="faint">—</span>}</td>
                    <td style={numCellStyle(r.longDrive > 0)}>{r.longDrive ? <span className="pill" style={{ padding: "2px 8px", background: "color-mix(in srgb,var(--ok) 18%,transparent)", color: "var(--ok)" }}>{r.longDrive}</span> : <span className="faint">—</span>}</td>
                    <td style={{ ...numCellStyle(), }}><span className="serif" style={{ fontSize: 18, fontWeight: 700, color: leader && r.wins > 0 ? "var(--accent-deep)" : "var(--brand)" }}>{r.wins || <span className="faint" style={{ fontSize: 13.5 }}>—</span>}</span></td>
                    <td style={numCellStyle()}>{r.weekendsWon || <span className="faint">—</span>}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
        <div style={{ padding: "12px var(--card-pad)", borderTop: "1px solid var(--line)", display: "flex", gap: 18, flexWrap: "wrap", fontSize: 11.5, color: "var(--ink-soft)" }}>
          <span><strong style={{ color: "var(--ink)" }}>Avg</strong> = gross scoring average per 18 holes</span>
          <span><strong style={{ color: "var(--ink)" }}>Bgy+</strong> = triple bogey or worse</span>
          <span><strong style={{ color: "var(--ink)" }}>CTP</strong> = closest-to-the-pin wins</span>
          <span><strong style={{ color: "var(--ink)" }}>Wknds</strong> = weekends with a win</span>
        </div>
      </div>
    </div>
  );
}

/* -------- Manager-only: certify a weekend's rounds & post them to member stats.
   Lives on the Manager · Tour Setup tab. Posting is gated on certification. -------- */
function PostWeekendCard({ ctx }) {
  const Y = window.YCC;
  const ENG = window.YCC_SCORING;
  const { tour, scores, gameConfig, seasonDoc, postWeekendResults, clearWeekendResults } = ctx;
  const initials = (n) => (n || "?").trim().split(/\s+/).map((s) => s[0]).join("").slice(0, 2).toUpperCase();
  const preview = ENG.weekendWins ? ENG.weekendWins({ tour, scores, gameConfig }) : { winsByName: {}, results: [] };
  const posted = !!(seasonDoc && seasonDoc.weeks && seasonDoc.weeks[tour.satISO]);
  const previewTotal = Object.values(preview.winsByName).reduce((a, b) => a + b, 0);
  const [certified, setCertified] = useState(posted);
  const canPost = previewTotal > 0 && certified;

  return (
    <div className="card" style={{ marginBottom: 22 }}>
      <div className="card-head">
        <div>
          <h3>Member stats · post to season</h3>
          <div className="muted" style={{ fontSize: 12.5, marginTop: 2 }}>Certify the rounds, then post this weekend's results into every member's season stats.</div>
        </div>
        <Icon name="trophy" size={20} style={{ color: "var(--accent-deep)" }} />
      </div>
      <div className="card-pad">
        {preview.results.length === 0 ? (
          <p className="muted" style={{ fontSize: 14, margin: "0 0 16px" }}>Once a group finishes a skins / Stableford / Nassau / Split-Sixes game and scores are in, the winners show here. Posting writes this weekend's stats (eagles, birdies, CTP, wins…) into the Season tab for every member.</p>
        ) : (
          <div className="stack" style={{ gap: 8, marginBottom: 16 }}>
            {preview.results.map((r, i) => (
              <div key={i} style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 14px", background: "var(--surface-2)", borderRadius: "var(--radius-sm)", flexWrap: "wrap" }}>
                <span className="pill pill-accent" style={{ whiteSpace: "nowrap" }}>{r.dayLabel} · {r.time}</span>
                <span className="faint" style={{ fontSize: 12, fontWeight: 700 }}>{r.game}</span>
                <span style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
                  {r.winners.map((w, j) => (
                    <span key={j} style={{ display: "flex", alignItems: "center", gap: 7, fontSize: 13, fontWeight: 700 }}>
                      <Avatar initials={initials(w)} size={22} tone="accent" /> {w}
                    </span>
                  ))}
                </span>
              </div>
            ))}
          </div>
        )}

        {/* certification gate */}
        <button onClick={() => setCertified((v) => !v)} disabled={previewTotal === 0} style={{
          display: "flex", alignItems: "center", gap: 11, width: "100%", textAlign: "left", padding: "12px 14px", marginBottom: 14,
          borderRadius: "var(--radius-sm)", border: "1.5px solid " + (certified ? "var(--brand)" : "var(--line-strong)"),
          background: certified ? "var(--brand-soft)" : "var(--surface)", cursor: previewTotal === 0 ? "not-allowed" : "pointer", opacity: previewTotal === 0 ? 0.55 : 1, transition: "all .14s",
        }}>
          <span style={{ width: 22, height: 22, borderRadius: 6, flex: "0 0 auto", display: "grid", placeItems: "center", background: certified ? "var(--brand)" : "var(--surface-2)", color: "#fff", border: "1px solid " + (certified ? "var(--brand)" : "var(--line-strong)") }}>
            {certified && <Icon name="check" size={14} />}
          </span>
          <span style={{ minWidth: 0 }}>
            <span style={{ display: "block", fontSize: 13.5, fontWeight: 700 }}>I certify these rounds are final</span>
            <span className="faint" style={{ fontSize: 11.5 }}>Scores reviewed &amp; correct. Required before posting to member stats.</span>
          </span>
        </button>

        <div style={{ display: "flex", gap: 10, flexWrap: "wrap", alignItems: "center" }}>
          <button className="btn btn-primary" disabled={!canPost} onClick={postWeekendResults} title={!certified ? "Certify the rounds first" : ""}>
            <Icon name="check" size={16} /> {posted ? "Update certified results" : "Certify & post to the season"}
          </button>
          {posted && <button className="btn btn-danger" onClick={clearWeekendResults}><Icon name="trash" size={15} /> Remove from season</button>}
          {posted && <span className="pill pill-green" style={{ whiteSpace: "nowrap" }}><Icon name="check" size={11} /> Posted to member stats</span>}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { SeasonScreen, PostWeekendCard });
