import { describe, it, expect } from "vitest";
import {
  SIMPLE_4,
  SIMPLE_8,
  SIMPLE_16,
  SIMPLE_32,
  NCAA_68,
  NFL_14,
  getBracketTemplate,
  getScoringRoundType,
} from "~/lib/bracket-templates";

describe("Bracket Templates", () => {
  describe("Template Structure", () => {
    it("SIMPLE_4 has correct structure", () => {
      expect(SIMPLE_4.id).toBe("simple_4");
      expect(SIMPLE_4.totalTeams).toBe(4);
      expect(SIMPLE_4.rounds).toHaveLength(2);
      expect(SIMPLE_4.scoringStartsAtRound).toBe("Semifinals");
      expect(SIMPLE_4.rounds.every((r) => r.isScoring)).toBe(true);
    });

    it("SIMPLE_8 has correct structure", () => {
      expect(SIMPLE_8.id).toBe("simple_8");
      expect(SIMPLE_8.totalTeams).toBe(8);
      expect(SIMPLE_8.rounds).toHaveLength(3);
      expect(SIMPLE_8.scoringStartsAtRound).toBe("Quarterfinals");
      expect(SIMPLE_8.rounds.every((r) => r.isScoring)).toBe(true);
    });

    it("SIMPLE_16 has correct structure", () => {
      expect(SIMPLE_16.id).toBe("simple_16");
      expect(SIMPLE_16.totalTeams).toBe(16);
      expect(SIMPLE_16.rounds).toHaveLength(4);
      expect(SIMPLE_16.scoringStartsAtRound).toBe("Quarterfinals");

      // First round doesn't score
      expect(SIMPLE_16.rounds[0].isScoring).toBe(false);
      expect(SIMPLE_16.rounds[0].name).toBe("Round of 16");

      // Quarterfinals and beyond score
      expect(SIMPLE_16.rounds[1].isScoring).toBe(true);
      expect(SIMPLE_16.rounds[2].isScoring).toBe(true);
      expect(SIMPLE_16.rounds[3].isScoring).toBe(true);
    });

    it("SIMPLE_32 has correct structure", () => {
      expect(SIMPLE_32.id).toBe("simple_32");
      expect(SIMPLE_32.totalTeams).toBe(32);
      expect(SIMPLE_32.rounds).toHaveLength(5);
      expect(SIMPLE_32.scoringStartsAtRound).toBe("Quarterfinals");

      // First two rounds don't score
      expect(SIMPLE_32.rounds[0].isScoring).toBe(false);
      expect(SIMPLE_32.rounds[1].isScoring).toBe(false);

      // Quarterfinals and beyond score
      expect(SIMPLE_32.rounds[2].isScoring).toBe(true);
      expect(SIMPLE_32.rounds[3].isScoring).toBe(true);
      expect(SIMPLE_32.rounds[4].isScoring).toBe(true);
    });

    it("NCAA_68 has correct structure", () => {
      expect(NCAA_68.id).toBe("ncaa_68");
      expect(NCAA_68.totalTeams).toBe(68);
      expect(NCAA_68.rounds).toHaveLength(7);
      expect(NCAA_68.scoringStartsAtRound).toBe("Elite Eight");

      // First Four through Sweet Sixteen don't score
      expect(NCAA_68.rounds[0].name).toBe("First Four");
      expect(NCAA_68.rounds[0].isScoring).toBe(false);
      expect(NCAA_68.rounds[1].name).toBe("Round of 64");
      expect(NCAA_68.rounds[1].isScoring).toBe(false);
      expect(NCAA_68.rounds[2].name).toBe("Round of 32");
      expect(NCAA_68.rounds[2].isScoring).toBe(false);
      expect(NCAA_68.rounds[3].name).toBe("Sweet Sixteen");
      expect(NCAA_68.rounds[3].isScoring).toBe(false);

      // Elite Eight and beyond score
      expect(NCAA_68.rounds[4].name).toBe("Elite Eight");
      expect(NCAA_68.rounds[4].isScoring).toBe(true);
      expect(NCAA_68.rounds[5].name).toBe("Final Four");
      expect(NCAA_68.rounds[5].isScoring).toBe(true);
      expect(NCAA_68.rounds[6].name).toBe("Championship");
      expect(NCAA_68.rounds[6].isScoring).toBe(true);
    });

    it("NFL_14 has correct structure", () => {
      expect(NFL_14.id).toBe("nfl_14");
      expect(NFL_14.totalTeams).toBe(14);
      expect(NFL_14.rounds).toHaveLength(4);
      expect(NFL_14.scoringStartsAtRound).toBe("Divisional");

      // Wild Card doesn't score
      expect(NFL_14.rounds[0].name).toBe("Wild Card");
      expect(NFL_14.rounds[0].isScoring).toBe(false);

      // Divisional and beyond score
      expect(NFL_14.rounds[1].name).toBe("Divisional");
      expect(NFL_14.rounds[1].isScoring).toBe(true);
      expect(NFL_14.rounds[2].isScoring).toBe(true);
      expect(NFL_14.rounds[3].isScoring).toBe(true);
    });
  });

  describe("Round Advancement", () => {
    it("rounds correctly feed into next rounds", () => {
      // 8-team bracket
      expect(SIMPLE_8.rounds[0].feedsInto).toBe("Semifinals");
      expect(SIMPLE_8.rounds[1].feedsInto).toBe("Finals");
      expect(SIMPLE_8.rounds[2].feedsInto).toBe(null);

      // NCAA bracket
      expect(NCAA_68.rounds[0].feedsInto).toBe("Round of 64");
      expect(NCAA_68.rounds[1].feedsInto).toBe("Round of 32");
      expect(NCAA_68.rounds[2].feedsInto).toBe("Sweet Sixteen");
      expect(NCAA_68.rounds[3].feedsInto).toBe("Elite Eight");
      expect(NCAA_68.rounds[4].feedsInto).toBe("Final Four");
      expect(NCAA_68.rounds[5].feedsInto).toBe("Championship");
      expect(NCAA_68.rounds[6].feedsInto).toBe(null);
    });
  });

  describe("Match Counts", () => {
    it("calculates correct match counts for each round", () => {
      // 16-team bracket
      expect(SIMPLE_16.rounds[0].matchCount).toBe(8); // Round of 16
      expect(SIMPLE_16.rounds[1].matchCount).toBe(4); // QF
      expect(SIMPLE_16.rounds[2].matchCount).toBe(2); // SF
      expect(SIMPLE_16.rounds[3].matchCount).toBe(1); // Finals

      // NCAA bracket
      expect(NCAA_68.rounds[0].matchCount).toBe(4); // First Four
      expect(NCAA_68.rounds[1].matchCount).toBe(32); // Round of 64
      expect(NCAA_68.rounds[2].matchCount).toBe(16); // Round of 32
      expect(NCAA_68.rounds[3].matchCount).toBe(8); // Sweet Sixteen
      expect(NCAA_68.rounds[4].matchCount).toBe(4); // Elite Eight
      expect(NCAA_68.rounds[5].matchCount).toBe(2); // Final Four
      expect(NCAA_68.rounds[6].matchCount).toBe(1); // Championship
    });
  });

  describe("getBracketTemplate", () => {
    it("returns correct template by id", () => {
      expect(getBracketTemplate("simple_4")).toBe(SIMPLE_4);
      expect(getBracketTemplate("simple_8")).toBe(SIMPLE_8);
      expect(getBracketTemplate("simple_16")).toBe(SIMPLE_16);
      expect(getBracketTemplate("ncaa_68")).toBe(NCAA_68);
    });

    it("returns undefined for invalid id", () => {
      expect(getBracketTemplate("invalid")).toBeUndefined();
    });
  });

  describe("getScoringRoundType", () => {
    it("identifies quarterfinals (4 matches)", () => {
      const type = getScoringRoundType("Quarterfinals", SIMPLE_8);
      expect(type).toBe("quarterfinals");
    });

    it("identifies semifinals (2 matches)", () => {
      const type = getScoringRoundType("Semifinals", SIMPLE_8);
      expect(type).toBe("semifinals");
    });

    it("identifies finals (1 match)", () => {
      const type = getScoringRoundType("Finals", SIMPLE_8);
      expect(type).toBe("finals");
    });

    it("returns null for non-scoring rounds", () => {
      const type = getScoringRoundType("Round of 16", SIMPLE_16);
      expect(type).toBe(null);
    });

    it("works with NCAA template", () => {
      expect(getScoringRoundType("Elite Eight", NCAA_68)).toBe("quarterfinals");
      expect(getScoringRoundType("Final Four", NCAA_68)).toBe("semifinals");
      expect(getScoringRoundType("Championship", NCAA_68)).toBe("finals");
      expect(getScoringRoundType("Sweet Sixteen", NCAA_68)).toBe(null);
    });
  });
});
