import { describe, it, expect, beforeEach } from 'vitest';
import { useDisciplineStore } from '../stores/discipline-slice';
import { useCombatStore } from '../stores/combatStore';
import { useGameStore } from '../stores/gameStore';
import { useManaStore } from '../stores/manaStore';
import { usePrestigeStore } from '../stores/prestigeStore';
import { useUIStore } from '../stores/uiStore';
import { useAttunementStore } from '../stores/attunementStore';
import { useCraftingStore } from '../stores/craftingStore';

function resetAllStores() {
  useUIStore.setState({
    paused: false,
    gameOver: false,
    victory: false,
    logs: [],
  });

  useGameStore.setState({
    day: 1,
    hour: 0,
    incursionStrength: 0,
    containmentWards: 0,
    initialized: true,
  });

  useManaStore.setState({
    rawMana: 1000,
    meditateTicks: 0,
    totalManaGathered: 0,
    elements: {
      transference: { unlocked: true, current: 50, max: 50, baseMax: 50 },
    },
  });

  useCombatStore.setState({
    currentFloor: 1,
    floorHP: 0,
    floorMaxHP: 0,
    maxFloorReached: 1,
    activeSpell: 'manaBolt',
    currentAction: 'meditate',
    castProgress: 0,
    spireMode: false,
    currentRoom: { roomType: 'combat', enemies: [] },
    clearedFloors: {},
    climbDirection: null,
    isDescending: false,
    startFloor: 1,
    exitFloor: 1,
    currentRoomIndex: 0,
    roomsPerFloor: 5,
    runId: 0,
    descentPeak: null,
    roomResetState: {},
    clearedRooms: {},
    isDescentComplete: false,
    golemancy: { activeGolems: [], lastSummonFloor: 0, golemDesigns: {}, golemLoadout: [] },
    equipmentSpellStates: [],
    weaponCastProgress: {},
    comboHitCount: 0,
    floorHitCount: 0,
    spells: { manaBolt: { learned: true, level: 1, studyProgress: 0 } },
    activityLog: [],
    achievements: { unlocked: [], progress: {} },
    totalSpellsCast: 0,
    totalDamageDealt: 0,
    totalCraftsCompleted: 0,
  });

  usePrestigeStore.setState({
    loopCount: 0,
    insight: 0,
    totalInsight: 0,
    loopInsight: 0,
    prestigeUpgrades: {},
    pactSlots: 1,
    defeatedGuardians: [],
    signedPacts: [],
    signedPactDetails: {},
    pactRitualFloor: null,
    pactRitualProgress: 0,
  });

  useDisciplineStore.setState({
    disciplines: {},
    activeIds: [],
    concurrentLimit: 1,
    totalXP: 0,
    processedPerks: [],
    practicingCallbacks: null,
  });

  useAttunementStore.setState({
    attunements: {
      enchanter: { active: true, level: 1, xp: 0 },
    },
  });

  useCraftingStore.setState({
    designProgress: null,
    designProgress2: null,
    preparationProgress: null,
    applicationProgress: null,
    equipmentCraftingProgress: null,
    completedEnchantmentDesigns: [],
    unlockedEffects: [],
    equippedInstances: {},
    equipmentInstances: {},
    lootInventory: { materials: {}, blueprints: [] },
    enchantmentSelection: {
      selectedEquipmentType: null,
      selectedEffects: [],
      designName: '',
      selectedDesign: null,
      selectedEquipmentInstance: null,
    },
    lastError: null,
  });
}

describe('Issue #347 — disciplines deactivate on spire entry', () => {
  beforeEach(resetAllStores);

  it('should deactivate all active disciplines when entering the Spire', () => {
    // Set up sufficient mana and activate a discipline
    useManaStore.setState({ rawMana: 1000, elements: {} });

    // Activate Raw Mana Mastery
    useDisciplineStore.getState().activate('raw-mastery');
    expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
    expect(useDisciplineStore.getState().activeIds.length).toBe(1);

    // Verify discipline is draining mana / accumulating XP
    useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
    expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBeGreaterThan(0);

    // Enter the Spire
    useCombatStore.getState().enterSpireMode();

    // ASSERT: All disciplines should be deactivated
    expect(useDisciplineStore.getState().activeIds.length).toBe(0);
  });

  it('should not accrue discipline XP during spire mode', () => {
    useManaStore.setState({ rawMana: 1000, elements: {} });

    // Activate and build up some XP
    useDisciplineStore.getState().activate('raw-mastery');
    useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
    useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
    const xpBefore = useDisciplineStore.getState().disciplines['raw-mastery'].xp;
    expect(xpBefore).toBeGreaterThan(0);

    // Enter the Spire
    useCombatStore.getState().enterSpireMode();

    // Confirm spire mode is active
    expect(useCombatStore.getState().spireMode).toBe(true);

    // Tick the game — discipline should NOT accrue XP because spireMode guard skips processTick
    useGameStore.getState().tick();
    useGameStore.getState().tick();
    useGameStore.getState().tick();

    // XP should remain unchanged from before entering the spire
    expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBe(xpBefore);
    expect(useDisciplineStore.getState().activeIds.length).toBe(0);
  });

  it('should deactivate all disciplines on spire exit as a safety measure', () => {
    useManaStore.setState({ rawMana: 1000, elements: {} });

    // Activate a discipline before entering
    useDisciplineStore.getState().activate('raw-mastery');

    // Enter spire (deactivates disciplines)
    useCombatStore.getState().enterSpireMode();
    expect(useCombatStore.getState().spireMode).toBe(true);
    expect(useDisciplineStore.getState().activeIds.length).toBe(0);

    // Simulate a discipline somehow reactivated during spire (edge case)
    useDisciplineStore.getState().disciplines['raw-mastery'] = { id: 'raw-mastery', xp: 0, paused: false };
    useDisciplineStore.setState({ activeIds: ['raw-mastery'] });
    expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');

    // Exit spire — should still clean up disciplines
    useCombatStore.getState().exitSpireMode();
    expect(useDisciplineStore.getState().activeIds.length).toBe(0);
    expect(useCombatStore.getState().spireMode).toBe(false);
  });

  it('deactivateAll() should preserve XP and pause state', () => {
    useManaStore.setState({ rawMana: 1000, elements: {} });

    useDisciplineStore.getState().activate('raw-mastery');
    useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
    useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
    const xpBefore = useDisciplineStore.getState().disciplines['raw-mastery'].xp;

    // Call deactivateAll directly
    useDisciplineStore.getState().deactivateAll();

    expect(useDisciplineStore.getState().activeIds.length).toBe(0);
    expect(useDisciplineStore.getState().disciplines['raw-mastery'].xp).toBe(xpBefore);
    expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(true);
  });

  it('deactivateAll() should work with multiple active disciplines', () => {
    useManaStore.setState({
      rawMana: 1000,
      elements: {
        transference: { unlocked: true, current: 100, max: 100, baseMax: 100 },
      },
    });

    // Temporarily raise concurrent limit for this test
    useDisciplineStore.setState({ concurrentLimit: 3 });

    useDisciplineStore.getState().activate('raw-mastery');
    useDisciplineStore.getState().activate('attune-transference');

    expect(useDisciplineStore.getState().activeIds.length).toBe(2);

    useDisciplineStore.getState().deactivateAll();

    expect(useDisciplineStore.getState().activeIds.length).toBe(0);
  });
});
