// ─── Discipline Store Slice ────────────────────────────────────────────────────
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import type { DisciplineState } from '../types/disciplines';
import {
  calculateManaDrain,
  calculateStatBonus,
  canProceedDiscipline,
} from '../utils/discipline-math';
import { baseDisciplines } from '../data/disciplines/base';
import { enchanterDisciplines } from '../data/disciplines/enchanter';
import { fabricatorDisciplines } from '../data/disciplines/fabricator';
import { invokerDisciplines } from '../data/disciplines/invoker';
import { MAX_CONCURRENT_DISCIPLINES } from '../types/disciplines';

const ALL_DISCIPLINES = [
  ...baseDisciplines,
  ...enchanterDisciplines,
  ...fabricatorDisciplines,
  ...invokerDisciplines,
];
const DISCIPLINE_MAP = Object.fromEntries(ALL_DISCIPLINES.map((d) => [d.id, d]));

export interface DisciplineStoreState {
  disciplines: Record<string, DisciplineState>;
  activeIds: string[];
  concurrentLimit: number;
  totalXP: number;
}

export interface DisciplineStoreActions {
  activate: (id: string, gameState?: { elements?: Record<string, { unlocked?: boolean }> }) => void;
  deactivate: (id: string) => void;
  processTick: (mana: { rawMana: number; elements: Record<string, { current: number }> }) => {
    rawMana: number;
    elements: Record<string, { current: number }>;
  };
}

export type DisciplineStore = DisciplineStoreState & DisciplineStoreActions;

export const useDisciplineStore = create<DisciplineStore>()(
  persist(
    (set, get) => ({
      disciplines: {},
      activeIds: [],
      concurrentLimit: MAX_CONCURRENT_DISCIPLINES,
      totalXP: 0,

      activate(id, gameState) {
        set((s) => {
          const def = DISCIPLINE_MAP[id];
          if (!def) return s;
          if (s.activeIds.includes(id)) return s;

          const nonPaused = s.activeIds.filter((aid) => {
            const d = s.disciplines[aid];
            return d && !d.paused;
          }).length;
          if (nonPaused >= s.concurrentLimit) return s;
          const discState = s.disciplines[id];
          if (!canProceedDiscipline(def, discState, gameState)) return s;

          const existing = s.disciplines[id] || { id, xp: 0, paused: false };
          return {
            disciplines: { ...s.disciplines, [id]: { ...existing, paused: false } },
            activeIds: [...s.activeIds, id],
          };
        });
      },

      deactivate(id) {
        set((s) => ({
          activeIds: s.activeIds.filter((aid) => aid !== id),
        }));
      },

      processTick(mana) {
        const s = get();
        let rawMana = mana.rawMana;
        const elements = { ...mana.elements };
        let newXP = s.totalXP;
        const newDisciplines = { ...s.disciplines };

        for (const id of s.activeIds) {
          const disc = newDisciplines[id];
          if (!disc) continue;
          if (disc.paused) continue;

          const def = DISCIPLINE_MAP[id];
          if (!def) continue;

          const drain = calculateManaDrain(def.drainBase, disc.xp, def.difficultyFactor);
          const element = elements[def.manaType];
          const available = def.manaType === 'raw' ? rawMana : element?.current;

          if (!available || available < drain) {
            newDisciplines[id] = { ...disc, paused: true };
            continue;
          }

          if (def.manaType === 'raw') {
            rawMana -= drain;
          } else if (elements[def.manaType]) {
            elements[def.manaType] = {
              ...elements[def.manaType],
              current: elements[def.manaType].current - drain,
            };
          }

          newDisciplines[id] = { ...disc, xp: disc.xp + 1 };
          newXP += 1;
        }

        const newLimit = Math.min(
          MAX_CONCURRENT_DISCIPLINES + Math.floor(newXP / 500),
          MAX_CONCURRENT_DISCIPLINES + 3
        );

        set({
          disciplines: newDisciplines,
          totalXP: newXP,
          concurrentLimit: Math.max(s.concurrentLimit, newLimit),
        });

        return { rawMana, elements };
      },
    }),
    { name: 'mana-loop-discipline-store' }
  )
);