const WAIVER_COLS = "56px minmax(220px, 1.6fr) 72px 100px 70px 90px 150px 120px 72px";

function WaiverView({ onSelectPlayer, activeLeague, session, onSwapWaiver }) {
  const live = window.useLiveLeague ? window.useLiveLeague(activeLeague) : null;
  const nflStatus = window.useNflDataStatus ? window.useNflDataStatus() : {};
  const [pos, setPos] = React.useState("ALL");
  const [rankingFormat, setRankingFormat] = React.useState(activeLeague?.scoring === "standard" ? "std" : (activeLeague?.scoring || "ppr"));
  const [search, setSearch] = React.useState("");
  const [addPlayer, setAddPlayer] = React.useState(null);

  const rankingFormatFor = window.rankingFormatFor;
  const enrichForScoring = window.enrichForScoring;
  const sortRankedPlayers = window.sortRankedPlayers;
  const FORMAT_TABS = window.FORMAT_TABS || [];
  const TIER_ORDER = window.TIER_ORDER || ["A+", "A", "B", "C", "D", "F"];
  const VALUE_TIER_META = window.VALUE_TIER_META || {};

  const activeFormat = React.useMemo(
    () => (rankingFormatFor ? rankingFormatFor(rankingFormat) : { scoring: rankingFormat, label: rankingFormat, settings: {} }),
    [rankingFormat],
  );
  const scoring = activeFormat.scoring || rankingFormat;

  const basePlayers = React.useMemo(
    () => (window.buildDraftPool ? window.buildDraftPool(window.PLAYERS || [], scoring) : (window.PLAYERS || [])),
    [nflStatus.projections, nflStatus.projectionsLoaded, scoring],
  );
  const enriched = React.useMemo(
    () => (enrichForScoring ? enrichForScoring(basePlayers, activeFormat) : basePlayers),
    [basePlayers, activeFormat],
  );

  const draftFinished = !session
    || activeLeague?.draftStatus === "complete"
    || (activeLeague?.picks || []).length > 0;
  const draftedIds = new Set(
    (activeLeague?.picks || [])
      .map((pick) => pick.playerId)
      .filter(Boolean),
  );
  const draftedNames = new Set(
    (activeLeague?.picks || [])
      .map((pick) => (pick.playerName || "").toLowerCase())
      .filter(Boolean),
  );
  const draftedAliases = new Set(
    (activeLeague?.picks || []).flatMap((pick) => {
      const aliases = window.playerIdAliases ? window.playerIdAliases(pick.playerId) : [pick.playerId];
      return aliases.filter(Boolean);
    }),
  );

  const availablePool = React.useMemo(() => {
    if (!session) return enriched.filter((p) => !p.unranked || p.pos === "DST" || p.pos === "K");
    return enriched.filter((p) => {
      if (p.unranked && p.pos !== "DST" && p.pos !== "K") return false;
      const aliases = window.playerIdAliases ? window.playerIdAliases(p.id) : [p.id];
      if (aliases.some((alias) => draftedIds.has(alias) || draftedAliases.has(alias))) return false;
      if (draftedNames.has((p.name || "").toLowerCase())) return false;
      return true;
    });
  }, [enriched, session, draftedIds.size, draftedAliases.size, draftedNames.size, activeLeague?.picks?.length]);

  const filtered = React.useMemo(() => {
    const positionFiltered = availablePool
      .filter((p) => pos === "ALL" || p.pos === pos)
      .filter((p) => !search || `${p.name} ${p.team} ${p.pos}`.toLowerCase().includes(search.toLowerCase()));
    return sortRankedPlayers
      ? sortRankedPlayers(positionFiltered, scoring, pos === "DST" || pos === "K" ? pos : pos)
      : positionFiltered.sort((a, b) => (b.adjusted || b.proj || 0) - (a.adjusted || a.proj || 0));
  }, [availablePool, pos, search, scoring]);

  const byTier = Object.fromEntries(TIER_ORDER.map((t) => [t, []]));
  const displayedPlayers = pos === "ALL"
    ? filtered
    : TIER_ORDER.flatMap((tier) => filtered
      .map((player, index) => ({
        ...player,
        displayRank: index + 1,
        tier: window.tierForOrderedRank ? window.tierForOrderedRank(index, filtered.length) : tier,
      }))
      .filter((p) => p.tier === tier));
  const riskTierByPlayerId = window.riskTierMapFor ? window.riskTierMapFor(displayedPlayers) : {};
  displayedPlayers.forEach((p) => { if (byTier[p.tier]) byTier[p.tier].push(p); });

  const userRoster = live?.roster?.length
    ? live.roster
    : (activeLeague?.picks || [])
      .filter((pick) => Number(pick.teamSlot) === Number(activeLeague?.draftPosition || 1))
      .map((pick) => ({
        id: pick.playerId,
        name: pick.playerName,
        pos: pick.playerPosition || "FLEX",
        team: pick.playerTeam || "",
      }));

  async function dropAndAdd(dropPlayer) {
    if (typeof onSwapWaiver !== "function" || !activeLeague?.id) return;
    const result = await onSwapWaiver(activeLeague.id, dropPlayer, addPlayer);
    if (result?.ok) setAddPlayer(null);
  }

  const countFor = (position) => (
    position === "ALL"
      ? availablePool.length
      : availablePool.filter((p) => p.pos === position).length
  );

  if (session && !draftFinished) {
    return (
      <div className="view-enter" style={{ maxWidth: 900, margin: "0 auto", padding: "48px 24px" }}>
        <div className="card" style={{ padding: 28 }}>
          <div className="mono" style={{ color: "var(--mint)", fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase" }}>Roster · Waiver</div>
          <h1 className="display" style={{ margin: "10px 0 8px", color: "var(--mint-soft)" }}>Waiver wire locked</h1>
          <p style={{ margin: 0, color: "var(--slate)", lineHeight: 1.6 }}>
            Finish Draft Live and confirm Draft Finished to populate remaining players here.
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="view-enter" style={{ maxWidth: 1440, margin: "0 auto", padding: "24px 24px 32px" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", marginBottom: 18, flexWrap: "wrap", gap: 16 }}>
        <div>
          <div className="mono" style={{ fontSize: 10, color: "var(--mint)", textTransform: "uppercase", letterSpacing: "0.18em", marginBottom: 6 }}>
            Roster · Waiver
          </div>
          <h1 className="display" style={{ margin: 0, fontSize: 32, color: "var(--mint-soft)", lineHeight: 1 }}>Waiver Wire</h1>
          <p style={{ marginTop: 6, color: "var(--slate)", fontSize: 13 }}>
            {session
              ? `${availablePool.length} undrafted players · ADD to swap onto ${live?.teamName || "your roster"}`
              : "Demo board · full pre-season pool"}
          </p>
        </div>
        <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
          <div style={{
            display: "flex", alignItems: "center", gap: 8,
            padding: "9px 12px", borderRadius: 10,
            border: "1px solid var(--green-600)", background: "var(--green-900)",
            minWidth: 240,
          }}>
            <window.IconSearch size={13} stroke="var(--slate)" />
            <input value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Search player, team, position"
              style={{ background: "transparent", border: "none", outline: "none", color: "var(--mint-soft)", fontFamily: "Sora", fontSize: 13, width: "100%" }} />
          </div>
          {FORMAT_TABS.length ? <TabBar tabs={FORMAT_TABS} value={rankingFormat} onChange={setRankingFormat} /> : null}
        </div>
      </div>

      <div style={{ marginBottom: 14 }}>
        <TabBar tabs={[
          { id: "ALL", label: "Overall", count: countFor("ALL") },
          { id: "QB",  label: "QB", count: countFor("QB") },
          { id: "RB",  label: "RB", count: countFor("RB") },
          { id: "WR",  label: "WR", count: countFor("WR") },
          { id: "TE",  label: "TE", count: countFor("TE") },
          { id: "DST", label: "DST", count: countFor("DST") },
          { id: "K",   label: "K", count: countFor("K") },
        ]} value={pos} onChange={setPos} />
      </div>

      <div className="card" style={{ overflow: "visible" }}>
        <div style={{
          display: "grid", gridTemplateColumns: WAIVER_COLS,
          padding: "12px 18px", background: "var(--green-900)",
          borderBottom: "1px solid var(--green-600)",
          fontSize: 10, color: "var(--slate)", textTransform: "uppercase", letterSpacing: "0.1em",
          fontFamily: "JetBrains Mono", fontWeight: 600, alignItems: "center",
        }}>
          <DrHeadCell align="center">Rank</DrHeadCell>
          <DrHeadCell align="flex-start">Player</DrHeadCell>
          <DrHeadCell align="center">{session ? "Add" : ""}</DrHeadCell>
          <DrHeadCell align="center">Proj</DrHeadCell>
          <DrHeadCell align="center">Bye</DrHeadCell>
          <DrHeadCell align="center">Risk</DrHeadCell>
          <DrHeadCell align="center">Boom/Bust</DrHeadCell>
          <DrHeadCell align="center">YoY Pts/Gm</DrHeadCell>
          <DrHeadCell align="flex-end">Value</DrHeadCell>
        </div>

        {pos === "ALL" ? filtered.map((p, index) => (
          <WaiverRankRow
            key={p.id}
            player={p}
            rowRank={index + 1}
            scoring={scoring}
            riskTier={riskTierByPlayerId[p.id]}
            showAdd={!!session}
            onSelectPlayer={onSelectPlayer}
            onAdd={() => setAddPlayer(p)}
          />
        )) : TIER_ORDER.map((tier) => {
          const tierPlayers = byTier[tier];
          if (!tierPlayers || !tierPlayers.length) return null;
          const meta = VALUE_TIER_META[tier] || { color: "var(--slate)", label: tier, note: "" };
          const range = window.rankTierRangeLabel ? window.rankTierRangeLabel(tier, filtered.length) : "";
          return (
            <React.Fragment key={tier}>
              <div style={{
                display: "flex", alignItems: "center", gap: 14,
                padding: "12px 18px",
                background: "rgba(149,249,174,0.04)",
                borderBottom: "1px solid var(--green-600)",
              }}>
                <span className="num" style={{ fontSize: 14, color: meta.color, fontWeight: 900 }}>{tier}</span>
                <span className="mono" style={{ fontSize: 10, color: meta.color, letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 700 }}>
                  {meta.label} · {range}
                </span>
                <span style={{ flex: 1, height: 1, background: "linear-gradient(to right, var(--green-600), transparent)" }} />
                <span className="mono" style={{ fontSize: 10, color: "var(--slate-dim)" }}>{tierPlayers.length}</span>
              </div>
              {tierPlayers.map((p) => (
                <WaiverRankRow
                  key={p.id}
                  player={p}
                  rowRank={p.displayRank}
                  scoring={scoring}
                  riskTier={riskTierByPlayerId[p.id]}
                  showAdd={!!session}
                  onSelectPlayer={onSelectPlayer}
                  onAdd={() => setAddPlayer(p)}
                />
              ))}
            </React.Fragment>
          );
        })}

        {!filtered.length && (
          <div style={{ padding: 60, textAlign: "center", color: "var(--slate)", fontSize: 14 }}>
            No players on waiver for this filter.
          </div>
        )}
      </div>

      {addPlayer && (
        <WaiverAddModal
          addPlayer={addPlayer}
          roster={userRoster}
          teamName={live?.teamName || activeLeague?.teamName || "Your team"}
          onDrop={dropAndAdd}
          onClose={() => setAddPlayer(null)}
        />
      )}
    </div>
  );
}

function DrHeadCell({ children, align = "flex-start" }) {
  return (
    <div style={{ display: "flex", alignItems: "center", justifyContent: align, minWidth: 0, padding: "0 6px" }}>
      {children}
    </div>
  );
}

function WaiverRankRow({ player, rowRank, scoring, riskTier, showAdd, onSelectPlayer, onAdd }) {
  const projTotal = (player.adjusted || player.proj || 0) * 17;
  const yoy = window.yoyTrendData ? window.yoyTrendData(player) : null;
  const yoyProfile = window.yoyTrendProfile ? window.yoyTrendProfile(yoy?.values) : { color: "var(--slate)" };
  const valueGrade = window.seasonValueGrade ? window.seasonValueGrade(player) : { letter: "—", color: "var(--slate)" };
  const bye = player.byeWeek || player.bye;
  const Risk = window.DrRiskProfile;
  const Boom = window.DrBoomBustProfile;
  const Value = window.DrValueProfile;

  return (
    <div style={{
      display: "grid", gridTemplateColumns: WAIVER_COLS, gap: 0, padding: "12px 18px",
      borderBottom: "1px solid var(--green-600)",
      alignItems: "center",
    }}>
      <div style={{ textAlign: "center" }}>
        <span className="num" style={{ fontSize: 17, color: "var(--mint-soft)" }}>{rowRank}</span>
      </div>
      <button onClick={() => onSelectPlayer && !player.synthetic && onSelectPlayer(player)} style={{
        background: "transparent", border: "none", padding: 0, textAlign: "left", cursor: player.synthetic ? "default" : "pointer",
      }}>
        <PlayerCell player={player} />
      </button>
      <div style={{ display: "flex", justifyContent: "center" }}>
        {showAdd && (
          <button className="btn" style={{ padding: "5px 10px", fontSize: 10 }} onClick={(e) => { e.stopPropagation(); onAdd(); }}>
            ADD
          </button>
        )}
      </div>
      <div style={{ textAlign: "center" }}>
        <span className="num" style={{ fontSize: 16, color: "var(--mint)" }}>{projTotal.toFixed(0)}</span>
      </div>
      <div style={{ textAlign: "center" }}>
        <span className="mono" style={{ fontSize: 11, color: "var(--slate-dim)" }}>{bye ? `W${bye}` : "TBD"}</span>
      </div>
      <div style={{ display: "flex", justifyContent: "center" }}>
        {Risk ? <Risk player={player} riskTier={riskTier} /> : null}
      </div>
      <div style={{ display: "flex", justifyContent: "center" }}>
        {Boom ? <Boom player={player} scoring={scoring} /> : null}
      </div>
      <div style={{ display: "flex", justifyContent: "center" }}>
        {yoy?.values && yoy.values.length >= 2
          ? <Sparkline data={yoy.values} width={96} height={28} color={yoyProfile.color} projectedTail />
          : <span className="mono" style={{ fontSize: 9, color: "var(--slate-dim)" }}>No Data</span>}
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end" }}>
        {Value ? <Value player={player} valueGrade={valueGrade} /> : <span className="num" style={{ color: valueGrade.color }}>{valueGrade.letter}</span>}
      </div>
    </div>
  );
}

function WaiverAddModal({ addPlayer, roster, teamName, onDrop, onClose }) {
  return (
    <div style={{
      position: "fixed", inset: 0, zIndex: 72, display: "flex", alignItems: "center", justifyContent: "center",
      padding: 24, background: "rgba(5,8,7,0.78)", backdropFilter: "blur(8px)",
    }}>
      <div className="card" style={{ width: "min(520px, 100%)", maxHeight: "86vh", overflow: "auto", padding: 24, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" }}>
        <div className="mono" style={{ color: "var(--mint)", fontSize: 10, letterSpacing: "0.16em", textTransform: "uppercase" }}>Add from waiver</div>
        <h2 className="display" style={{ margin: "8px 0 8px", color: "var(--mint-soft)", fontSize: 24, lineHeight: 1.15 }}>
          Drop a player to add {addPlayer.name}
        </h2>
        <p style={{ color: "var(--slate)", fontSize: 13, lineHeight: 1.55, marginBottom: 14 }}>
          {teamName} · {addPlayer.pos} {addPlayer.team} · DROP someone to complete the swap. The dropped player returns to waiver.
        </p>
        <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          {(roster || []).map((player) => (
            <div key={player.id || player.name} style={{
              display: "grid", gridTemplateColumns: "1fr auto auto", gap: 12, alignItems: "center",
              padding: "10px 12px", borderRadius: 10,
              background: "var(--green-900)", border: "1px solid var(--green-600)",
            }}>
              <span style={{ color: "var(--mint-soft)", fontWeight: 600, fontSize: 14 }}>{player.name}</span>
              <span className="mono" style={{ color: "var(--slate)", fontSize: 11, letterSpacing: "0.08em" }}>{player.pos}</span>
              <button
                onClick={() => onDrop(player)}
                style={{
                  padding: "6px 12px", borderRadius: 8, border: "1px solid var(--red)",
                  background: "rgba(255,94,94,0.12)", color: "var(--red)",
                  fontFamily: "JetBrains Mono", fontSize: 10, fontWeight: 800, letterSpacing: "0.08em",
                  cursor: "pointer",
                }}
              >
                DROP
              </button>
            </div>
          ))}
          {!roster?.length && (
            <div style={{ padding: 16, color: "var(--slate)", fontSize: 13 }}>No roster players to drop.</div>
          )}
        </div>
        <div style={{ display: "flex", justifyContent: "flex-end", marginTop: 18 }}>
          <button className="btn ghost" onClick={onClose}>Cancel</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { WaiverView });
