'use client';

import { useMemo, type ReactNode } from 'react';
import { useManaStore } from '@/lib/game/stores/manaStore';
import { usePrestigeStore } from '@/lib/game/stores/prestigeStore';
import { useUIStore } from '@/lib/game/stores/uiStore';
import { useCombatStore } from '@/lib/game/stores/combatStore';
import { useGameStore } from '@/lib/game/stores/gameStore';
import { computeEffects } from '@/lib/game/effects/upgrade-effects';
import { hasSpecial, SPECIAL_EFFECTS } from '@/lib/game/effects/special-effects';
import {
  computeMaxMana,
  computeRegen,
  computeClickMana,
  getMeditationBonus,
  canAffordSpellCost,
  calcDamage,
  getFloorElement,
  getBoonBonuses,
  getIncursionStrength,
} from '@/lib/game/utils';
import {
  ELEMENTS,
  GUARDIANS,
  SPELLS_DEF,
} from '@/lib/game/constants';
import type { ElementDef, GuardianDef, SpellDef, GameAction } from '@/lib/game/types';
import type { UnifiedStore, GameContextValue } from './types';
import { GameContext } from './context-create';

function createUnifiedStore(
  gameStore: ReturnType<typeof useGameStore.getState>,
  manaState: ReturnType<typeof useManaStore.getState>,
  prestigeState: ReturnType<typeof usePrestigeStore.getState>,
  uiState: ReturnType<typeof useUIStore.getState>,
  combatState: ReturnType<typeof useCombatStore.getState>
): UnifiedStore {
  return {
    // From gameStore
    day: gameStore.day,
    hour: gameStore.hour,
    incursionStrength: gameStore.incursionStrength,
    containmentWards: gameStore.containmentWards,
    initialized: gameStore.initialized,
    tick: gameStore.tick,
    resetGame: gameStore.resetGame,
    gatherMana: gameStore.gatherMana,
    startNewLoop: gameStore.startNewLoop,

    // From manaStore
    rawMana: manaState.rawMana,
    meditateTicks: manaState.meditateTicks,
    totalManaGathered: manaState.totalManaGathered,
    elements: manaState.elements,
    setRawMana: manaState.setRawMana,
    addRawMana: manaState.addRawMana,
    spendRawMana: manaState.spendRawMana,
    convertMana: manaState.convertMana,
    unlockElement: manaState.unlockElement,
    craftComposite: manaState.craftComposite,

    // From prestigeStore
    loopCount: prestigeState.loopCount,
    insight: prestigeState.insight,
    totalInsight: prestigeState.totalInsight,
    loopInsight: prestigeState.loopInsight,
    prestigeUpgrades: prestigeState.prestigeUpgrades,
    memorySlots: prestigeState.memorySlots,
    pactSlots: prestigeState.pactSlots,
    memories: prestigeState.memories,
    defeatedGuardians: prestigeState.defeatedGuardians,
    signedPacts: prestigeState.signedPacts,
    pactRitualFloor: prestigeState.pactRitualFloor,
    pactRitualProgress: prestigeState.pactRitualProgress,
    doPrestige: prestigeState.doPrestige,
    addMemory: prestigeState.addMemory,
    removeMemory: prestigeState.removeMemory,
    clearMemories: prestigeState.clearMemories,
    startPactRitual: prestigeState.startPactRitual,
    cancelPactRitual: prestigeState.cancelPactRitual,
    removePact: prestigeState.removePact,
    defeatGuardian: prestigeState.defeatGuardian,

    // From combatStore
    currentFloor: combatState.currentFloor,
    floorHP: combatState.floorHP,
    floorMaxHP: combatState.floorMaxHP,
    maxFloorReached: combatState.maxFloorReached,
    activeSpell: combatState.activeSpell,
    currentAction: combatState.currentAction,
    castProgress: combatState.castProgress,
    spells: combatState.spells,
    setAction: combatState.setAction,
    setSpell: combatState.setSpell,
    learnSpell: combatState.learnSpell,
    advanceFloor: combatState.advanceFloor,

    // From uiStore
    log: uiState.logs,
    paused: uiState.paused,
    gameOver: uiState.gameOver,
    victory: uiState.victory,
    addLog: uiState.addLog,
    togglePause: uiState.togglePause,
    setPaused: uiState.setPaused,
    setGameOver: uiState.setGameOver,
  };
}

