// Stadium map — 2026 NFL slate. Shared venues keep one pin; occupant follows the home team that week.

const NFL_REG_WEEKS = 18;

/** Green-arrow headings from the annotated map (degrees, SVG clockwise from +X). */
const STADIUM_HEADING = {
  SEA: -135,
  LV: 55,
  MIN: 112,
  CHI: 45,
  DET: 37,
};

function stadiumHeading(site) {
  const id = site?.id || site?.team;
  const teams = site?.teams || (site?.team ? [site.team] : []);
  for (const key of [id, ...teams]) {
    if (key && STADIUM_HEADING[key] != null) return STADIUM_HEADING[key];
  }
  return site?.iconRot ?? -38;
}

function StadiumMap({ onSelectPlayer, activeLeague, session }) {
  const live = window.useLiveLeague ? window.useLiveLeague(activeLeague) : null;
  const NFL_CITIES = window.NFL_CITIES || [];
  const NFL_STADIUMS = window.NFL_STADIUMS || [];
  const PLAYERS = window.PLAYERS || [];
  const [weekNum, setWeekNum] = React.useState(1);
  const [allGames, setAllGames] = React.useState(() => window.NFL_SCHEDULE || []);
  const schedule = React.useMemo(
    () => (allGames || []).filter((g) => g.week === weekNum),
    [allGames, weekNum],
  );
  const roster = live?.roster?.length
    ? live.roster
    : (activeLeague
      ? (() => {
        try {
          return (window.buildLiveLeagueContext && window.buildLiveLeagueContext(activeLeague)?.roster) || [];
        } catch (error) {
          console.warn("Games roster build failed", error);
          return [];
        }
      })()
      : (session
        ? []
        : (window.getDemoRosterPlayers ? window.getDemoRosterPlayers({ forceSeed: true }) : [])));
  const [scheduleTick, setScheduleTick] = React.useState(0);

  React.useEffect(() => {
    const sync = () => setAllGames(window.NFL_SCHEDULE || []);
    const bump = () => { sync(); setScheduleTick((n) => n + 1); };
    window.addEventListener("nfl-schedule", bump);
    window.addEventListener("league-schedule", bump);
    sync();
    if (!(window.NFL_SCHEDULE || []).length && typeof window.hydrateNflScheduleFromApi === "function") {
      window.hydrateNflScheduleFromApi().then(sync);
    }
    return () => {
      window.removeEventListener("nfl-schedule", bump);
      window.removeEventListener("league-schedule", bump);
    };
  }, []);

  const hasLeagueSked = !!(activeLeague && window.hasLeagueSchedule && window.hasLeagueSchedule(activeLeague.id));
  const opponentRoster = React.useMemo(() => {
    if (!hasLeagueSked || !activeLeague) return [];
    const userSlot = (window.resolveUserSlot || window.inferUserSlot)
      ? (window.resolveUserSlot || window.inferUserSlot)(activeLeague)
      : ((activeLeague.teams || []).find((team) => team.isUserTeam)?.slot
        || activeLeague.draftPosition
        || 1);
    const oppSlot = typeof window.opponentSlotForWeek === "function"
      ? window.opponentSlotForWeek(activeLeague, userSlot, weekNum)
      : null;
    if (!oppSlot || typeof window.playersForTeamSlot !== "function") return [];
    return window.playersForTeamSlot(activeLeague, oppSlot);
  }, [hasLeagueSked, activeLeague, weekNum, scheduleTick]);

  const weekStatus = React.useMemo(() => {
    const status = {};
    NFL_CITIES.forEach((city) => { status[city.team] = "off"; });
    schedule.forEach((game) => {
      if (game.homeTeam) status[game.homeTeam] = "neutral";
      if (game.awayTeam) status[game.awayTeam] = "neutral";
    });
    const mark = (players, stake) => {
      (players || []).forEach((player) => {
        const game = schedule.find((g) => g.homeTeam === player.team || g.awayTeam === player.team);
        if (!game) return;
        const apply = (code) => {
          if (!code) return;
          if (stake === "you") status[code] = "you";
          else if (status[code] !== "you") status[code] = stake;
        };
        apply(player.team);
        apply(game.homeTeam);
        apply(game.awayTeam);
      });
    };
    mark(roster, "you");
    if (hasLeagueSked) mark(opponentRoster, "opp");
    return status;
  }, [NFL_CITIES, schedule, roster, opponentRoster, hasLeagueSked]);

  const [hoverCity, setHoverCity] = React.useState(null);
  const [tooltipPos, setTooltipPos] = React.useState({ x: 0, y: 0 });

  const cityGameData = React.useMemo(() => {
    const rank = { you: 3, opp: 2, neutral: 1, off: 0 };
    const preferTeams = new Set([
      ...roster.map((p) => p.team).filter(Boolean),
      ...opponentRoster.map((p) => p.team).filter(Boolean),
    ]);
    const map = {};
    const stadiums = NFL_STADIUMS.length ? NFL_STADIUMS : NFL_CITIES.map((c) => ({
      id: c.team, name: c.city, idleLabel: c.team, city: c.city, indoor: c.indoor, x: c.x, y: c.y, teams: [c.team], shared: false, iconRot: stadiumHeading(c),
    }));
    stadiums.forEach((stadium) => {
      const occ = typeof window.occupantAtStadium === "function"
        ? window.occupantAtStadium(stadium, schedule, preferTeams)
        : { occupant: stadium.teams.find((t) => schedule.some((g) => g.homeTeam === t)) || null, conflict: false, alsoHome: [] };
      const occupant = occ.occupant;
      const game = occupant ? schedule.find((g) => g.homeTeam === occupant) : null;
      let status = "off";
      if (game) {
        const hs = weekStatus[game.homeTeam] || "off";
        const as = weekStatus[game.awayTeam] || "off";
        status = (rank[hs] || 0) >= (rank[as] || 0) ? hs : as;
        if (status === "off") status = "neutral";
      }
      const teamsInGame = game ? [game.homeTeam, game.awayTeam].filter(Boolean) : [];
      const homePlayers = roster.filter((p) => teamsInGame.includes(p.team));
      const oppPlayers = opponentRoster.filter((p) => teamsInGame.includes(p.team));
      map[stadium.id] = {
        ...stadium,
        team: occupant || stadium.idleLabel,
        occupant,
        conflict: !!occ.conflict,
        alsoHome: occ.alsoHome || [],
        status,
        homePlayers,
        oppPlayers,
        opponent: game ? game.awayTeam : null,
        kickoff: `Week ${weekNum}`,
        weather: stadium.indoor ? "Dome" : "Outdoor",
        emptyShared: stadium.shared && !occupant,
      };
      stadium.teams.forEach((t) => { map[t] = map[stadium.id]; });
    });
    return map;
  }, [NFL_CITIES, NFL_STADIUMS, weekStatus, roster, opponentRoster, schedule, PLAYERS, live, weekNum]);

  const statusColor = {
    you: "var(--mint)",
    opp: "#7BD9F4",
    neutral: "var(--gold)",
    off: "var(--slate-dim)",
  };

  const statusLabel = {
    you: "Your player",
    opp: "Opponent's player",
    neutral: "Active game",
    off: "No active game",
  };

  const nickFor = (code) => (window.NFL_TEAM_NICK && window.NFL_TEAM_NICK[code]) || code;

  const eyebrow = live
    ? `2026 Week ${weekNum} · NFL slate + your roster stake`
    : `2026 Week ${weekNum} · NFL slate`;

  return (
    <div className="card" style={{ padding: 22, position: "relative", overflow: "hidden" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", flexWrap: "wrap", gap: 16, marginBottom: 14 }}>
        <SectionTitle eyebrow={eyebrow}>NFL stadiums</SectionTitle>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 14, alignItems: "center" }}>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 4, marginRight: 8 }}>
            {Array.from({ length: NFL_REG_WEEKS }, (_, idx) => idx + 1).map((week) => (
              <button
                key={week}
                type="button"
                onClick={() => setWeekNum(week)}
                style={{
                  width: 28, height: 28, borderRadius: 6,
                  border: `1px solid ${weekNum === week ? "var(--mint)" : "var(--green-600)"}`,
                  background: weekNum === week ? "rgba(149,249,174,0.1)" : "transparent",
                  color: weekNum === week ? "var(--mint)" : "var(--slate)",
                  fontFamily: "JetBrains Mono", fontSize: 11, cursor: "pointer",
                }}
              >
                {week}
              </button>
            ))}
          </div>
          {Object.entries(statusLabel).map(([k, v]) => (
            <span key={k} style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
              <span style={{ width: 8, height: 8, borderRadius: "50%", background: statusColor[k], boxShadow: k !== "off" ? `0 0 8px ${statusColor[k]}80` : "none" }} />
              <span className="mono" style={{ fontSize: 10, color: "var(--slate)", letterSpacing: "0.04em", textTransform: "uppercase" }}>{v}</span>
            </span>
          ))}
        </div>
      </div>

      <div style={{ position: "relative", width: "100%", aspectRatio: "2000 / 1200", background: "linear-gradient(135deg, var(--green-900), var(--black))", borderRadius: 16, overflow: "hidden", border: "1px solid var(--green-600)" }}>
        <svg viewBox="0 0 2000 1200" preserveAspectRatio="xMidYMid meet" width="100%" height="100%" style={{ display: "block" }}>
          {Array.from({ length: 11 }).map((_, i) => (
            <line key={"v" + i} x1={i * 200} y1="0" x2={i * 200} y2="1200" stroke="rgba(149,249,174,0.04)" strokeWidth="2" />
          ))}
          {Array.from({ length: 7 }).map((_, i) => (
            <line key={"h" + i} x1="0" y1={i * 200} x2="2000" y2={i * 200} stroke="rgba(149,249,174,0.04)" strokeWidth="2" />
          ))}

          {window.US_MAP_PATHS && (
            <g>
              <path d={window.US_MAP_PATHS.outline}
                    fill="rgba(217,255,228,0.08)"
                    stroke="rgba(149,249,174,0.28)"
                    strokeWidth="2"
                    strokeLinejoin="round" />
              <path d={window.US_MAP_PATHS.boundaries}
                    fill="none"
                    stroke="rgba(42,74,55,0.7)"
                    strokeWidth="1.2"
                    strokeLinecap="round"
                    strokeLinejoin="round" />
            </g>
          )}

          {(NFL_STADIUMS.length ? NFL_STADIUMS : NFL_CITIES).map((site) => {
            const stadium = site.teams ? site : { ...site, id: site.team, idleLabel: site.team, teams: [site.team], shared: false, lx: 0, ly: -28 };
            const cg = cityGameData[stadium.id] || {};
            const c = statusColor[cg.status] || statusColor.off;
            const active = cg.status && cg.status !== "off";
            const isHover = hoverCity === stadium.id;
            const label = cg.occupant ? nickFor(cg.occupant) : stadium.idleLabel;
            const lx = stadium.x + (stadium.lx || 0);
            const ly = stadium.y + (stadium.ly || -28);
            const scale = active ? (isHover ? 1.15 : 1) : 0.82;
            const heading = stadiumHeading(stadium);
            return (
              <g key={stadium.id}
                 onMouseEnter={() => { setHoverCity(stadium.id); setTooltipPos({ x: stadium.x, y: stadium.y }); }}
                 onMouseLeave={() => setHoverCity(null)}
                 style={{ cursor: "pointer" }}>
                {active && (
                  <ellipse cx={stadium.x} cy={stadium.y} rx={28} ry={20} fill={c} opacity="0.14" />
                )}
                <g transform={`translate(${stadium.x} ${stadium.y}) rotate(${heading}) scale(${scale})`}>
                  <ellipse rx="20" ry="8" fill={active ? c : "rgba(5,14,10,0.85)"} stroke={c} strokeWidth="2.2" opacity={active ? 1 : 0.85} />
                  <path d="M -10 0 Q 0 -3.5 10 0 Q 0 3.5 -10 0" fill="none" stroke={active ? "rgba(5,14,10,0.7)" : c} strokeWidth="1.3" />
                  <line x1="-16" y1="0" x2="16" y2="0" stroke={active ? "rgba(5,14,10,0.5)" : c} strokeWidth="1.1" />
                </g>
                <text x={lx} y={ly} textAnchor="middle" fontSize={stadium.shared && !cg.occupant ? 13 : 15} fontFamily="Georgia, Times, serif" fill={c} fontWeight="700" opacity={active ? 1 : 0.72} letterSpacing="0.04em">{label}</text>
              </g>
            );
          })}
        </svg>

        {hoverCity && (() => {
          const cg = cityGameData[hoverCity];
          if (!cg) return null;
          const leftPct = (tooltipPos.x / 2000) * 100;
          const topPct = (tooltipPos.y / 1200) * 100;
          const flipRight = leftPct > 70;
          const flipUp = topPct > 60;
          return (
            <div style={{
              position: "absolute",
              left: `${leftPct}%`,
              top: `${topPct}%`,
              transform: `translate(${flipRight ? "-110%" : "20px"}, ${flipUp ? "-110%" : "10px"})`,
              padding: 14,
              background: "rgba(5,8,7,0.96)",
              border: "1px solid var(--green-600)",
              borderRadius: 12,
              boxShadow: "0 16px 40px rgba(0,0,0,0.5)",
              minWidth: 240, maxWidth: 280,
              backdropFilter: "blur(8px)",
              zIndex: 10,
              pointerEvents: "none",
            }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 6 }}>
                <div>
                  <div className="mono" style={{ fontSize: 9, color: statusColor[cg.status], letterSpacing: "0.12em", textTransform: "uppercase" }}>
                    {statusLabel[cg.status]}
                  </div>
                  <div className="display" style={{ marginTop: 2, fontSize: 18, color: "var(--mint-soft)" }}>{cg.name || cg.city}</div>
                </div>
                {cg.occupant ? <TeamChip team={cg.occupant} size="sm" /> : null}
              </div>

              {cg.shared && (
                <div className="mono" style={{ marginTop: 4, fontSize: 10, color: "var(--slate)" }}>
                  Shared by {(cg.teams || []).join(" / ")} · one home team per day
                </div>
              )}

              {cg.conflict && (cg.alsoHome || []).length > 1 && (
                <div className="mono" style={{ marginTop: 6, fontSize: 11, color: "var(--gold)" }}>
                  Same-week home slate at this stadium: {(cg.alsoHome || []).join(" / ")}. Showing {cg.occupant}.
                </div>
              )}

              {cg.status !== "off" && cg.opponent && (
                <div style={{ marginTop: 8, fontSize: 12, color: "var(--mint-soft)" }}>
                  <span className="mono" style={{ fontSize: 10, color: "var(--slate)" }}>Home this week</span>
                  <div style={{ marginTop: 3 }}>{cg.occupant} vs {cg.opponent}</div>
                </div>
              )}

              {cg.status !== "off" && (
                <div className="mono" style={{ marginTop: 8, fontSize: 11, color: "var(--slate)", letterSpacing: "0.02em" }}>
                  {cg.kickoff} · {cg.weather}
                </div>
              )}

              {cg.oppPlayers && cg.oppPlayers.length > 0 && (
                <div style={{ marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--green-600)" }}>
                  <div className="mono" style={{ fontSize: 9, color: "#7BD9F4", letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 6 }}>Opponent ({cg.oppPlayers.length})</div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                    {cg.oppPlayers.map((p) => (
                      <div key={p.id} style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                        <span style={{ fontSize: 12, color: "var(--mint-soft)" }}>{p.name}</span>
                        <span className="mono" style={{ fontSize: 10, color: "#7BD9F4" }}>{p.pos}</span>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {cg.homePlayers && cg.homePlayers.length > 0 && (
                <div style={{ marginTop: 10, paddingTop: 10, borderTop: "1px solid var(--green-600)" }}>
                  <div className="mono" style={{ fontSize: 9, color: "var(--mint)", letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 6 }}>Your players ({cg.homePlayers.length})</div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
                    {cg.homePlayers.map((p) => (
                      <div key={p.id} style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                        <span style={{ fontSize: 12, color: "var(--mint-soft)" }}>{p.name}</span>
                        <span className="mono" style={{ fontSize: 10, color: "var(--mint)" }}>{p.pos} · {(p.proj || 0).toFixed(1)} proj</span>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {cg.status === "off" && (
                <div className="mono" style={{ marginTop: 8, fontSize: 11, color: "var(--slate-dim)" }}>
                  {cg.shared
                    ? `No home game this week (${(cg.teams || []).join(" / ")} on the road or bye).`
                    : (live ? "No home game mapped for this stadium this week." : "No home game this week.")}
                </div>
              )}
            </div>
          );
        })()}
      </div>

      <div className="mono" style={{ marginTop: 10, fontSize: 10, color: "var(--slate)", letterSpacing: "0.03em", lineHeight: 1.5 }}>
        30 stadiums · SoFi (Rams / Chargers) and MetLife (Giants / Jets) keep one pin · occupant follows the home team that week
      </div>

      <YourGamesStrip roster={roster} cityGameData={cityGameData} schedule={schedule} onSelectPlayer={onSelectPlayer} />
      <LeagueScheduleSection activeLeague={activeLeague} live={live} />
    </div>
  );
}

function YourGamesStrip({ roster, cityGameData, schedule, onSelectPlayer }) {
  const games = (roster || []).map((p) => {
    const game = (schedule || []).find((g) => g.homeTeam === p.team || g.awayTeam === p.team);
    const ctx = cityGameData[game?.homeTeam] || cityGameData[p.team];
    return { player: p, ctx };
  });

  return (
    <div style={{ marginTop: 18 }}>
      <div className="mono" style={{ fontSize: 10, color: "var(--mint)", letterSpacing: "0.14em", textTransform: "uppercase", marginBottom: 10 }}>Your players this week</div>
      {!games.length ? (
        <div style={{ padding: 12, color: "var(--slate)", fontSize: 13 }}>No roster players to map yet.</div>
      ) : (
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 8 }}>
          {games.map(({ player, ctx }) => (
            <button key={player.id} onClick={() => onSelectPlayer && onSelectPlayer(player)} style={{
              display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10,
              padding: 10, borderRadius: 8,
              background: "var(--green-900)", border: "1px solid var(--green-600)",
              cursor: "pointer", textAlign: "left",
              transition: "border-color 0.12s",
            }}
              onMouseEnter={(e) => { e.currentTarget.style.borderColor = "var(--mint)"; }}
              onMouseLeave={(e) => { e.currentTarget.style.borderColor = "var(--green-600)"; }}>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 12, color: "var(--mint-soft)", fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{player.name}</div>
                <div className="mono" style={{ fontSize: 10, color: "var(--slate)", marginTop: 2, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                  {player.pos} · {ctx ? ctx.city : player.team} · {ctx && !ctx.indoor ? "Outdoor" : "Dome"}
                </div>
              </div>
              <div style={{ textAlign: "right", flexShrink: 0 }}>
                <div className="num" style={{ fontSize: 14, color: "var(--mint)" }}>{(player.proj || 0).toFixed(1)}</div>
                <div className="mono" style={{ fontSize: 9, color: "var(--slate-dim)" }}>proj</div>
              </div>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

const FANTASY_REG_WEEKS = 13;

function scheduleStorageKey(leagueId) {
  return `949fantasy.league-schedule.v1.${leagueId || "local"}`;
}

function defaultLeagueTeams(activeLeague, live) {
  if (activeLeague?.teams?.length) {
    return activeLeague.teams.map((team) => ({
      slot: Number(team.slot),
      name: team.name || `Team ${team.slot}`,
      isUserTeam: !!team.isUserTeam,
    }));
  }
  const count = Number(activeLeague?.teamCount || live?.standings?.length || 12);
  const userName = live?.teamName || activeLeague?.teamName || "My Team";
  const userSlot = Number(activeLeague?.draftPosition || 1);
  return Array.from({ length: count }, (_, idx) => {
    const slot = idx + 1;
    return {
      slot,
      name: slot === userSlot ? userName : `Team ${slot}`,
      isUserTeam: slot === userSlot,
    };
  });
}

function emptyGrid(teamCount) {
  const grid = {};
  for (let week = 1; week <= FANTASY_REG_WEEKS; week += 1) {
    grid[week] = {};
    for (let slot = 1; slot <= teamCount; slot += 1) grid[week][slot] = null;
  }
  return grid;
}

function loadScheduleGrid(leagueId, teamCount) {
  const fallback = emptyGrid(teamCount);
  try {
    const raw = window.localStorage.getItem(scheduleStorageKey(leagueId));
    if (!raw) return fallback;
    const parsed = JSON.parse(raw);
    if (!parsed || typeof parsed !== "object") return fallback;
    const grid = emptyGrid(teamCount);
    for (let week = 1; week <= FANTASY_REG_WEEKS; week += 1) {
      const row = parsed[week] || parsed[String(week)] || {};
      for (let slot = 1; slot <= teamCount; slot += 1) {
        const opp = Number(row[slot] || row[String(slot)]);
        grid[week][slot] = Number.isFinite(opp) && opp >= 1 && opp <= teamCount && opp !== slot ? opp : null;
      }
    }
    return grid;
  } catch (error) {
    return fallback;
  }
}

function saveScheduleGrid(leagueId, grid) {
  window.localStorage.setItem(scheduleStorageKey(leagueId), JSON.stringify(grid));
}

function pairCount(grid, slot, teamCount) {
  let filled = 0;
  for (let week = 1; week <= FANTASY_REG_WEEKS; week += 1) {
    if (grid[week]?.[slot]) filled += 1;
  }
  return filled;
}

function LeagueScheduleSection({ activeLeague, live }) {
  const teams = defaultLeagueTeams(activeLeague, live);
  const leagueId = activeLeague?.id || "local";
  const [open, setOpen] = React.useState(() => !!window.__openLeagueSchedule);
  const [editSlot, setEditSlot] = React.useState(() => teams.find((t) => t.isUserTeam)?.slot || teams[0]?.slot || 1);
  const [viewWeek, setViewWeek] = React.useState(1);
  const [grid, setGrid] = React.useState(() => loadScheduleGrid(leagueId, teams.length));

  React.useEffect(() => {
    setGrid(loadScheduleGrid(leagueId, teams.length));
    setEditSlot(teams.find((t) => t.isUserTeam)?.slot || teams[0]?.slot || 1);
  }, [leagueId, teams.length]);

  React.useEffect(() => {
    if (window.__openLeagueSchedule) {
      setOpen(true);
      window.__openLeagueSchedule = false;
    }
  }, []);

  function setOpponent(slot, week, opponentSlot) {
    setGrid((prev) => {
      const next = emptyGrid(teams.length);
      for (let wk = 1; wk <= FANTASY_REG_WEEKS; wk += 1) {
        for (let s = 1; s <= teams.length; s += 1) next[wk][s] = prev[wk]?.[s] ?? null;
      }
      const prevOpp = next[week][slot];
      if (prevOpp) {
        if (next[week][prevOpp] === slot) next[week][prevOpp] = null;
      }
      const opp = opponentSlot ? Number(opponentSlot) : null;
      if (!opp) {
        next[week][slot] = null;
      } else {
        const displaced = next[week][opp];
        if (displaced && displaced !== slot && next[week][displaced] === opp) next[week][displaced] = null;
        next[week][slot] = opp;
        next[week][opp] = slot;
      }
      saveScheduleGrid(leagueId, next);
      window.dispatchEvent(new CustomEvent("league-schedule", { detail: { leagueId } }));
      return next;
    });
  }

  const nameFor = (slot) => teams.find((t) => t.slot === slot)?.name || `Team ${slot}`;
  const weekPairings = [];
  const seen = new Set();
  for (let slot = 1; slot <= teams.length; slot += 1) {
    const opp = grid[viewWeek]?.[slot];
    if (!opp || seen.has(slot)) continue;
    seen.add(slot);
    seen.add(opp);
    weekPairings.push({ home: slot, away: opp });
  }
  const unscheduled = teams.filter((t) => !seen.has(t.slot));
  const savedAny = Object.values(grid).some((row) => Object.values(row).some(Boolean));

  return (
    <div style={{ marginTop: 20, paddingTop: 18, borderTop: "1px solid var(--green-600)" }}>
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        className="btn outline"
        style={{ padding: "8px 14px", fontSize: 13 }}
      >
        {open ? "Hide league schedule" : "+Add League Schedule"}
      </button>
      <div className="mono" style={{ marginTop: 8, fontSize: 10, color: "var(--slate)" }}>
        {savedAny
          ? `${teams.length} teams · 13 regular-season games each · stored on this device`
          : "Enter each opponent’s 13-game slate, then scroll the weekly league matchups below."}
      </div>

      {open && (
        <div style={{ marginTop: 16 }}>
          <div className="mono" style={{ fontSize: 10, color: "var(--mint)", letterSpacing: "0.12em", textTransform: "uppercase", marginBottom: 10 }}>
            Team by team
          </div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginBottom: 14 }}>
            {teams.map((team) => {
              const filled = pairCount(grid, team.slot, teams.length);
              const active = editSlot === team.slot;
              return (
                <button
                  key={team.slot}
                  type="button"
                  onClick={() => setEditSlot(team.slot)}
                  style={{
                    padding: "7px 10px",
                    borderRadius: 8,
                    border: `1px solid ${active ? "var(--mint)" : "var(--green-600)"}`,
                    background: active ? "rgba(149,249,174,0.08)" : "var(--green-900)",
                    color: active ? "var(--mint)" : "var(--mint-soft)",
                    fontFamily: "Sora",
                    fontSize: 12,
                    cursor: "pointer",
                  }}
                >
                  {team.name}{team.isUserTeam ? " · you" : ""} · {filled}/{FANTASY_REG_WEEKS}
                </button>
              );
            })}
          </div>

          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 8 }}>
            {Array.from({ length: FANTASY_REG_WEEKS }, (_, idx) => idx + 1).map((week) => {
              const current = grid[week]?.[editSlot] || "";
              return (
                <label key={week} style={{ display: "flex", flexDirection: "column", gap: 6, padding: 10, borderRadius: 8, border: "1px solid var(--green-600)", background: "var(--green-900)" }}>
                  <span className="mono" style={{ fontSize: 10, color: "var(--slate)", letterSpacing: "0.08em", textTransform: "uppercase" }}>Week {week}</span>
                  <select
                    value={current}
                    onChange={(e) => setOpponent(editSlot, week, e.target.value)}
                    style={{
                      background: "var(--black)",
                      color: "var(--mint-soft)",
                      border: "1px solid var(--green-600)",
                      borderRadius: 6,
                      padding: "7px 8px",
                      fontFamily: "Sora",
                      fontSize: 12,
                    }}
                  >
                    <option value="">Bye / TBD</option>
                    {teams.filter((t) => t.slot !== editSlot).map((t) => (
                      <option key={t.slot} value={t.slot}>{t.name}</option>
                    ))}
                  </select>
                </label>
              );
            })}
          </div>
        </div>
      )}

      <div style={{ marginTop: 22 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 10, marginBottom: 10 }}>
          <div className="mono" style={{ fontSize: 10, color: "var(--mint)", letterSpacing: "0.14em", textTransform: "uppercase" }}>
            League games · Week {viewWeek}
          </div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 4 }}>
            {Array.from({ length: FANTASY_REG_WEEKS }, (_, idx) => idx + 1).map((week) => (
              <button
                key={week}
                type="button"
                onClick={() => setViewWeek(week)}
                style={{
                  width: 28, height: 28, borderRadius: 6,
                  border: `1px solid ${viewWeek === week ? "var(--mint)" : "var(--green-600)"}`,
                  background: viewWeek === week ? "rgba(149,249,174,0.1)" : "transparent",
                  color: viewWeek === week ? "var(--mint)" : "var(--slate)",
                  fontFamily: "JetBrains Mono", fontSize: 11, cursor: "pointer",
                }}
              >
                {week}
              </button>
            ))}
          </div>
        </div>
        {!weekPairings.length ? (
          <div style={{ padding: 14, color: "var(--slate)", fontSize: 13 }}>
            No league matchups for Week {viewWeek} yet. Use +Add League Schedule and fill teams one at a time.
          </div>
        ) : (
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(260px, 1fr))", gap: 8 }}>
            {weekPairings.map((game) => {
              const userIn = teams.some((t) => t.isUserTeam && (t.slot === game.home || t.slot === game.away));
              return (
                <div key={`${game.home}-${game.away}`} style={{
                  padding: 12, borderRadius: 8,
                  border: `1px solid ${userIn ? "rgba(149,249,174,0.45)" : "var(--green-600)"}`,
                  background: userIn ? "rgba(149,249,174,0.06)" : "var(--green-900)",
                }}>
                  <div className="mono" style={{ fontSize: 9, color: userIn ? "var(--mint)" : "var(--slate)", letterSpacing: "0.1em", textTransform: "uppercase" }}>
                    {userIn ? "Your matchup" : "League game"}
                  </div>
                  <div style={{ marginTop: 6, color: "var(--mint-soft)", fontSize: 14, fontWeight: 600 }}>
                    {nameFor(game.home)} vs {nameFor(game.away)}
                  </div>
                </div>
              );
            })}
          </div>
        )}
        {unscheduled.length ? (
          <div className="mono" style={{ marginTop: 10, fontSize: 10, color: "var(--slate-dim)" }}>
            Unscheduled this week: {unscheduled.map((t) => t.name).join(", ")}
          </div>
        ) : null}
      </div>
    </div>
  );
}

Object.assign(window, { StadiumMap });
