import { describe, it, expect, vi, beforeEach } from "vitest";
import { NhlStandingsAdapter } from "../nhl";

const SAMPLE_NHL_RESPONSE = {
  standings: [
    {
      teamName: { default: "Boston Bruins" },
      teamAbbrev: { default: "BOS" },
      conferenceName: "Eastern",
      divisionName: "Atlantic",
      gamesPlayed: 68,
      wins: 42,
      losses: 20,
      otLosses: 6,
      points: 90,
      pointPctg: 0.662,
      winPctg: 0.618,
      l10Wins: 7,
      l10Losses: 2,
      l10OtLosses: 1,
      streakCode: "W",
      streakCount: 3,
      homeWins: 24,
      homeLosses: 9,
      homeOtLosses: 2,
      roadWins: 18,
      roadLosses: 11,
      roadOtLosses: 4,
      conferenceSequence: 1,
      divisionSequence: 1,
      leagueSequence: 1,
    },
    {
      teamName: { default: "Toronto Maple Leafs" },
      teamAbbrev: { default: "TOR" },
      conferenceName: "Eastern",
      divisionName: "Atlantic",
      gamesPlayed: 70,
      wins: 38,
      losses: 25,
      otLosses: 7,
      points: 83,
      pointPctg: 0.593,
      winPctg: 0.543,
      l10Wins: 5,
      l10Losses: 4,
      l10OtLosses: 1,
      streakCode: "L",
      streakCount: 2,
      homeWins: 20,
      homeLosses: 12,
      homeOtLosses: 3,
      roadWins: 18,
      roadLosses: 13,
      roadOtLosses: 4,
      conferenceSequence: 3,
      divisionSequence: 2,
      leagueSequence: 5,
    },
  ],
};

describe("NhlStandingsAdapter", () => {
  beforeEach(() => {
    vi.stubGlobal("fetch", vi.fn());
  });

  it("maps NHL API response to FetchedStandingsRecord[]", async () => {
    vi.mocked(fetch).mockResolvedValueOnce({
      ok: true,
      json: async () => SAMPLE_NHL_RESPONSE,
    } as Response);

    const adapter = new NhlStandingsAdapter();
    const records = await adapter.fetchStandings();

    expect(records).toHaveLength(2);

    const bos = records[0];
    expect(bos.teamName).toBe("Boston Bruins");
    expect(bos.externalTeamId).toBe("BOS");
    expect(bos.wins).toBe(42);
    expect(bos.losses).toBe(20);
    expect(bos.otLosses).toBe(6);
    expect(bos.gamesPlayed).toBe(68);
    expect(bos.conference).toBe("Eastern");
    expect(bos.division).toBe("Atlantic");
    expect(bos.conferenceRank).toBe(1);
    expect(bos.divisionRank).toBe(1);
    expect(bos.leagueRank).toBe(1);
  });

  it("formats streak correctly", async () => {
    vi.mocked(fetch).mockResolvedValueOnce({
      ok: true,
      json: async () => SAMPLE_NHL_RESPONSE,
    } as Response);

    const adapter = new NhlStandingsAdapter();
    const records = await adapter.fetchStandings();

    expect(records[0].streak).toBe("W3");
    expect(records[1].streak).toBe("L2");
  });

  it("formats lastTen as W-L-OTL", async () => {
    vi.mocked(fetch).mockResolvedValueOnce({
      ok: true,
      json: async () => SAMPLE_NHL_RESPONSE,
    } as Response);

    const adapter = new NhlStandingsAdapter();
    const records = await adapter.fetchStandings();

    expect(records[0].lastTen).toBe("7-2-1");
  });

  it("formats home and away records", async () => {
    vi.mocked(fetch).mockResolvedValueOnce({
      ok: true,
      json: async () => SAMPLE_NHL_RESPONSE,
    } as Response);

    const adapter = new NhlStandingsAdapter();
    const records = await adapter.fetchStandings();

    expect(records[0].homeRecord).toBe("24-9-2");
    expect(records[0].awayRecord).toBe("18-11-4");
  });

  it("throws on non-ok response", async () => {
    vi.mocked(fetch).mockResolvedValueOnce({
      ok: false,
      status: 503,
      statusText: "Service Unavailable",
    } as Response);

    const adapter = new NhlStandingsAdapter();
    await expect(adapter.fetchStandings()).rejects.toThrow("503");
  });
});
