import { describe, expect, it, vi, beforeEach } from "vitest";

const mockDb = vi.hoisted(() => ({
  query: {
    seasonParticipants: { findMany: vi.fn() },
    seasonParticipantSimulatorInputs: { findMany: vi.fn() },
    seasonParticipantExpectedValues: { findMany: vi.fn() },
  },
}));

vi.mock("~/database/context", () => ({
  database: () => mockDb,
}));

describe("simulator input model", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("does not treat previously generated ratings as direct rating inputs", async () => {
    const { getParticipantSimulatorInputs } = await import("../simulator");

    mockDb.query.seasonParticipants.findMany.mockResolvedValue([
      { id: "direct-rating" },
      { id: "generated-rating" },
      { id: "legacy-direct-rating" },
    ]);
    mockDb.query.seasonParticipantSimulatorInputs.findMany.mockResolvedValue([
      {
        participantId: "direct-rating",
        sourceOdds: 750,
        sourceElo: null,
        worldRanking: null,
        rating: "31.2500",
        projectedWins: null,
        projectedTablePoints: null,
        seed: null,
        region: null,
        metadata: { ratingMethod: "direct" },
      },
      {
        participantId: "generated-rating",
        sourceOdds: 750,
        sourceElo: null,
        worldRanking: null,
        rating: "35.0000",
        projectedWins: null,
        projectedTablePoints: null,
        seed: null,
        region: null,
        metadata: { ratingMethod: "sourceOdds" },
      },
      {
        participantId: "legacy-direct-rating",
        sourceOdds: null,
        sourceElo: null,
        worldRanking: null,
        rating: "27.5000",
        projectedWins: null,
        projectedTablePoints: null,
        seed: null,
        region: null,
        metadata: null,
      },
    ]);
    mockDb.query.seasonParticipantExpectedValues.findMany.mockResolvedValue([]);

    const inputs = await getParticipantSimulatorInputs("season-1");
    const byParticipant = new Map(inputs.map((input) => [input.participantId, input]));

    expect(byParticipant.get("direct-rating")?.rating).toBe(31.25);
    expect(byParticipant.get("generated-rating")?.rating).toBeNull();
    expect(byParticipant.get("legacy-direct-rating")?.rating).toBe(27.5);
  });
});
