import { beforeEach, describe, expect, it, vi } from "vitest";
import type { RouterContextProvider } from "react-router";

const ctx = {} as unknown as RouterContextProvider;
let action: any;

vi.mock("~/lib/auth.server", () => ({
  auth: { api: { getSession: vi.fn() } },
}));
vi.mock("~/models/user", () => ({
  isUserAdmin: vi.fn(),
}));
vi.mock("~/models/sports-season", () => ({
  updateSportsSeason: vi.fn(),
  findSportsSeasonById: vi.fn(),
  deleteSportsSeason: vi.fn(),
}));
vi.mock("~/models/pending-standings-mappings", () => ({
  getPendingStandingsMappings: vi.fn(),
  deletePendingStandingsMapping: vi.fn(),
}));
vi.mock("~/models/season-participant", () => ({
  findParticipantsBySportsSeasonId: vi.fn(),
  findParticipantById: vi.fn(),
  updateParticipant: vi.fn(),
}));
vi.mock("~/models/regular-season-standings", () => ({
  getLastSyncedAt: vi.fn(),
  upsertRegularSeasonStandings: vi.fn(),
}));
vi.mock("~/models/scoring-calculator", () => ({
  processSeasonStandings: vi.fn(),
  recalculateStandings: vi.fn(),
}));
vi.mock("~/models/standings", () => ({
  createDailySnapshot: vi.fn(),
}));
vi.mock("~/database/context", () => ({
  database: vi.fn(),
}));
vi.mock("~/services/standings-sync/index", () => ({
  syncStandings: vi.fn(),
}));
vi.mock("~/services/simulations/registry", () => ({
  getSimulatorInfo: vi.fn(),
  SIMULATOR_TYPES: [],
}));

function makeResolveRequest() {
  const formData = new FormData();
  formData.append("intent", "resolve-mapping");
  formData.append("externalTeamId", "ext-42");
  formData.append("participantId", "participant-7");
  formData.append(
    "standingData",
    JSON.stringify({
      teamName: "Golden State",
      wins: 48,
      losses: 20,
      winPct: 0.706,
      gamesPlayed: 68,
      leagueRank: 3,
    })
  );

  return new Request("http://localhost/admin/sports-seasons/season-1", {
    method: "POST",
    body: formData,
  });
}

describe("admin.sports-seasons.$id action", () => {
  beforeEach(async () => {
    vi.clearAllMocks();
    vi.resetModules();

    const { auth } = await import("~/lib/auth.server");
    vi.mocked(auth.api.getSession).mockResolvedValue({ user: { id: "admin-1" } } as any);

    const { isUserAdmin } = await import("~/models/user");
    vi.mocked(isUserAdmin).mockResolvedValue(true);

    const { findParticipantById, updateParticipant } = await import("~/models/season-participant");
    vi.mocked(findParticipantById).mockResolvedValue({
      id: "participant-7",
      name: "Golden State Warriors",
      sportsSeasonId: "season-1",
    } as any);
    vi.mocked(updateParticipant).mockResolvedValue({ id: "participant-7" } as any);

    const { upsertRegularSeasonStandings } = await import("~/models/regular-season-standings");
    vi.mocked(upsertRegularSeasonStandings).mockResolvedValue(undefined as never);

    const { deletePendingStandingsMapping } = await import("~/models/pending-standings-mappings");
    vi.mocked(deletePendingStandingsMapping).mockResolvedValue(undefined as never);

    const routeModule = await import("../admin.sports-seasons.$id");
    action = routeModule.action;
  });

  it("returns the resolved API team and participant name after a mapping is confirmed", async () => {
    const result = await action({
      request: makeResolveRequest(),
      params: { id: "season-1" },
      context: ctx,
    });

    expect(result).toMatchObject({
      success: true,
      intent: "resolve-mapping",
      resolvedTeam: "Golden State",
      resolvedParticipant: "Golden State Warriors",
    });
  });

  it("rejects a participant from a different sports season", async () => {
    const { findParticipantById, updateParticipant } = await import("~/models/season-participant");
    vi.mocked(findParticipantById).mockResolvedValue({
      id: "participant-7",
      name: "Golden State Warriors",
      sportsSeasonId: "other-season",
    } as any);

    const result = await action({
      request: makeResolveRequest(),
      params: { id: "season-1" },
      context: ctx,
    });

    expect(result).toMatchObject({
      error: "Selected participant does not belong to this sports season.",
    });
    expect(vi.mocked(updateParticipant)).not.toHaveBeenCalled();
  });
});
