import { describe, it, expect, beforeEach } from 'vitest';
import { useManaStore } from '../stores/manaStore';
import { ELEMENTS, BASE_UNLOCKED_ELEMENTS, BASE_ELEMENTS } from '../constants/elements';

// ─── Regression test: "Unlock All Base Elements" only unlocks 7 base ───────
// Issue #374: Button was unlocking all 22 elements instead of just 7 base.

function resetManaStore() {
  useManaStore.setState({
    rawMana: 10000,
    meditateTicks: 0,
    totalManaGathered: 0,
    elements: Object.fromEntries(
      Object.keys(ELEMENTS).map(k => [
        k,
        {
          current: 0,
          max: 10,
          baseMax: 10,
          unlocked: BASE_UNLOCKED_ELEMENTS.includes(k),
        },
      ])
    ) as Record<string, { current: number; max: number; baseMax: number; unlocked: boolean }>,
    elementRegen: {},
  });
}

describe('Unlock All Base Elements debug button', () => {
  beforeEach(() => {
    resetManaStore();
  });

  it('BASE_ELEMENTS contains exactly 7 base elements', () => {
    expect(BASE_ELEMENTS).toHaveLength(7);
    expect(BASE_ELEMENTS).toContain('fire');
    expect(BASE_ELEMENTS).toContain('water');
    expect(BASE_ELEMENTS).toContain('air');
    expect(BASE_ELEMENTS).toContain('earth');
    expect(BASE_ELEMENTS).toContain('light');
    expect(BASE_ELEMENTS).toContain('dark');
    expect(BASE_ELEMENTS).toContain('death');
  });

  it('BASE_ELEMENTS does NOT contain utility, composite, or exotic elements', () => {
    expect(BASE_ELEMENTS).not.toContain('transference');
    expect(BASE_ELEMENTS).not.toContain('metal');
    expect(BASE_ELEMENTS).not.toContain('sand');
    expect(BASE_ELEMENTS).not.toContain('lightning');
    expect(BASE_ELEMENTS).not.toContain('frost');
    expect(BASE_ELEMENTS).not.toContain('blackflame');
    expect(BASE_ELEMENTS).not.toContain('radiantflames');
    expect(BASE_ELEMENTS).not.toContain('miasma');
    expect(BASE_ELEMENTS).not.toContain('shadowglass');
    expect(BASE_ELEMENTS).not.toContain('crystal');
    expect(BASE_ELEMENTS).not.toContain('stellar');
    expect(BASE_ELEMENTS).not.toContain('void');
    expect(BASE_ELEMENTS).not.toContain('soul');
    expect(BASE_ELEMENTS).not.toContain('time');
    expect(BASE_ELEMENTS).not.toContain('plasma');
  });

  it('unlockElement for all BASE_ELEMENTS only unlocks those 7', () => {
    const store = useManaStore.getState();

    // All base elements should start locked (only transference is base-unlocked)
    BASE_ELEMENTS.forEach(e => {
      expect(store.elements[e]?.unlocked).toBe(false);
    });

    // Unlock all base elements (cost 0, simulating debug button)
    BASE_ELEMENTS.forEach(e => {
      store.unlockElement(e, 0);
    });

    const afterState = useManaStore.getState();

    // All 7 base elements should now be unlocked
    BASE_ELEMENTS.forEach(e => {
      expect(afterState.elements[e]?.unlocked).toBe(true);
    });

    // Non-base elements should NOT be unlocked
    const nonBaseElements = Object.keys(ELEMENTS).filter(
      e => !BASE_ELEMENTS.includes(e as never) && !BASE_UNLOCKED_ELEMENTS.includes(e)
    );
    nonBaseElements.forEach(e => {
      expect(afterState.elements[e]?.unlocked).toBe(false);
    });
  });

  it('debug handleUnlockBase does not unlock transference', () => {
    const store = useManaStore.getState();

    // Verify transference starts unlocked
    expect(store.elements['transference']?.unlocked).toBe(true);

    // Run the unlock logic
    BASE_ELEMENTS.forEach(e => {
      if (!store.elements[e]?.unlocked) {
        store.unlockElement(e, 0);
      }
    });

    const afterState = useManaStore.getState();
    // transference was already unlocked, should still be unlocked
    expect(afterState.elements['transference']?.unlocked).toBe(true);
    // But no new utility elements were unlocked
    expect(afterState.elements['metal']?.unlocked).toBe(false);
  });

  it('total unlocked count after unlock base is exactly 8 (7 base + transference)', () => {
    const store = useManaStore.getState();
    const unlockedBefore = Object.values(store.elements).filter(e => e.unlocked).length;
    // Only transference should be unlocked initially
    expect(unlockedBefore).toBe(1);

    BASE_ELEMENTS.forEach(e => {
      store.unlockElement(e, 0);
    });

    const afterState = useManaStore.getState();
    const unlockedAfter = Object.values(afterState.elements).filter(e => e.unlocked).length;
    expect(unlockedAfter).toBe(8); // 7 base + transference
  });
});
