/**
 * Tests for draft room reconnection state synchronization.
 *
 * These tests validate the core sync logic that runs when a mobile user
 * returns from a long background period. They exercise the handler functions
 * and state sync patterns in isolation, verifying:
 *
 * 1. All picks made during the offline window are visible after reconnection
 * 2. The correct person is shown as "on the clock"
 * 3. Available players list is accurate (drafted players excluded)
 * 4. Timer-update events immediately sync currentPickNumber
 * 5. draft-state-sync event provides a full snapshot for instant sync
 * 6. Revalidation retry ensures the HTTP path also succeeds
 * 7. Buffered picks during revalidation are properly merged
 */

import { describe, it, expect, vi, beforeEach } from "vitest";
import { getTeamForPick } from "~/lib/draft-order";

// ---------------------------------------------------------------------------
// Fixtures
// ---------------------------------------------------------------------------

function makeDraftSlots(count: number) {
  return Array.from({ length: count }, (_, i) => ({
    id: `slot-${i + 1}`,
    seasonId: "season-1",
    teamId: `team-${i + 1}`,
    draftOrder: i + 1,
    team: {
      id: `team-${i + 1}`,
      name: `Team ${i + 1}`,
      seasonId: "season-1",
      ownerId: `user-${i + 1}`,
    },
  }));
}

function makePick(pickNumber: number, teamId: string, participantId: string) {
  const teamCount = 4; // default for tests
  const round = Math.ceil(pickNumber / teamCount);
  const pickInRound = ((pickNumber - 1) % teamCount) + 1;
  return {
    id: `pick-${pickNumber}`,
    pickNumber,
    round,
    pickInRound,
    timeUsed: 100,
    team: {
      id: teamId,
      name: `Team ${teamId.split("-")[1]}`,
      seasonId: "season-1",
      ownerId: `user-${teamId.split("-")[1]}`,
    },
    participant: {
      id: participantId,
      name: `Player ${participantId.split("-")[1]}`,
    },
    sport: { id: "sport-1", name: "NFL" },
  };
}

function makeParticipant(id: string, name: string, sportId = "sport-1", sportName = "NFL") {
  return { id, name, sport: { id: sportId, name: sportName } };
}

// ---------------------------------------------------------------------------
// 1. draft-order helper validates correctly for snake draft
// ---------------------------------------------------------------------------

describe("getTeamForPick – snake draft order", () => {
  const draftSlots = makeDraftSlots(4);

  it("round 1 (odd): picks go 1→4", () => {
    expect(getTeamForPick(1, draftSlots)?.team.id).toBe("team-1");
    expect(getTeamForPick(2, draftSlots)?.team.id).toBe("team-2");
    expect(getTeamForPick(3, draftSlots)?.team.id).toBe("team-3");
    expect(getTeamForPick(4, draftSlots)?.team.id).toBe("team-4");
  });

  it("round 2 (even): picks go 4→1 (snake)", () => {
    expect(getTeamForPick(5, draftSlots)?.team.id).toBe("team-4");
    expect(getTeamForPick(6, draftSlots)?.team.id).toBe("team-3");
    expect(getTeamForPick(7, draftSlots)?.team.id).toBe("team-2");
    expect(getTeamForPick(8, draftSlots)?.team.id).toBe("team-1");
  });

  it("round 3 (odd): picks go 1→4 again", () => {
    expect(getTeamForPick(9, draftSlots)?.team.id).toBe("team-1");
    expect(getTeamForPick(12, draftSlots)?.team.id).toBe("team-4");
  });
});

// ---------------------------------------------------------------------------
// 2. timer-update handler syncs currentPickNumber
// ---------------------------------------------------------------------------

