import { describe, it, expect } from "vitest";
import { CHARACTER_POOL, assignCharacter } from "./agentCharacters";

describe("agentCharacters", () => {
  describe("CHARACTER_POOL", () => {
    it("contains exactly 6 characters", () => {
      expect(CHARACTER_POOL).toHaveLength(6);
    });

    it("each character has a name, avatar, title, and description", () => {
      for (const character of CHARACTER_POOL) {
        expect(character.name).toBeTruthy();
        expect(character.avatar).toBeTruthy();
        expect(character.avatar).toMatch(/^https:\/\//u);
        expect(character.title).toBeTruthy();
        expect(character.description).toBeTruthy();
      }
    });

    it("all names are unique", () => {
      const names = CHARACTER_POOL.map((c) => c.name);
      const uniqueNames = new Set(names);
      expect(uniqueNames.size).toBe(CHARACTER_POOL.length);
    });
  });

  describe("assignCharacter", () => {
    it("returns a character from the pool", () => {
      const character = assignCharacter([]);
      const names = CHARACTER_POOL.map((c) => c.name);
      expect(names).toContain(character.name);
    });

    it("avoids names already in use when possible", () => {
      const takenNames = ["Amari", "Keiko", "Minori", "Reina", "Tatsumi"];
      // Run many times to confirm we never get a taken name
      for (let i = 0; i < 50; i++) {
        const character = assignCharacter(takenNames);
        expect(takenNames).not.toContain(character.name);
        expect(character.name).toBe("Yumiko");
      }
    });

    it("picks from the full pool when all 6 names are taken", () => {
      const allNames = CHARACTER_POOL.map((c) => c.name);
      const seen = new Set<string>();
      // Run enough times that we'd statistically see variety
      for (let i = 0; i < 100; i++) {
        const character = assignCharacter(allNames);
        seen.add(character.name);
      }
      // Should still pick valid characters
      for (const name of seen) {
        expect(allNames).toContain(name);
      }
      // With 100 runs and 6 characters, we should see at least 2 distinct names
      expect(seen.size).toBeGreaterThan(1);
    });

    it("returns a character with name, avatar, title, and description", () => {
      const character = assignCharacter([]);
      expect(character.name).toBeTruthy();
      expect(character.avatar).toBeTruthy();
      expect(character.title).toBeTruthy();
      expect(character.description).toBeTruthy();
    });

    it("works when the active list is empty", () => {
      const character = assignCharacter([]);
      expect(character).toBeDefined();
    });
  });
});
