// useGameStore.ts — Zustand store, source unique de l'état game
// Lazy calculation pattern : gains passifs calculés au read depuis lastTick

import { create } from "zustand";
import {
  GameState,
  DEFAULT_STATE,
  applyIdleGains,
  applyClick,
  buyGenerator,
  buyEvolutionNode,
  applyPrestige,
  canPrestige as canPrestigeCheck,
  totalProductionPerSecond,
  generatorCost as genCost,
} from "../core/economy";

const SAVE_KEY = "clickerz_state";

function loadState(): GameState {
  try {
    const raw = localStorage.getItem(SAVE_KEY);
    if (!raw) return { ...DEFAULT_STATE, lastTick: Date.now() };
    const saved = JSON.parse(raw) as GameState;
    return applyIdleGains(saved, Date.now());
  } catch {
    return { ...DEFAULT_STATE, lastTick: Date.now() };
  }
}

function saveState(state: GameState): void {
  localStorage.setItem(SAVE_KEY, JSON.stringify(state));
}

interface GameStore {
  // State
  state: GameState;
  playSeconds: number;

  // Derived (recalculated on tick)
  canPrestige: boolean;
  productionPerSecond: number;

  // Actions
  tick: () => void;
  click: () => void;
  buy: (genId: string) => void;
  buyNode: (nodeId: string) => void;
  prestige: () => void;
  reset: () => void;
  loadFromServer: (serverState: GameState) => void;
  generatorCost: typeof genCost;
}

export const useGameStore = create<GameStore>((set, get) => ({
  state: loadState(),
  playSeconds: 0,
  canPrestige: canPrestigeCheck(loadState()),
  productionPerSecond: totalProductionPerSecond(loadState()),

  tick: () => {
    set((s) => {
      const updated = applyIdleGains(s.state, Date.now());
      saveState(updated);
      return {
        state: updated,
        playSeconds: s.playSeconds + 1,
        canPrestige: canPrestigeCheck(updated),
        productionPerSecond: totalProductionPerSecond(updated),
      };
    });
  },

  click: () => {
    set((s) => {
      const updated = applyClick(applyIdleGains(s.state, Date.now()));
      saveState(updated);
      return {
        state: updated,
        canPrestige: canPrestigeCheck(updated),
        productionPerSecond: totalProductionPerSecond(updated),
      };
    });
  },

  buy: (genId: string) => {
    set((s) => {
      const withIdle = applyIdleGains(s.state, Date.now());
      const updated = buyGenerator(withIdle, genId);
      if (!updated) return s;
      saveState(updated);
      return {
        state: updated,
        productionPerSecond: totalProductionPerSecond(updated),
      };
    });
  },

  buyNode: (nodeId: string) => {
    set((s) => {
      const updated = buyEvolutionNode(s.state, nodeId);
      if (!updated) return s;
      saveState(updated);
      return {
        state: updated,
        productionPerSecond: totalProductionPerSecond(updated),
      };
    });
  },

  prestige: () => {
    set((s) => {
      if (!canPrestigeCheck(s.state)) return s;
      const updated = applyPrestige(s.state);
      saveState(updated);
      return {
        state: updated,
        canPrestige: canPrestigeCheck(updated),
        productionPerSecond: totalProductionPerSecond(updated),
      };
    });
  },

  reset: () => {
    const fresh = { ...DEFAULT_STATE, lastTick: Date.now() };
    saveState(fresh);
    set({
      state: fresh,
      playSeconds: 0,
      canPrestige: false,
      productionPerSecond: 0,
    });
  },

  loadFromServer: (serverState: GameState) => {
    const hydrated = applyIdleGains(serverState, Date.now());
    saveState(hydrated);
    set({
      state: hydrated,
      canPrestige: canPrestigeCheck(hydrated),
      productionPerSecond: totalProductionPerSecond(hydrated),
    });
  },

  generatorCost: genCost,
}));
