import { describe, it, expect } from 'vitest';
import { generateGuardianName } from '../data/guardian-encounters';
import { getProceduralGuardian } from '../data/guardian-procedural';
import { getGuardianForFloor } from '../data/guardian-encounters';

describe('guardian name uniqueness', () => {
  it('generateGuardianName produces different names for same element at different 100-floor cycles', () => {
    // These floors previously collided: same element, same prefix, same title
    const name170 = generateGuardianName(['crystal'], 170);
    const name370 = generateGuardianName(['crystal'], 370);
    expect(name170).not.toBe(name370);
  });

  it('generateGuardianName produces different names for multi-element guardians at different cycles', () => {
    // Floors 200/230 share elements [crystal, stellar, void]
    const name200 = generateGuardianName(['crystal', 'stellar', 'void'], 200);
    const name230 = generateGuardianName(['crystal', 'stellar', 'void'], 230);
    expect(name200).not.toBe(name230);

    // Floors 210/240 share elements [soul, time, plasma]
    const name210 = generateGuardianName(['soul', 'time', 'plasma'], 210);
    const name240 = generateGuardianName(['soul', 'time', 'plasma'], 240);
    expect(name210).not.toBe(name240);
  });

  it('all static guardian floors (10-240) produce unique names', () => {
    const names = new Map<string, number>();
    for (let floor = 10; floor <= 240; floor += 10) {
      const g = getGuardianForFloor(floor);
      if (g) {
        const existing = names.get(g.name);
        expect(existing).toBeUndefined(
          `Duplicate name "${g.name}" at floors ${existing} and ${floor}`,
        );
        names.set(g.name, floor);
      }
    }
  });

  it('all procedural guardian floors (250-490) produce unique names', () => {
    const names = new Map<string, number>();
    for (let floor = 250; floor <= 490; floor += 10) {
      const g = getProceduralGuardian(floor);
      if (g) {
        const existing = names.get(g.name);
        expect(existing).toBeUndefined(
          `Duplicate name "${g.name}" at floors ${existing} and ${floor}`,
        );
        names.set(g.name, floor);
      }
    }
  });

  it('all guardian floors (10-490) produce unique names', () => {
    const names = new Map<string, number>();
    for (let floor = 10; floor <= 490; floor += 10) {
      const g = getGuardianForFloor(floor);
      if (g) {
        const existing = names.get(g.name);
        expect(existing).toBeUndefined(
          `Duplicate name "${g.name}" at floors ${existing} and ${floor}`,
        );
        names.set(g.name, floor);
      }
    }
  });

  it('generateGuardianName is deterministic (same inputs always produce same output)', () => {
    const name1 = generateGuardianName(['fire', 'water'], 250);
    const name2 = generateGuardianName(['fire', 'water'], 250);
    expect(name1).toBe(name2);

    const name3 = generateGuardianName(['crystal'], 170);
    const name4 = generateGuardianName(['crystal'], 170);
    expect(name3).toBe(name4);
  });

  it('generateGuardianName includes a title', () => {
    const name = generateGuardianName(['crystal'], 170);
    expect(name).toMatch(/ the (Warden|Keeper|Lord|Titan|Sovereign|Guardian|Sentinel|Champion|Overlord|Archon)$/);
  });
});
