import { create } from 'zustand'; import type { Rack, Module } from '../types'; import { apiClient } from '../api/client'; interface RackState { racks: Rack[]; loading: boolean; selectedModuleId: string | null; // Fetch fetchRacks: () => Promise; // Rack CRUD addRack: (name: string, totalU?: number, location?: string) => Promise; updateRack: (id: string, data: Partial<{ name: string; totalU: number; location: string; displayOrder: number }>) => Promise; deleteRack: (id: string) => Promise; // Module CRUD (optimistic update helpers) addModule: (rackId: string, data: Parameters[1]) => Promise; moveModule: (moduleId: string, targetRackId: string, targetUPosition: number) => Promise; updateModuleLocal: (moduleId: string, data: Partial) => void; removeModuleLocal: (moduleId: string) => void; // Selection setSelectedModule: (id: string | null) => void; // Cabling cablingFromPortId: string | null; setCablingFromPortId: (id: string | null) => void; createConnection: (fromPortId: string, toPortId: string) => Promise; updateConnection: (id: string, data: Partial<{ color: string; label: string; edgeType: string }>) => Promise; deleteConnection: (id: string) => Promise; // Port Config Global Modal activeConfigPortId: string | null; setActiveConfigPortId: (id: string | null) => void; // Connection Config Global Modal activeConfigConnectionId: string | null; setActiveConfigConnectionId: (id: string | null) => void; } export const useRackStore = create((set, get) => ({ racks: [], loading: false, selectedModuleId: null, fetchRacks: async () => { set({ loading: true }); try { const racks = await apiClient.racks.list(); set({ racks, loading: false }); } catch { set({ loading: false }); throw new Error('Failed to load racks'); } }, addRack: async (name, totalU = 42, location) => { const rack = await apiClient.racks.create({ name, totalU, location }); set((s) => ({ racks: [...s.racks, rack].sort((a, b) => a.displayOrder - b.displayOrder) })); return rack; }, updateRack: async (id, data) => { const updated = await apiClient.racks.update(id, data); set((s) => ({ racks: s.racks .map((r) => (r.id === id ? updated : r)) .sort((a, b) => a.displayOrder - b.displayOrder), })); }, deleteRack: async (id) => { await apiClient.racks.delete(id); set((s) => ({ racks: s.racks.filter((r) => r.id !== id) })); }, addModule: async (rackId, data) => { const module = await apiClient.racks.addModule(rackId, data); set((s) => ({ racks: s.racks.map((r) => r.id === rackId ? { ...r, modules: [...r.modules, module].sort((a, b) => a.uPosition - b.uPosition) } : r ), })); return module; }, moveModule: async (moduleId, targetRackId, targetUPosition) => { const updated = await apiClient.modules.move(moduleId, targetRackId, targetUPosition); set((s) => { // Remove from source rack, insert into target rack const racks = s.racks.map((r) => ({ ...r, modules: r.modules.filter((m) => m.id !== moduleId), })); return { racks: racks.map((r) => r.id === targetRackId ? { ...r, modules: [...r.modules, updated].sort((a, b) => a.uPosition - b.uPosition) } : r ), }; }); }, updateModuleLocal: (moduleId, data) => { set((s) => ({ racks: s.racks.map((r) => ({ ...r, modules: r.modules.map((m) => (m.id === moduleId ? { ...m, ...data } : m)), })), })); }, removeModuleLocal: (moduleId) => { set((s) => ({ racks: s.racks.map((r) => ({ ...r, modules: r.modules.filter((m) => m.id !== moduleId), })), })); }, setSelectedModule: (id) => set({ selectedModuleId: id }), // Cabling cablingFromPortId: null, setCablingFromPortId: (id) => set({ cablingFromPortId: id }), createConnection: async (fromPortId, toPortId) => { await apiClient.connections.create({ fromPortId, toPortId }); // Refresh racks to get updated nested connections const racks = await apiClient.racks.list(); set({ racks }); }, deleteConnection: async (id) => { await apiClient.connections.delete(id); const racks = await apiClient.racks.list(); set({ racks }); }, updateConnection: async (id, data) => { await apiClient.connections.update(id, data); const racks = await apiClient.racks.list(); set({ racks }); }, activeConfigPortId: null, setActiveConfigPortId: (id) => set({ activeConfigPortId: id }), activeConfigConnectionId: null, setActiveConfigConnectionId: (id) => set({ activeConfigConnectionId: id }), }));