describe("timer-update handler – currentPickNumber sync", () => {
  it("updates currentPick from timer-update data", () => {
    let currentPick = 5;
    const setCurrentPick = (value: number) => { currentPick = value; };
    let teamTimers: Record<string, number> = {};
    const setTeamTimers = (fn: (prev: Record<string, number>) => Record<string, number>) => {
      teamTimers = fn(teamTimers);
    };

    // Simulate the timer-update handler from the draft room component
    const handleTimerUpdate = (data: any) => {
      setTeamTimers((prev) => ({
        ...prev,
        [data.teamId]: data.timeRemaining,
      }));
      if (data.currentPickNumber !== null) {
        setCurrentPick(data.currentPickNumber);
      }
    };

    // Timer update for pick 25 (user was away, picks advanced from 5 to 25)
    handleTimerUpdate({
      seasonId: "season-1",
      teamId: "team-2",
      timeRemaining: 85,
      currentPickNumber: 25,
    });

    expect(currentPick).toBe(25);
    expect(teamTimers["team-2"]).toBe(85);
  });

  it("does not update currentPick when currentPickNumber is null", () => {
    let currentPick = 5;
    const setCurrentPick = (value: number) => { currentPick = value; };

    const handleTimerUpdate = (data: any) => {
      if (data.currentPickNumber !== null) {
        setCurrentPick(data.currentPickNumber);
      }
    };

    handleTimerUpdate({
      seasonId: "season-1",
      teamId: "team-1",
      timeRemaining: 100,
      currentPickNumber: null,
    });

    expect(currentPick).toBe(5);
  });
});

// ---------------------------------------------------------------------------
// 3. draft-state-sync handler – full state snapshot
// ---------------------------------------------------------------------------

describe("draft-state-sync handler – full state sync on reconnection", () => {
  it("syncs picks, currentPick, isPaused, and isDraftComplete from server snapshot", () => {
    // Initial state (stale – from before mobile background)
    let picks = [makePick(1, "team-1", "player-1")];
    let currentPick = 2;
    let isPaused = false;
    let isDraftComplete = false;
    let teamTimers: Record<string, number> = { "team-1": 100, "team-2": 120 };

    const setPicks = (value: any) => { picks = value; };
    const setCurrentPick = (value: number) => { currentPick = value; };
    const setIsPaused = (value: boolean) => { isPaused = value; };
    const setIsDraftComplete = (value: boolean) => { isDraftComplete = value; };
    const setTeamTimers = (fn: (prev: Record<string, number>) => Record<string, number>) => {
      teamTimers = fn(teamTimers);
    };
    const isRevalidatingRef = { current: false };

    // Simulate the draft-state-sync handler
    const handleDraftStateSync = (data: any) => {
      if (!isRevalidatingRef.current) {
        setPicks(data.picks);
        setCurrentPick(data.currentPickNumber);
        setIsPaused(data.isPaused);
        setIsDraftComplete(
          data.status === "active" || data.status === "completed"
        );
        if (data.timers) {
          setTeamTimers((prev) => {
            const updated = { ...prev };
            data.timers.forEach((t: any) => {
              updated[t.teamId] = t.timeRemaining;
            });
            return updated;
          });
        }
      }
    };

    // Server sends full state after join-draft on reconnect
    const serverPicks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
      makePick(4, "team-4", "player-4"),
      makePick(5, "team-4", "player-5"),
      makePick(6, "team-3", "player-6"),
    ];

    handleDraftStateSync({
      currentPickNumber: 7,
      isPaused: false,
      status: "draft",
      picks: serverPicks,
      timers: [
        { teamId: "team-1", timeRemaining: 45 },
        { teamId: "team-2", timeRemaining: 80 },
        { teamId: "team-3", timeRemaining: 60 },
        { teamId: "team-4", timeRemaining: 55 },
      ],
    });

    // All 6 picks should be synced
    expect(picks).toHaveLength(6);
    expect(picks[5].pickNumber).toBe(6);

    // Current pick should be 7 (next pick)
    expect(currentPick).toBe(7);

    // Paused and complete status synced
    expect(isPaused).toBe(false);
    expect(isDraftComplete).toBe(false);

    // Timers synced
    expect(teamTimers["team-1"]).toBe(45);
    expect(teamTimers["team-2"]).toBe(80);
    expect(teamTimers["team-3"]).toBe(60);
    expect(teamTimers["team-4"]).toBe(55);
  });

  it("sets isDraftComplete when status is 'active'", () => {
    let isDraftComplete = false;
    const setIsDraftComplete = (value: boolean) => { isDraftComplete = value; };
    const isRevalidatingRef = { current: false };

    const handleDraftStateSync = (data: any) => {
      if (!isRevalidatingRef.current) {
        setIsDraftComplete(
          data.status === "active" || data.status === "completed"
        );
      }
    };

    handleDraftStateSync({
      currentPickNumber: 81,
      isPaused: false,
      status: "active",
      picks: [],
      timers: [],
    });

    expect(isDraftComplete).toBe(true);
  });

  it("skips sync when revalidation is in-flight", () => {
    let picks = [makePick(1, "team-1", "player-1")];
    const setPicks = (value: any) => { picks = value; };
    const isRevalidatingRef = { current: true }; // revalidation in progress

    const handleDraftStateSync = (data: any) => {
      if (!isRevalidatingRef.current) {
        setPicks(data.picks);
      }
    };

    handleDraftStateSync({
      currentPickNumber: 7,
      isPaused: false,
      status: "draft",
      picks: [
        makePick(1, "team-1", "player-1"),
        makePick(2, "team-2", "player-2"),
      ],
      timers: [],
    });

    // Picks should NOT be updated because revalidation is in-flight
    expect(picks).toHaveLength(1);
  });
});

