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

vi.mock("~/models/user", () => ({
  isUserAdminByClerkId: vi.fn(),
}));

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

import { isCommissioner, hasCommissionerRecord } from "../commissioner";
import { isUserAdminByClerkId } from "~/models/user";
import { database } from "~/database/context";

const LEAGUE_ID = "league-1";
const USER_ID = "user-clerk-1";

function makeMockDb(commissionerRow: object | null) {
  return {
    query: {
      commissioners: {
        findFirst: vi.fn().mockResolvedValue(commissionerRow),
      },
    },
  };
}

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

describe("isCommissioner", () => {
  it("returns true for a site admin without a commissioner record", async () => {
    vi.mocked(isUserAdminByClerkId).mockResolvedValue(true);
    vi.mocked(database).mockReturnValue(makeMockDb(null) as never);

    const result = await isCommissioner(LEAGUE_ID, USER_ID);
    expect(result).toBe(true);
  });

  it("returns true for a user with a commissioner record", async () => {
    vi.mocked(isUserAdminByClerkId).mockResolvedValue(false);
    vi.mocked(database).mockReturnValue(
      makeMockDb({ id: "comm-1", leagueId: LEAGUE_ID, userId: USER_ID }) as never
    );

    const result = await isCommissioner(LEAGUE_ID, USER_ID);
    expect(result).toBe(true);
  });

  it("returns true for a site admin who also has a commissioner record", async () => {
    vi.mocked(isUserAdminByClerkId).mockResolvedValue(true);
    vi.mocked(database).mockReturnValue(
      makeMockDb({ id: "comm-1", leagueId: LEAGUE_ID, userId: USER_ID }) as never
    );

    const result = await isCommissioner(LEAGUE_ID, USER_ID);
    expect(result).toBe(true);
  });

  it("returns false for a non-admin user without a commissioner record", async () => {
    vi.mocked(isUserAdminByClerkId).mockResolvedValue(false);
    vi.mocked(database).mockReturnValue(makeMockDb(null) as never);

    const result = await isCommissioner(LEAGUE_ID, USER_ID);
    expect(result).toBe(false);
  });

  it("runs the admin check and DB query in parallel", async () => {
    const order: string[] = [];
    vi.mocked(isUserAdminByClerkId).mockImplementation(async () => {
      order.push("admin");
      return false;
    });
    const db = makeMockDb(null);
    db.query.commissioners.findFirst = vi.fn().mockImplementation(async () => {
      order.push("db");
      return null;
    });
    vi.mocked(database).mockReturnValue(db as never);

    await isCommissioner(LEAGUE_ID, USER_ID);

    // Both should have been called; order is non-deterministic for parallel calls
    expect(order).toContain("admin");
    expect(order).toContain("db");
  });
});

describe("hasCommissionerRecord", () => {
  it("returns true when a commissioner record exists", async () => {
    vi.mocked(database).mockReturnValue(
      makeMockDb({ id: "comm-1", leagueId: LEAGUE_ID, userId: USER_ID }) as never
    );

    const result = await hasCommissionerRecord(LEAGUE_ID, USER_ID);
    expect(result).toBe(true);
  });

  it("returns false when no commissioner record exists", async () => {
    vi.mocked(database).mockReturnValue(makeMockDb(null) as never);

    const result = await hasCommissionerRecord(LEAGUE_ID, USER_ID);
    expect(result).toBe(false);
  });

  it("returns false for a site admin without a commissioner record", async () => {
    // hasCommissionerRecord must NOT consult the admin flag
    vi.mocked(database).mockReturnValue(makeMockDb(null) as never);

    const result = await hasCommissionerRecord(LEAGUE_ID, USER_ID);
    expect(result).toBe(false);
    expect(isUserAdminByClerkId).not.toHaveBeenCalled();
  });
});
