import {Dispatch, SetStateAction, useEffect, useRef} from 'react'; import { getCartUpdates } from '../api/promoApi'; import { normalizeProductImage } from '../utils/product'; import type { Product } from '../types/cart'; interface UseCartPollingParams { enabled: boolean; onProductsChange: Dispatch>; onComplete: () => void; onLoadingChange: (isLoading: boolean) => void; setDisplayText: Dispatch>; } export function useCartPolling({ enabled, onProductsChange, onComplete, onLoadingChange, setDisplayText, }: UseCartPollingParams) { const timeoutRef = useRef(null); useEffect(() => { if (!enabled) return; let cancelled = false; async function tick() { try { onLoadingChange(true); const update = await getCartUpdates(); if (cancelled) return; if (update.status === 'complete') { onLoadingChange(false); onComplete(); return; } if (update.status === 'waiting') { setDisplayText('Брок бегает по супермаркету...') return; } if (update.status === 'clear') { const nextProducts = update.payload?.chunk?.map(product => normalizeProductImage(product)) ?? []; onProductsChange(nextProducts); } if (update.status === 'data') { const chunk = update.payload?.chunk?.map(product => normalizeProductImage(product)) ?? []; onProductsChange(current => { const next = [...current]; chunk.forEach(product => { const index = next.findIndex(item => item.name === product.name); if (index === -1) { next.push(product); } else { next[index] = { ...next[index], n: next[index].n + product.n, }; } }); return next; }); setDisplayText('Брок закинул пару товаров...') } timeoutRef.current = window.setTimeout(tick, 3000); } catch (error) { setDisplayText('Ищем Брока...') timeoutRef.current = window.setTimeout(tick, 3000); } } tick(); return () => { cancelled = true; if (timeoutRef.current) { window.clearTimeout(timeoutRef.current); } }; }, [enabled, onComplete, onLoadingChange, onProductsChange]); }