// ---------------------------------------------------------------------------
// 4. Revalidation sync merges picks correctly
// ---------------------------------------------------------------------------

describe("revalidation sync – pick merge with buffering", () => {
  it("merges DB snapshot with buffered picks from socket events during revalidation", () => {
    const dbPicks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
    ];

    // A pick that arrived via socket during the revalidation window
    const bufferedPick = makePick(4, "team-4", "player-4");

    const dbPickIds = new Set(dbPicks.map((p) => p.id));
    const pendingPicks = [bufferedPick];

    // Merge logic from the sync effect
    const missedPicks = pendingPicks.filter((p) => !dbPickIds.has(p.id));
    const mergedPicks = [...dbPicks, ...missedPicks];

    expect(mergedPicks).toHaveLength(4);
    expect(mergedPicks[3].pickNumber).toBe(4);
    expect(mergedPicks[3].participant.id).toBe("player-4");
  });

  it("deduplicates picks that are in both DB snapshot and buffer", () => {
    const dbPicks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
    ];

    // The same pick arrived via socket AND is in the DB snapshot
    const bufferedPick = makePick(3, "team-3", "player-3");

    const dbPickIds = new Set(dbPicks.map((p) => p.id));
    const pendingPicks = [bufferedPick];

    const missedPicks = pendingPicks.filter((p) => !dbPickIds.has(p.id));
    const mergedPicks = [...dbPicks, ...missedPicks];

    // No duplicates – pick 3 appears only once
    expect(mergedPicks).toHaveLength(3);
  });

  it("handles empty buffer (no socket events during revalidation)", () => {
    const dbPicks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
    ];

    const pendingPicks: any[] = [];
    const dbPickIds = new Set(dbPicks.map((p) => p.id));
    const missedPicks = pendingPicks.filter((p) => !dbPickIds.has(p.id));
    const mergedPicks = [...dbPicks, ...missedPicks];

    expect(mergedPicks).toHaveLength(2);
  });

  it("handles multiple buffered picks during slow revalidation", () => {
    const dbPicks = [
      makePick(1, "team-1", "player-1"),
    ];

    // Three picks arrived while revalidation was slow
    const bufferedPicks = [
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
      makePick(4, "team-4", "player-4"),
    ];

    const dbPickIds = new Set(dbPicks.map((p) => p.id));
    const missedPicks = bufferedPicks.filter((p) => !dbPickIds.has(p.id));
    const mergedPicks = [...dbPicks, ...missedPicks];

    expect(mergedPicks).toHaveLength(4);
  });
});

// ---------------------------------------------------------------------------
// 4b. Failed revalidation staleness guard
// ---------------------------------------------------------------------------

