import { createStore } from 'zustand/vanilla'; import { useSyncExternalStore } from 'react'; export interface PricingItem { id: string; label: string; price: number; modelPath?: string; } export interface PricingState { items: PricingItem[]; isHydrated: boolean; } export interface PricingActions { updatePrice: (itemId: string, newPrice: number) => void; updateItem: (itemId: string, updates: Partial>) => void; addItem: (item: PricingItem) => void; removeItem: (itemId: string) => void; resetPrices: () => void; hydrate: () => void; } export type PricingStore = PricingState & PricingActions; const DEFAULT_ITEMS: PricingItem[] = [ { id: 'base', label: 'G1 Robot Base', price: 250000 }, { id: 'emarati-kandura', label: 'Emarati Kandura', price: 15000 }, { id: 'industrial-vest', label: 'Industrial Vest', price: 8500 }, { id: 'business-suit', label: 'Business Suit', price: 12000 }, { id: 'custom-color', label: 'Custom Color', price: 3500 }, ]; const STORAGE_KEY = 'lootah-pricing'; function loadFromStorage(): PricingItem[] | null { if (typeof window === 'undefined') return null; try { const raw = localStorage.getItem(STORAGE_KEY); if (!raw) return null; const parsed = JSON.parse(raw); if (!Array.isArray(parsed)) return null; return parsed; } catch { return null; } } function saveToStorage(items: PricingItem[]) { if (typeof window === 'undefined') return; try { localStorage.setItem(STORAGE_KEY, JSON.stringify(items)); } catch { // Storage full or unavailable } } export const pricingStore = createStore((set, get) => ({ items: DEFAULT_ITEMS, isHydrated: false, updatePrice: (itemId: string, newPrice: number) => { set((state) => { const updated = state.items.map((item) => item.id === itemId ? { ...item, price: newPrice } : item ); saveToStorage(updated); return { items: updated }; }); }, updateItem: (itemId: string, updates: Partial>) => { set((state) => { const updated = state.items.map((item) => item.id === itemId ? { ...item, ...updates } : item ); saveToStorage(updated); return { items: updated }; }); }, resetPrices: () => { saveToStorage(DEFAULT_ITEMS); set({ items: [...DEFAULT_ITEMS] }); }, addItem: (item: PricingItem) => { set((state) => { if (state.items.some((i) => i.id === item.id)) return state; const updated = [...state.items, item]; saveToStorage(updated); return { items: updated }; }); }, removeItem: (itemId: string) => { // Prevent removing the base robot price if (itemId === 'base') return; set((state) => { const updated = state.items.filter((i) => i.id !== itemId); saveToStorage(updated); return { items: updated }; }); }, hydrate: () => { const stored = loadFromStorage(); if (stored && stored.length > 0) { // Use stored items directly (preserves custom labels, prices, added items). // Re-add any default items that were never stored (fresh install gap). const storedIds = new Set(stored.map((s) => s.id)); const missing = DEFAULT_ITEMS.filter((d) => !storedIds.has(d.id)); set({ items: [...stored, ...missing], isHydrated: true }); } else { set({ isHydrated: true }); } }, })); export const usePricingStore = (selector: (state: PricingStore) => T): T => { return useSyncExternalStore( pricingStore.subscribe, () => selector(pricingStore.getState()), () => selector(pricingStore.getState()) ); }; export const getPrice = (itemId: string): number => { const item = pricingStore.getState().items.find((i) => i.id === itemId); return item?.price ?? 0; };