"use client"; import { useState, useEffect, useCallback, useRef } from 'react'; import { useToast } from '@/components/ui/use-toast'; import type { CartItemCreate } from '@/lib/cart'; import type { Cart } from '@/lib/cart-store'; import cartStore from '@/lib/cart-store'; import { apiStatus } from '@/lib/api'; // Глобальная переменная для отслеживания последней синхронизации let lastSyncTimestamp = 0; const SYNC_THROTTLE_MS = 5000; // Минимальное время между синхронизациями (5 секунд) export function useCart() { const [cart, setCart] = useState(cartStore.getState()); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const { toast } = useToast(); const syncInProgressRef = useRef(false); // Подписка на изменения корзины useEffect(() => { const unsubscribe = cartStore.subscribe(() => { setCart(cartStore.getState()); }); return () => unsubscribe(); }, []); // Проверка аутентификации и синхронизация корзины useEffect(() => { if (apiStatus.isAuthenticated) { // Проверяем, не происходит ли уже синхронизация и не слишком ли рано для новой const now = Date.now(); if (!syncInProgressRef.current && now - lastSyncTimestamp > SYNC_THROTTLE_MS) { synchronizeCart(); } } }, [apiStatus.isAuthenticated]); // Синхронизация локальной корзины с сервером с дроттлингом const synchronizeCart = useCallback(async () => { try { // Если синхронизация уже идет, не запускаем новую if (syncInProgressRef.current) return; syncInProgressRef.current = true; setLoading(true); // Фиксируем время последней синхронизации lastSyncTimestamp = Date.now(); await cartStore.syncWithServer(); } catch (err) { setError('Не удалось синхронизировать корзину'); toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось синхронизировать корзину', }); } finally { setLoading(false); syncInProgressRef.current = false; } }, [toast]); // Добавление товара в корзину const addToCart = useCallback(async (item: CartItemCreate) => { try { setLoading(true); setError(null); const result = await cartStore.addToCart(item); if (result) { toast({ title: 'Товар добавлен', description: 'Товар успешно добавлен в корзину', }); return true; } else { toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось добавить товар в корзину', }); return false; } } catch (err) { setError('Не удалось добавить товар в корзину'); toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось добавить товар в корзину', }); return false; } finally { setLoading(false); } }, [toast]); // Обновление количества товара в корзине const updateCartItem = useCallback(async (id: number, quantity: number) => { try { setLoading(true); setError(null); const result = await cartStore.updateCartItem(id, quantity); if (!result) { toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось обновить товар в корзине', }); } return result; } catch (err) { setError('Не удалось обновить товар в корзине'); toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось обновить товар в корзине', }); return false; } finally { setLoading(false); } }, [toast]); // Удаление товара из корзины const removeFromCart = useCallback(async (id: number) => { try { setLoading(true); setError(null); const result = await cartStore.removeFromCart(id); if (result) { toast({ title: 'Товар удален', description: 'Товар успешно удален из корзины', }); return true; } else { toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось удалить товар из корзины', }); return false; } } catch (err) { setError('Не удалось удалить товар из корзины'); toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось удалить товар из корзины', }); return false; } finally { setLoading(false); } }, [toast]); // Очистка корзины const clearCart = useCallback(async () => { try { setLoading(true); setError(null); const result = await cartStore.clearCart(); if (result) { toast({ title: 'Корзина очищена', description: 'Корзина успешно очищена', }); return true; } else { toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось очистить корзину', }); return false; } } catch (err) { setError('Не удалось очистить корзину'); toast({ variant: 'destructive', title: 'Ошибка', description: 'Не удалось очистить корзину', }); return false; } finally { setLoading(false); } }, [toast]); return { cart, loading, error, addToCart, updateCartItem, removeFromCart, clearCart, synchronizeCart, itemsCount: cartStore.getItemsCount(), itemCount: cartStore.getItemsCount(), isAuthenticated: apiStatus.isAuthenticated, items_count: cart.items_count, total_amount: cart.total_amount }; }