import { create } from "zustand";
import { persist, createJSONStorage } from "zustand/middleware";
import type {
  InventoryItem,
  ActiveEffect,
  UserInventory,
} from "../types/quest";

// ─── Store interface ──────────────────────────────────────────────────────────

interface InventoryStore {
  // Raw inventory from API
  items: InventoryItem[];
  activeEffects: ActiveEffect[];

  // Loading / error
  loading: boolean;
  activatingId: string | null; // item id currently being activated
  error: string | null;
  lastActivatedId: string | null; // shows success state briefly

  // Actions
  syncFromAPI: (inv: UserInventory) => void;
  activateItemOptimistic: (itemId: string) => void;
  activateItemSuccess: (inv: UserInventory, itemId: string) => void;
  activateItemError: (itemId: string, error: string) => void;
  clearLastActivated: () => void;
  setLoading: (v: boolean) => void;
}

export const useInventoryStore = create<InventoryStore>()(
  persist(
    (set) => ({
      items: [],
      activeEffects: [],
      loading: false,
      activatingId: null,
      error: null,
      lastActivatedId: null,

      syncFromAPI: (inv) =>
        set({ items: inv.items, activeEffects: inv.active_effects }),

      // Optimistic — mark as "activating" immediately for instant UI feedback
      activateItemOptimistic: (itemId) =>
        set({ activatingId: itemId, error: null }),

      // On API success — replace inventory with fresh server state
      activateItemSuccess: (inv, itemId) =>
        set({
          items: inv.items,
          activeEffects: inv.active_effects,
          activatingId: null,
          lastActivatedId: itemId,
        }),

      activateItemError: (itemId, error) => set({ activatingId: null, error }),

      clearLastActivated: () => set({ lastActivatedId: null }),

      setLoading: (v) => set({ loading: v }),
    }),
    {
      name: "inventory-store",
      storage: createJSONStorage(() => localStorage),
      // Persist items + active effects so the app can show active item banners
      // without waiting for a network request on every mount
      partialize: (state) => ({
        items: state.items,
        activeEffects: state.activeEffects,
      }),
    },
  ),
);

// ─── Selector helpers (call these in components, not inside the store) ─────────

/** Returns true if any active effect has the given effect_type */
export function hasActiveEffect(
  activeEffects: ActiveEffect[],
  effectType: string,
): boolean {
  const now = Date.now();
  return activeEffects.some(
    (e) =>
      e.item.effect_type === effectType &&
      new Date(e.expires_at).getTime() > now,
  );
}

/** Returns the active effect for a given effect_type, or null */
export function getActiveEffect(
  activeEffects: ActiveEffect[],
  effectType: string,
): ActiveEffect | null {
  const now = Date.now();
  return (
    activeEffects.find(
      (e) =>
        e.item.effect_type === effectType &&
        new Date(e.expires_at).getTime() > now,
    ) ?? null
  );
}

/** Returns all non-expired active effects */
export function getLiveEffects(activeEffects: ActiveEffect[]): ActiveEffect[] {
  const now = Date.now();
  return activeEffects.filter((e) => new Date(e.expires_at).getTime() > now);
}

/** Formats time remaining as "2h 14m" or "43m" */
export function formatTimeLeft(expiresAt: string): string {
  const msLeft = new Date(expiresAt).getTime() - Date.now();
  if (msLeft <= 0) return "Expired";
  const totalMin = Math.floor(msLeft / 60_000);
  const h = Math.floor(totalMin / 60);
  const m = totalMin % 60;
  return h > 0 ? `${h}h ${m}m` : `${m}m`;
}