describe("revalidation sync – staleness guard on failed fetch", () => {
  it("skips state overwrite when draftPicks reference is unchanged (fetch failed)", () => {
    // Initial loader data (stale — from before mobile background)
    const staleDraftPicks = [
      makePick(1, "team-1", "player-1"),
    ];

    // Simulated state that draft-state-sync already updated to fresh data
    let picks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
    ];
    let currentPick = 4;
    const setPicks = (value: any) => { picks = value; };
    const setCurrentPick = (value: number) => { currentPick = value; };

    // Track the draftPicks reference at revalidation start
    const draftPicksAtRevalidationStart = staleDraftPicks;

    // Simulate: revalidation completes but draftPicks is the SAME reference
    // (loader fetch failed, React Router didn't update the data)
    const draftPicksAfterRevalidation = staleDraftPicks; // same reference

    if (draftPicksAfterRevalidation === draftPicksAtRevalidationStart) {
      // Guard fires — skip the overwrite
      return;
    }

    // This code should NOT run
    setPicks(draftPicksAfterRevalidation);
    setCurrentPick(1);

    // If guard worked, these should still be the fresh values
    expect(picks).toHaveLength(3);
    expect(currentPick).toBe(4);
  });

  it("applies state overwrite when draftPicks reference changes (fetch succeeded)", () => {
    const staleDraftPicks = [
      makePick(1, "team-1", "player-1"),
    ];

    let picks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
    ];
    let currentPick = 4;
    const setPicks = (value: any) => { picks = value; };
    const setCurrentPick = (value: number) => { currentPick = value; };

    const draftPicksAtRevalidationStart = staleDraftPicks;

    // Simulate: revalidation completes with NEW data (different reference)
    const freshDraftPicks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
      makePick(4, "team-4", "player-4"),
    ];

    if (freshDraftPicks === draftPicksAtRevalidationStart) {
      return; // Guard fires — but won't in this case
    }

    // Merge logic runs — apply fresh data
    const dbPickIds = new Set(freshDraftPicks.map((p) => p.id));
    const bufferedPicks: any[] = [];
    const missedPicks = bufferedPicks.filter((p: any) => !dbPickIds.has(p.id));
    setPicks([...freshDraftPicks, ...missedPicks]);
    setCurrentPick(5);

    expect(picks).toHaveLength(4);
    expect(currentPick).toBe(5);
  });
});

// ---------------------------------------------------------------------------
// 5. Available players accuracy after reconnection
// ---------------------------------------------------------------------------

describe("available players filtering after reconnection", () => {
  const allParticipants = [
    makeParticipant("player-1", "Patrick Mahomes"),
    makeParticipant("player-2", "Josh Allen"),
    makeParticipant("player-3", "Lamar Jackson"),
    makeParticipant("player-4", "Jalen Hurts"),
    makeParticipant("player-5", "Joe Burrow"),
    makeParticipant("player-6", "Dak Prescott"),
  ];

  it("correctly filters drafted players from available list after sync", () => {
    // After reconnection, picks include players 1-3
    const picks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
    ];

    const draftedIds = new Set(picks.map((p) => p.participant.id));
    const available = allParticipants.filter((p) => !draftedIds.has(p.id));

    expect(available).toHaveLength(3);
    expect(available.map((p) => p.name)).toEqual([
      "Jalen Hurts",
      "Joe Burrow",
      "Dak Prescott",
    ]);
  });

  it("shows all players as available when picks are empty (draft just started)", () => {
    const picks: any[] = [];
    const draftedIds = new Set(picks.map((p: any) => p.participant.id));
    const available = allParticipants.filter((p) => !draftedIds.has(p.id));

    expect(available).toHaveLength(6);
  });

  it("shows no players as available when all are drafted", () => {
    const picks = allParticipants.map((p, i) =>
      makePick(i + 1, `team-${(i % 4) + 1}`, p.id)
    );
    const draftedIds = new Set(picks.map((p) => p.participant.id));
    const available = allParticipants.filter((p) => !draftedIds.has(p.id));

    expect(available).toHaveLength(0);
  });
});

// ---------------------------------------------------------------------------
// 6. "On the clock" correctness after reconnection
// ---------------------------------------------------------------------------

