/// Local Data Source: Cart Storage /// /// Handles local storage of cart items using Hive for offline access. /// Supports offline-first functionality and cart persistence. library; import 'package:hive_ce/hive.dart'; import 'package:worker/core/constants/storage_constants.dart'; import 'package:worker/core/database/hive_service.dart'; import 'package:worker/core/errors/exceptions.dart'; import 'package:worker/features/cart/data/models/cart_item_model.dart'; /// Cart Local Data Source Interface abstract class CartLocalDataSource { /// Save cart items to local storage /// /// [items] - List of cart items to save Future saveCartItems(List items); /// Get cart items from local storage /// /// Returns list of cart items Future> getCartItems(); /// Add item to local cart /// /// [item] - Cart item to add Future addCartItem(CartItemModel item); /// Update item in local cart /// /// [item] - Cart item to update Future updateCartItem(CartItemModel item); /// Remove items from local cart /// /// [itemIds] - Product IDs to remove Future removeCartItems(List itemIds); /// Clear all items from local cart Future clearCart(); /// Get cart item count /// /// Returns total number of items Future getCartItemCount(); /// Get cart total /// /// Returns total amount Future getCartTotal(); } /// Cart Local Data Source Implementation class CartLocalDataSourceImpl implements CartLocalDataSource { CartLocalDataSourceImpl(this._hiveService); final HiveService _hiveService; /// Get cart box as Box (following best practices) Box get _cartBox => _hiveService.getBox(HiveBoxNames.cartBox); @override Future saveCartItems(List items) async { try { // Clear existing items await _cartBox.clear(); // Save new items with productId as key for (final item in items) { await _cartBox.put(item.productId, item); } } catch (e) { throw StorageException('Failed to save cart items: $e'); } } @override Future> getCartItems() async { try { // Get all cart items from box using .whereType() for type safety final items = _cartBox.values .whereType() .toList(); return items; } catch (e) { throw StorageException('Failed to get cart items: $e'); } } @override Future addCartItem(CartItemModel item) async { try { // Check if item already exists final existingItem = _cartBox.get(item.productId); if (existingItem != null && existingItem is CartItemModel) { // Update quantity if item exists final updatedItem = existingItem.copyWith( quantity: existingItem.quantity + item.quantity, subtotal: (existingItem.quantity + item.quantity) * existingItem.unitPrice, ); await _cartBox.put(item.productId, updatedItem); } else { // Add new item await _cartBox.put(item.productId, item); } } catch (e) { throw StorageException('Failed to add cart item: $e'); } } @override Future updateCartItem(CartItemModel item) async { try { // Update or add item await _cartBox.put(item.productId, item); } catch (e) { throw StorageException('Failed to update cart item: $e'); } } @override Future removeCartItems(List itemIds) async { try { // Remove items by productId keys for (final itemId in itemIds) { await _cartBox.delete(itemId); } } catch (e) { throw StorageException('Failed to remove cart items: $e'); } } @override Future clearCart() async { try { await _cartBox.clear(); } catch (e) { throw StorageException('Failed to clear cart: $e'); } } @override Future getCartItemCount() async { try { final items = await getCartItems(); // Sum up all quantities final totalQuantity = items.fold( 0.0, (sum, item) => sum + item.quantity, ); return totalQuantity.toInt(); } catch (e) { throw StorageException('Failed to get cart item count: $e'); } } @override Future getCartTotal() async { try { final items = await getCartItems(); // Sum up all subtotals final total = items.fold( 0.0, (sum, item) => sum + item.subtotal, ); return total; } catch (e) { throw StorageException('Failed to get cart total: $e'); } } }