import { describe, it, expect } from 'vitest';

describe('SpireSummaryTab module structure', () => {
  it('exports SpireSummaryTab from its module', async () => {
    const mod = await import('./SpireSummaryTab');
    expect(mod.SpireSummaryTab).toBeDefined();
    expect(typeof mod.SpireSummaryTab).toBe('function');
  }, 30000);

  it('SpireSummaryTab has correct displayName', async () => {
    const { SpireSummaryTab } = await import('./SpireSummaryTab');
    expect(SpireSummaryTab.displayName).toBe('SpireSummaryTab');
  });
});

describe('Tab barrel export', () => {
  it('includes SpireSummaryTab in the tabs index', async () => {
    const mod = await import('@/components/game/tabs');
    expect(mod.SpireSummaryTab).toBeDefined();
    expect(typeof mod.SpireSummaryTab).toBe('function');
  });
});

describe('Guardian data', () => {
  it('has static guardians plus procedural guardians', async () => {
    const { getAllGuardianFloors } = await import('@/lib/game/data/guardian-encounters');
    const floors = getAllGuardianFloors();
    // Static: 10-80 (8), 90-110 (3), 130-160 (4), 170-200 (4) = 19 static
    // Procedural: 210-450 every 10 = 25 procedural
    expect(floors.length).toBeGreaterThanOrEqual(19);
  });

  it('guardians are at expected floors for all tiers', async () => {
    const { getGuardianForFloor } = await import('@/lib/game/data/guardian-encounters');
    // Base: 10-80, Composite: 90-110, Comp+Components: 130-160, Exotic: 170-200
    for (const floor of [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 130, 140, 150, 160, 170, 180, 190, 200]) {
      expect(getGuardianForFloor(floor)).not.toBeNull();
    }
  });

  it('follows element progression: base → composite → exotic', async () => {
    const { getGuardianForFloor } = await import('@/lib/game/data/guardian-encounters');
    // Elements are now arrays
    expect(getGuardianForFloor(10)!.element).toEqual(['fire']);
    expect(getGuardianForFloor(20)!.element).toEqual(['water']);
    expect(getGuardianForFloor(30)!.element).toEqual(['air']);
    expect(getGuardianForFloor(40)!.element).toEqual(['earth']);
    expect(getGuardianForFloor(50)!.element).toEqual(['light']);
    expect(getGuardianForFloor(60)!.element).toEqual(['dark']);
    expect(getGuardianForFloor(70)!.element).toEqual(['death']);
    expect(getGuardianForFloor(80)!.element).toEqual(['transference']);
    expect(getGuardianForFloor(90)!.element).toEqual(['metal']);
    expect(getGuardianForFloor(100)!.element).toEqual(['sand']);
    expect(getGuardianForFloor(110)!.element).toEqual(['lightning']);
    expect(getGuardianForFloor(170)!.element).toEqual(['crystal']);
    expect(getGuardianForFloor(180)!.element).toEqual(['stellar']);
    expect(getGuardianForFloor(190)!.element).toEqual(['void']);
  });

  it('all static guardians have required fields', async () => {
    const { getGuardianForFloor } = await import('@/lib/game/data/guardian-encounters');
    for (const floor of [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 130, 140, 150, 160, 170, 180, 190, 200]) {
      const def = getGuardianForFloor(floor)!;
      expect(def.name).toBeTruthy();
      expect(def.element).toBeTruthy();
      expect(Array.isArray(def.element)).toBe(true);
      expect(def.hp).toBeGreaterThan(0);
      expect(def.color).toBeTruthy();
      expect(def.boons).toBeInstanceOf(Array);
      expect(def.boons.length).toBeGreaterThan(0);
    }
  });

  it('all static guardians have unique element sets', async () => {
    const { getGuardianForFloor } = await import('@/lib/game/data/guardian-encounters');
    const floors = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 130, 140, 150, 160, 170, 180, 190, 200];
    const elementKeys = floors.map((f) => getGuardianForFloor(f)!.element.join(','));
    const uniqueElements = new Set(elementKeys);
    expect(uniqueElements.size).toBe(elementKeys.length);
  });
});

describe('Combat store spire fields', () => {
  it('useCombatStore is importable', async () => {
    const mod = await import('@/lib/game/stores');
    expect(mod.useCombatStore).toBeDefined();
    expect(typeof mod.useCombatStore).toBe('function');
  });
});

describe('Floor element cycle', () => {
  it('FLOOR_ELEM_CYCLE has 7 elements', async () => {
    const { FLOOR_ELEM_CYCLE } = await import('@/lib/game/constants');
    expect(FLOOR_ELEM_CYCLE.length).toBe(7);
  });

  it('element opposites define expected pairs', async () => {
    const { ELEMENT_OPPOSITES } = await import('@/lib/game/constants');
    // ELEMENT_OPPOSITES now uses arrays to support multiple counters per element
    expect(ELEMENT_OPPOSITES['fire']).toEqual(expect.arrayContaining(['water']));
    expect(ELEMENT_OPPOSITES['water']).toEqual(expect.arrayContaining(['fire', 'lightning']));
    expect(ELEMENT_OPPOSITES['air']).toEqual(expect.arrayContaining(['earth']));
    expect(ELEMENT_OPPOSITES['earth']).toEqual(expect.arrayContaining(['air']));
    expect(ELEMENT_OPPOSITES['light']).toEqual(expect.arrayContaining(['dark']));
    expect(ELEMENT_OPPOSITES['dark']).toEqual(expect.arrayContaining(['light']));
    // lightning is weak to earth (earth counters lightning, spec §4.2)
    expect(ELEMENT_OPPOSITES['lightning']).toEqual(expect.arrayContaining(['earth']));
  });
});

describe('File size limits (400 lines max)', () => {
  it('SpireSummaryTab.tsx is under 400 lines', async () => {
    const fs = await import('fs');
    const path = await import('path');
    const filePath = path.join(__dirname, 'SpireSummaryTab.tsx');
    const content = fs.readFileSync(filePath, 'utf-8');
    const lines = content.split('\n').length;
    expect(lines).toBeLessThanOrEqual(400);
  });
});