export function GameProvider({ children }: { children: ReactNode }) {
  // Get all individual stores
  const gameStore = useGameStore();
  const manaState = useManaStore();
  const prestigeState = usePrestigeStore();
  const uiState = useUIStore();
  const combatState = useCombatStore();

  // Create unified store object for backward compatibility
  const unifiedStore = useMemo(
    () => createUnifiedStore(gameStore, manaState, prestigeState, uiState, combatState),
    [gameStore, manaState, prestigeState, uiState, combatState]
  );

  // Computed effects from upgrades
  const upgradeEffects = useMemo(
    () => computeEffects({}, {}),
    []
  );

  // Create a minimal state object for compute functions
  const stateForCompute = useMemo(() => ({
    prestigeUpgrades: prestigeState.prestigeUpgrades,
    signedPacts: prestigeState.signedPacts,
    rawMana: manaState.rawMana,
    meditateTicks: manaState.meditateTicks,
    incursionStrength: gameStore.incursionStrength,
  }), [prestigeState, manaState, gameStore.incursionStrength]);

  // Derived stats
  const maxMana = useMemo(
    () => computeMaxMana(stateForCompute, upgradeEffects),
    [stateForCompute, upgradeEffects]
  );

  const baseRegen = useMemo(
    () => computeRegen(stateForCompute, upgradeEffects),
    [stateForCompute, upgradeEffects]
  );

  const clickMana = useMemo(() => computeClickMana(stateForCompute), [stateForCompute]);

  // Floor element from combat store
  const floorElem = useMemo(() => getFloorElement(combatState.currentFloor), [combatState.currentFloor]);
  const floorElemDef = ELEMENTS[floorElem];
  const isGuardianFloor = !!GUARDIANS[combatState.currentFloor];
  const currentGuardian = GUARDIANS[combatState.currentFloor];
  const activeSpellDef = SPELLS_DEF[combatState.activeSpell];

  const meditationMultiplier = useMemo(
    () => getMeditationBonus(manaState.meditateTicks, {}, upgradeEffects.meditationEfficiency),
    [manaState.meditateTicks, upgradeEffects.meditationEfficiency]
  );

  const incursionStrength = useMemo(
    () => getIncursionStrength(gameStore.day, gameStore.hour),
    [gameStore.day, gameStore.hour]
  );

  const studySpeedMult = 1;

  const studyCostMult = 1;

  // Effective regen calculations
  const effectiveRegenWithSpecials = baseRegen * (1 - incursionStrength);

  const manaCascadeBonus = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_CASCADE)
    ? Math.floor(maxMana / 100) * 0.1
    : 0;

  const manaWaterfallBonus = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_WATERFALL)
    ? Math.floor(maxMana / 100) * 0.25
    : 0;

  const effectiveRegen = (effectiveRegenWithSpecials + manaCascadeBonus + manaWaterfallBonus) * meditationMultiplier;

  // Has special flags for UI
  const hasManaWaterfall = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_WATERFALL);
  const hasFlowSurge = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.FLOW_SURGE);
  const hasManaOverflow = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_OVERFLOW);
  const hasEternalFlow = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.ETERNAL_FLOW);

  // Active boons
  const activeBoons = useMemo(
    () => getBoonBonuses(prestigeState.signedPacts),
    [prestigeState.signedPacts]
  );

  // DPS calculation - based on active spell, attack speed, and damage
  const dps = useMemo(() => {
    if (!activeSpellDef) return 0;
    const baseDmg = calcDamage(
      { signedPacts: prestigeState.signedPacts },
      combatState.activeSpell,
      floorElem
    );
    const dmgWithEffects = baseDmg * upgradeEffects.baseDamageMultiplier + upgradeEffects.baseDamageBonus;
    const attackSpeed = (1 + 0 * 0.05) * upgradeEffects.attackSpeedMultiplier;
    const castSpeed = activeSpellDef.castSpeed || 1;
    return dmgWithEffects * attackSpeed * castSpeed;
  }, [activeSpellDef, prestigeState.signedPacts, floorElem, upgradeEffects, combatState.activeSpell]);

  // Helper functions
  const canCastSpell = (spellId: string): boolean => {
    const spell = SPELLS_DEF[spellId];
    if (!spell) return false;
    return canAffordSpellCost(spell.cost, manaState.rawMana, manaState.elements);
  };

  const value: GameContextValue = {
    store: unifiedStore,
    manaStore: manaState,
    prestigeStore: prestigeState,
    uiStore: uiState,
    combatStore: combatState,
    upgradeEffects,
    maxMana,
    baseRegen,
    clickMana,
    floorElem,
    floorElemDef,
    isGuardianFloor,
    currentGuardian,
    activeSpellDef,
    meditationMultiplier,
    incursionStrength,
    studySpeedMult,
    studyCostMult,
    effectiveRegenWithSpecials,
    manaCascadeBonus,
    manaWaterfallBonus,
    effectiveRegen,
    hasManaWaterfall,
    hasFlowSurge,
    hasManaOverflow,
    hasEternalFlow,
    dps,
    activeBoons,
    canCastSpell,
    hasSpecial,
    SPECIAL_EFFECTS,
  };

  return <GameContext.Provider value={value}>{children}</GameContext.Provider>;
}

GameProvider.displayName = "GameProvider";
