// ─── Crafting Store ─────────────────────────────────────────────────────
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import type { EquipmentSlot } from '../types/equipmentSlot';
import type { CraftingStore, CraftingState } from './craftingStore.types';
import * as CraftingUtils from '../crafting-utils';
import * as CraftingDesign from '../crafting-design';
import { useManaStore } from './manaStore';
import { useCombatStore } from './combatStore';

import { useUIStore } from './uiStore';
import { getEnchantingEfficiencyBonus } from '../effects/discipline-effects';
import * as ApplicationActions from '../crafting-actions/application-actions';
import * as PreparationActions from '../crafting-actions/preparation-actions';
import { equipItem as equipItemAction, unequipItem as unequipItemAction } from '../crafting-actions/equipment-actions';
import { ErrorCode } from '../utils/result';
import { createSafeStorage } from '../utils/safe-persist';
import { createDefaultCraftingState } from './crafting-initial-state';
import { craftMaterial as craftMaterialAction } from '../crafting-actions/crafting-material-actions';
import { processEquipmentCraftingTick } from './crafting-equipment-tick';
import { startCraftingEquipment, cancelEquipmentCrafting, startFabricatorCrafting } from './pipelines/equipment-crafting';

export const useCraftingStore = create<CraftingStore>()(
  persist(
    (set, get) => {
      const defaultState = createDefaultCraftingState();
      return {
        ...defaultState,

        // Actions
        setDesignProgress: (progress) => set({ designProgress: progress }),
        setDesignProgress2: (progress) => set({ designProgress2: progress }),
        setPreparationProgress: (progress) => set({ preparationProgress: progress }),
        setApplicationProgress: (progress) => set({ applicationProgress: progress }),
        setEquipmentCraftingProgress: (progress) => set({ equipmentCraftingProgress: progress }),

        // Enchantment design actions
        startDesigningEnchantment: (name, equipmentTypeId, effects) => {
          const state = get(); // crafting state
          const efficiencyBonus = getEnchantingEfficiencyBonus();

          const validation = CraftingDesign.validateDesignEffects(effects, equipmentTypeId, 0, state.unlockedEffects);
          if (!validation.valid) return false;

          const equipType = CraftingUtils.getEquipmentType(equipmentTypeId);
          if (!equipType) return false;

          const totalCapacityCost = CraftingDesign.calculateDesignCapacityCost(effects, efficiencyBonus);

          if (totalCapacityCost > equipType.baseCapacity) return false;

          let updates: Partial<CraftingState> = {};

          if (!state.designProgress) {
            updates = {
              designProgress: {
                designId: CraftingUtils.generateDesignId(),
                progress: 0,
                required: CraftingDesign.calculateDesignTime(effects),
                name,
                equipmentType: equipmentTypeId,
                effects,
              },
            };
            // Update currentAction in combatStore
            useCombatStore.setState({ currentAction: 'design' });
          } else if (!state.designProgress2) {
            updates = {
              designProgress2: {
                designId: CraftingUtils.generateDesignId(),
                progress: 0,
                required: CraftingDesign.calculateDesignTime(effects),
                name,
                equipmentType: equipmentTypeId,
                effects,
              },
            };
            useCombatStore.setState({ currentAction: 'design' });
          } else {
            return false;
          }

          set(updates);
          return true;
        },

        cancelDesign: (slot?: 1 | 2) => {
          const state = get();
          if (slot === 2) {
            if (state.designProgress2) {
              set({ designProgress2: null });
            }
          } else if (slot === 1) {
            if (state.designProgress) {
              set({ designProgress: null });
              useCombatStore.setState({ currentAction: 'meditate' });
            }
          } else if (state.designProgress) {
            set({ designProgress: null });
            useCombatStore.setState({ currentAction: 'meditate' });
          } else if (state.designProgress2) {
            set({ designProgress2: null });
          }
        },

        deleteDesign: (designId) => {
          set((state) => ({
            enchantmentDesigns: state.enchantmentDesigns.filter(d => d.id !== designId),
          }));
        },

        // Enchantment design save
        saveDesign: (design) => {
          const state = get();
          if (state.designProgress2 && state.designProgress2.designId === design.id) {
            set((s) => ({
              enchantmentDesigns: [...s.enchantmentDesigns, design],
              designProgress2: null,
            }));
          } else {
            set((s) => ({
              enchantmentDesigns: [...s.enchantmentDesigns, design],
              designProgress: null,
            }));
            useCombatStore.setState({ currentAction: 'meditate' });
          }
        },

        // Enchantment application actions
        startApplying: (equipmentInstanceId, designId) => {
          const currentAction = useCombatStore.getState().currentAction;
          const result = ApplicationActions.startApplying(
            equipmentInstanceId,
            designId,
            get,
            set as unknown as (partial: Partial<CraftingState>) => void,
            currentAction
          );
          if (result) {
            useCombatStore.setState({ currentAction: 'enchant' });
          }
          return result;
        },

        pauseApplication: () => {
          ApplicationActions.pauseApplication(get, set as unknown as (partial: Partial<CraftingState>) => void);
        },

        resumeApplication: () => {
          ApplicationActions.resumeApplication(get, set as unknown as (partial: Partial<CraftingState>) => void);
        },

        cancelApplication: () => {
          ApplicationActions.cancelApplication(get, set as unknown as (partial: Partial<CraftingState>) => void);
          useCombatStore.setState({ currentAction: 'meditate' });
        },

        // Preparation actions
        startPreparing: (equipmentInstanceId) => {
          const rawMana = useManaStore.getState().rawMana;
          const result = PreparationActions.startPreparing(
            equipmentInstanceId,
            rawMana,
            get,
            set
          );
          if (result) {
            useCombatStore.setState({ currentAction: 'prepare' });
            set({ lastError: null });
          } else {
            const state = get();
            const instance = state.equipmentInstances[equipmentInstanceId];
            let message = 'Cannot start preparation';
            if (!instance) {
              message = `Equipment instance not found: ${equipmentInstanceId}`;
            } else if (instance.tags?.includes('Ready for Enchantment')) {
              message = 'Equipment is already prepared';
            } else {
              message = 'Insufficient mana for preparation';
            }
            set({ lastError: { code: ErrorCode.INVALID_INPUT, message, timestamp: Date.now() } });
          }
          return result;
        },

        cancelPreparation: () => {
          PreparationActions.cancelPreparation(get, set);
          useCombatStore.setState({ currentAction: 'meditate' });
        },

        startCraftingEquipment: (blueprintId: string) => startCraftingEquipment(blueprintId, get, set),

        cancelEquipmentCrafting: () => cancelEquipmentCrafting(get, set),

        // Fabricator crafting — uses elemental mana instead of raw mana
        startFabricatorCrafting: (recipeId: string) => startFabricatorCrafting(recipeId, get, set),

        // Material crafting — instant crafting of materials
        craftMaterial: (recipeId: string) => {
          const state = get();
          const result = craftMaterialAction(recipeId, state.lootInventory.materials);
          if (!result.success) return false;
          if (result.newMaterials) {
            set((s) => ({ lootInventory: { ...s.lootInventory, materials: result.newMaterials! } }));
          }
          return true;
        },

        // Enchantment selection actions
        setSelectedEquipmentType: (type) => {
          set((s) => ({ enchantmentSelection: { ...s.enchantmentSelection, selectedEquipmentType: type }}));
        },
        setSelectedEffects: (effects) => {
          set((s) => ({ enchantmentSelection: { ...s.enchantmentSelection, selectedEffects: effects } }));
        },
        setDesignName: (name) => {
          set((s) => ({ enchantmentSelection: { ...s.enchantmentSelection, designName: name } }));
        },
        setSelectedDesign: (id) => {
          set((s) => ({ enchantmentSelection: { ...s.enchantmentSelection, selectedDesign: id } }));
        },
        setSelectedEquipmentInstance: (id) => {
          set((s) => ({ enchantmentSelection: { ...s.enchantmentSelection, selectedEquipmentInstance: id } }));
        },
        resetEnchantmentSelection: () => {
          set((s) => ({
            enchantmentSelection: {
              selectedEquipmentType: null,
              selectedEffects: [],
              designName: '',
              selectedDesign: null,
              selectedEquipmentInstance: null,
            },
          }));
        },

        // Loot inventory actions
        deleteMaterial: (materialId: string, amount: number) => {
          set((state) => {
            const newMaterials = { ...state.lootInventory.materials };
            const currentAmount = newMaterials[materialId] || 0;
            const newAmount = Math.max(0, currentAmount - amount);

            if (newAmount <= 0) {
              delete newMaterials[materialId];
            } else {
              newMaterials[materialId] = newAmount;
            }

            return {
              lootInventory: {
                ...state.lootInventory,
                materials: newMaterials,
              },
            };
          });
        },

        deleteEquipmentInstance: (instanceId: string) => {
          set((state) => {
            let newEquipped = { ...state.equippedInstances };
            for (const [slot, id] of Object.entries(newEquipped)) {
              if (id === instanceId) {
                newEquipped[slot as EquipmentSlot] = null;
              }
            }

            const newInstances = { ...state.equipmentInstances };
            delete newInstances[instanceId];

            return {
              equippedInstances: newEquipped,
              equipmentInstances: newInstances,
            };
          });
        },

        equipItem: (instanceId: string, slot: EquipmentSlot) => {
          return equipItemAction(instanceId, slot, get, set);
        },

        unequipItem: (slot: EquipmentSlot) => {
          unequipItemAction(slot, set);
        },

        clearLastError: () => set({ lastError: null }),

        setActiveCraftingSubTab: (tab) => set({ activeCraftingSubTab: tab }),

        unlockEffects: (effectIds: string[]) => {
          set((state) => {
            const existing = new Set(state.unlockedEffects);
            let changed = false;
            for (const id of effectIds) {
              if (!existing.has(id)) {
                existing.add(id);
                changed = true;
              }
            }
            if (!changed) return state;
            return { unlockedEffects: Array.from(existing) };
          });
        },

        unlockRecipes: (recipeIds: string[]) => {
          set((state) => {
            const existing = new Set(state.unlockedRecipes);
            let changed = false;
            for (const id of recipeIds) {
              if (!existing.has(id)) {
                existing.add(id);
                changed = true;
              }
            }
            if (!changed) return state;
            return { unlockedRecipes: Array.from(existing) };
          });
        },

        processEquipmentCraftingTick: (): { completed: boolean; logMessage?: string } => {
          const state = get();
          return processEquipmentCraftingTick(state, set as unknown as (partial: Partial<CraftingState>) => void);
        },

        resetCrafting: () => {
          set(createDefaultCraftingState());
        },
      };
    },
    {
      storage: createSafeStorage(),
      name: 'mana-loop-crafting',
      version: 1,
      partialize: (state) => ({
        designProgress: state.designProgress,
        designProgress2: state.designProgress2,
        preparationProgress: state.preparationProgress,
        applicationProgress: state.applicationProgress,
        equipmentCraftingProgress: state.equipmentCraftingProgress,
        enchantmentDesigns: state.enchantmentDesigns,
        unlockedEffects: state.unlockedEffects,
        unlockedRecipes: state.unlockedRecipes,
        equipmentInstances: state.equipmentInstances,
        equippedInstances: state.equippedInstances,
        lootInventory: state.lootInventory,
        enchantmentSelection: state.enchantmentSelection,
        lastError: state.lastError,
        activeCraftingSubTab: state.activeCraftingSubTab,
      }),
    }
  )
);