describe("on-the-clock display after reconnection", () => {
  const draftSlots = makeDraftSlots(4);

  it("shows correct team on clock after timer-update syncs currentPickNumber", () => {
    // User was disconnected at pick 5 (Team 4's turn in round 2)
    // 20 picks happened, now at pick 25 (which is round 7, pick 1 → Team 1)
    const currentPickNumber = 25;
    const currentSlot = getTeamForPick(currentPickNumber, draftSlots);

    expect(currentSlot?.team.id).toBe("team-1");
    expect(currentSlot?.team.name).toBe("Team 1");
  });

  it("shows correct team after draft-state-sync provides currentPickNumber", () => {
    // Server says currentPickNumber is 13 (round 4, even, pick 1 → team 4)
    const currentPickNumber = 13;
    const currentSlot = getTeamForPick(currentPickNumber, draftSlots);

    expect(currentSlot?.team.id).toBe("team-4");
  });

  it("handles edge case: currentPickNumber = 1 (draft just started)", () => {
    const currentSlot = getTeamForPick(1, draftSlots);
    expect(currentSlot?.team.id).toBe("team-1");
  });

  it("handles last pick of a round correctly", () => {
    // Pick 4 = last pick of round 1 (team 4)
    expect(getTeamForPick(4, draftSlots)?.team.id).toBe("team-4");
    // Pick 8 = last pick of round 2 (team 1, snake)
    expect(getTeamForPick(8, draftSlots)?.team.id).toBe("team-1");
  });
});

// ---------------------------------------------------------------------------
// 7. Revalidation retry mechanism
// ---------------------------------------------------------------------------

describe("revalidation retry on reconnection", () => {
  it("calls revalidate immediately and schedules a retry", () => {
    const revalidate = vi.fn();
    let reconnectCount = 0;

    // Simulate the effect logic
    const runEffect = () => {
      if (reconnectCount > 0) {
        revalidate();
        // Schedule retry
        setTimeout(() => revalidate(), 3000);
      }
    };

    // First reconnect
    reconnectCount = 1;
    runEffect();

    expect(revalidate).toHaveBeenCalledTimes(1);

    // After 3 seconds, retry fires
    vi.advanceTimersByTime(3000);
    expect(revalidate).toHaveBeenCalledTimes(2);
  });

  it("clears pending retry when a new reconnect happens", () => {
    const revalidate = vi.fn();
    let timeoutId: ReturnType<typeof setTimeout> | null = null;

    const runEffect = (reconnectCount: number) => {
      if (reconnectCount > 0) {
        revalidate();
        if (timeoutId) clearTimeout(timeoutId);
        timeoutId = setTimeout(() => revalidate(), 3000);
      }
    };

    // First reconnect
    runEffect(1);
    expect(revalidate).toHaveBeenCalledTimes(1);

    // Second reconnect before retry fires
    vi.advanceTimersByTime(1000);
    runEffect(2);
    expect(revalidate).toHaveBeenCalledTimes(2);

    // After 3s from second reconnect, only one retry fires (not two)
    vi.advanceTimersByTime(3000);
    expect(revalidate).toHaveBeenCalledTimes(3);
  });

  beforeEach(() => {
    vi.useFakeTimers();
  });
});

// ---------------------------------------------------------------------------
// 8. Full reconnection scenario end-to-end (state simulation)
// ---------------------------------------------------------------------------

