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

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

// Mock the schema so the schema module doesn't execute drizzle builder calls,
// following the same pattern as scoring-event-dashboard.test.ts.
vi.mock("~/database/schema", () => ({
  sportsSeasons: {
    id: "ss.id",
    sportId: "ss.sport_id",
    name: "ss.name",
    year: "ss.year",
    draftOn: "ss.draft_on",
    draftOff: "ss.draft_off",
  },
}));

vi.mock("drizzle-orm", () => ({
  eq:  (col: unknown, val: unknown) => ({ type: "eq", col, val }),
  sql: (strings: TemplateStringsArray, ...values: unknown[]) => ({ type: "sql", strings, values }),
  lte: (col: unknown, val: unknown) => ({ type: "lte", col, val }),
  gte: (col: unknown, val: unknown) => ({ type: "gte", col, val }),
  and: (...args: unknown[]) => ({ type: "and", args }),
  desc: (col: unknown) => ({ type: "desc", col }),
  asc:  (col: unknown) => ({ type: "asc",  col }),
}));

import { findAllSportsSeasons, findDraftableSportsSeasons } from "../sports-season";
import { database } from "~/database/context";

const today = new Date().toISOString().slice(0, 10);
const future = "2099-12-31";
const pastStart = "2020-01-01";
const pastEnd = "2020-12-31";

const mockSeasons = [
  { id: "season-1", name: "2025 NBA Playoffs", draftOn: today, draftOff: future, year: 2025 },
  { id: "season-2", name: "2025 F1 Season", draftOn: today, draftOff: future, year: 2025 },
  { id: "season-3", name: "2024 Old Golf", draftOn: pastStart, draftOff: pastEnd, year: 2024 },
];

function makeMockDb(seasons: typeof mockSeasons) {
  return {
    query: {
      sportsSeasons: {
        findMany: vi.fn().mockResolvedValue(seasons),
      },
    },
  };
}

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

describe("findAllSportsSeasons", () => {
  it("returns all sport seasons regardless of draft window", async () => {
    vi.mocked(database).mockReturnValue(makeMockDb(mockSeasons) as never);
    const result = await findAllSportsSeasons();
    expect(result).toHaveLength(3);
  });
});

describe("findDraftableSportsSeasons", () => {
  it("returns only currently-draftable seasons", async () => {
    const draftableOnly = mockSeasons.filter((s) => s.draftOn <= today && today <= s.draftOff);
    const mockDb = makeMockDb(draftableOnly);
    vi.mocked(database).mockReturnValue(mockDb as never);

    const result = await findDraftableSportsSeasons();
    expect(result).toHaveLength(2);
    expect(result.every((s) => s.draftOn <= today && today <= s.draftOff)).toBe(true);
  });

  it("returns empty array when no seasons fall within a draft window", async () => {
    vi.mocked(database).mockReturnValue(makeMockDb([]) as never);
    const result = await findDraftableSportsSeasons();
    expect(result).toHaveLength(0);
  });

  it("calls findMany with a where clause", async () => {
    const mockDb = makeMockDb([]);
    vi.mocked(database).mockReturnValue(mockDb as never);

    await findDraftableSportsSeasons();
    expect(mockDb.query.sportsSeasons.findMany).toHaveBeenCalledWith(
      expect.objectContaining({
        where: expect.anything(),
      })
    );
  });
});
