import { create } from 'zustand' import { pinnedFlowsApi } from '@/api/pinnedFlows' import type { PinnedFlow } from '@/api/pinnedFlows' import { toast } from '@/lib/toast' interface PinnedFlowsState { items: PinnedFlow[] isLoaded: boolean isLoading: boolean isMutatingByTreeId: Record error: string | null load: (force?: boolean) => Promise pin: (treeId: string) => Promise unpin: (treeId: string) => Promise toggle: (treeId: string) => void isPinned: (treeId: string) => boolean } export const usePinnedFlowsStore = create()((set, get) => ({ items: [], isLoaded: false, isLoading: false, isMutatingByTreeId: {}, error: null, load: async (force = false) => { const state = get() if (state.isLoaded && !force) return if (state.isLoading) return set({ isLoading: true, error: null }) try { const data = await pinnedFlowsApi.list() set({ items: data.items, isLoaded: true, isLoading: false }) } catch { set({ error: 'Failed to load pinned flows', isLoading: false }) } }, pin: async (treeId: string) => { const state = get() if (state.isMutatingByTreeId[treeId]) return set({ isMutatingByTreeId: { ...state.isMutatingByTreeId, [treeId]: true } }) try { await pinnedFlowsApi.pin(treeId) const data = await pinnedFlowsApi.list() set((s) => ({ items: data.items, isMutatingByTreeId: { ...s.isMutatingByTreeId, [treeId]: false }, })) } catch (err: unknown) { const status = (err as { response?: { status?: number } })?.response?.status if (status === 409) { toast.error('Maximum of 15 favorites reached. Unpin a flow to add a new one.') } else { toast.error('Failed to pin flow') } set((s) => ({ isMutatingByTreeId: { ...s.isMutatingByTreeId, [treeId]: false }, })) } }, unpin: async (treeId: string) => { const state = get() if (state.isMutatingByTreeId[treeId]) return const prevItems = state.items set({ items: state.items.filter((f) => f.tree_id !== treeId), isMutatingByTreeId: { ...state.isMutatingByTreeId, [treeId]: true }, }) try { await pinnedFlowsApi.unpin(treeId) set((s) => ({ isMutatingByTreeId: { ...s.isMutatingByTreeId, [treeId]: false }, })) } catch { toast.error('Failed to unpin flow') set((s) => ({ items: prevItems, isMutatingByTreeId: { ...s.isMutatingByTreeId, [treeId]: false }, })) } }, toggle: (treeId: string) => { const state = get() if (state.isPinned(treeId)) { state.unpin(treeId) } else { state.pin(treeId) } }, isPinned: (treeId: string) => { return get().items.some((f) => f.tree_id === treeId) }, }))