describe("full mobile reconnection scenario", () => {
  it("correctly syncs all state after 20 picks made during mobile background", () => {
    const draftSlots = makeDraftSlots(4);

    // STATE BEFORE MOBILE BACKGROUND (picks 1-4 made)
    let picks = [
      makePick(1, "team-1", "player-1"),
      makePick(2, "team-2", "player-2"),
      makePick(3, "team-3", "player-3"),
      makePick(4, "team-4", "player-4"),
    ];
    let currentPick = 5;
    let teamTimers: Record<string, number> = {
      "team-1": 100,
      "team-2": 100,
      "team-3": 100,
      "team-4": 100,
    };

    // --- USER GOES TO MOBILE BACKGROUND ---
    // 20 more picks happen (picks 5-24), now on pick 25

    // --- USER RETURNS FROM BACKGROUND ---

    // Step 1: Socket reconnects, server sends draft-state-sync
    const serverPicks = Array.from({ length: 24 }, (_, i) => {
      const pickNum = i + 1;
      const teamIdx = getTeamForPick(pickNum, draftSlots);
      if (!teamIdx) throw new Error(`No team for pick ${pickNum}`);
      return makePick(pickNum, teamIdx.team.id, `player-${pickNum}`);
    });

    // Simulate draft-state-sync handler
    picks = serverPicks;
    currentPick = 25;
    teamTimers = {
      "team-1": 45,
      "team-2": 80,
      "team-3": 60,
      "team-4": 55,
    };

    // VERIFY: All 24 picks are now visible
    expect(picks).toHaveLength(24);

    // VERIFY: Correct person on the clock (pick 25 = round 7, odd, pick 1 → team 1)
    const onClock = getTeamForPick(currentPick, draftSlots);
    expect(onClock?.team.id).toBe("team-1");

    // VERIFY: Available players excludes drafted ones
    const allParticipants = Array.from({ length: 40 }, (_, i) =>
      makeParticipant(`player-${i + 1}`, `Player ${i + 1}`)
    );
    const draftedIds = new Set(picks.map((p) => p.participant.id));
    const available = allParticipants.filter((p) => !draftedIds.has(p.id));
    expect(available).toHaveLength(16); // 40 - 24 = 16

    // VERIFY: Timer state is fresh
    expect(teamTimers["team-1"]).toBe(45);

    // Step 2: Timer-update arrives 1 second later
    // This would also sync currentPickNumber (belt-and-suspenders)
    const timerUpdate = {
      seasonId: "season-1",
      teamId: "team-1",
      timeRemaining: 44,
      currentPickNumber: 25,
    };
    teamTimers = { ...teamTimers, [timerUpdate.teamId]: timerUpdate.timeRemaining };
    currentPick = timerUpdate.currentPickNumber;

    expect(currentPick).toBe(25);
    expect(teamTimers["team-1"]).toBe(44);
  });

  it("handles reconnection during a paused draft", () => {
    let isPaused = false;
    let currentPick = 5;

    // Server sends sync with paused state
    isPaused = true;
    currentPick = 10;

    expect(isPaused).toBe(true);
    expect(currentPick).toBe(10);
  });

  it("handles reconnection after draft completed", () => {
    let isDraftComplete = false;
    let picks: any[] = [];

    // Server sends sync with completed status
    const totalPicks = 80; // 4 teams × 20 rounds
    picks = Array.from({ length: totalPicks }, (_, i) =>
      makePick(i + 1, `team-${(i % 4) + 1}`, `player-${i + 1}`)
    );
    isDraftComplete = true;

    expect(isDraftComplete).toBe(true);
    expect(picks).toHaveLength(80);
  });
});

// ---------------------------------------------------------------------------
// 9. Autodraft and timer sync on revalidation
// ---------------------------------------------------------------------------

describe("autodraft and timer sync on revalidation completion", () => {
  it("syncs autodraftStatus from loader data on revalidation", () => {
    type AutodraftStatusEntry = { isEnabled: boolean; mode: "next_pick" | "while_on"; queueOnly: boolean };
    let autodraftStatus: Record<string, AutodraftStatusEntry> = {
      "team-1": { isEnabled: false, mode: "next_pick", queueOnly: false },
      "team-2": { isEnabled: false, mode: "next_pick", queueOnly: false },
    };

    // Simulate what happens on revalidation completion
    const autodraftSettings = [
      { teamId: "team-1", isEnabled: true, mode: "while_on" as const, queueOnly: false },
      { teamId: "team-2", isEnabled: false, mode: "next_pick" as const, queueOnly: false },
      { teamId: "team-3", isEnabled: true, mode: "next_pick" as const, queueOnly: true },
    ];

    autodraftStatus = {};
    autodraftSettings.forEach((setting) => {
      autodraftStatus[setting.teamId] = {
        isEnabled: setting.isEnabled,
        mode: setting.mode,
        queueOnly: setting.queueOnly,
      };
    });

    expect(autodraftStatus["team-1"].isEnabled).toBe(true);
    expect(autodraftStatus["team-2"].isEnabled).toBe(false);
    expect(autodraftStatus["team-3"].isEnabled).toBe(true);
  });

  it("syncs teamTimers from loader data on revalidation", () => {
    let teamTimers: Record<string, number> = {
      "team-1": 100,
      "team-2": 100,
    };

    const timers = [
      { teamId: "team-1", timeRemaining: 45 },
      { teamId: "team-2", timeRemaining: 80 },
      { teamId: "team-3", timeRemaining: 120 },
    ];

    // Simulate the sync logic
    const updated = { ...teamTimers };
    timers.forEach((timer) => {
      updated[timer.teamId] = timer.timeRemaining;
    });
    teamTimers = updated;

    expect(teamTimers["team-1"]).toBe(45);
    expect(teamTimers["team-2"]).toBe(80);
    expect(teamTimers["team-3"]).toBe(120);
  });
});
