import 'package:hive_ce/hive.dart'; import 'package:retail/core/database/hive_database.dart'; import 'package:retail/features/products/data/models/product_model.dart'; import 'package:retail/features/products/data/datasources/product_local_datasource.dart'; import 'package:retail/features/products/domain/entities/product.dart'; /// Hive implementation of ProductLocalDataSource class ProductLocalDataSourceHive implements ProductLocalDataSource { final HiveDatabase _database; ProductLocalDataSourceHive(this._database); Box get _box => _database.productsBox; /// Convert ProductModel to Product entity Product _toEntity(ProductModel model) { return Product( id: model.id, name: model.name, description: model.description, price: model.price, imageUrl: model.imageUrl, categoryId: model.categoryId, stockQuantity: model.stockQuantity, isAvailable: model.isAvailable, createdAt: model.createdAt, updatedAt: model.updatedAt, ); } /// Convert Product entity to ProductModel ProductModel _toModel(Product entity) { return ProductModel( id: entity.id, name: entity.name, description: entity.description, price: entity.price, imageUrl: entity.imageUrl, categoryId: entity.categoryId, stockQuantity: entity.stockQuantity, isAvailable: entity.isAvailable, createdAt: entity.createdAt, updatedAt: entity.updatedAt, ); } @override Future> getAllProducts() async { try { return _box.values.map(_toEntity).toList(); } catch (e) { throw Exception('Failed to get products: $e'); } } @override Future getProductById(String id) async { try { final model = _box.get(id); return model != null ? _toEntity(model) : null; } catch (e) { throw Exception('Failed to get product by ID: $e'); } } @override Future> getProductsByCategory(String categoryId) async { try { return _box.values .where((product) => product.categoryId == categoryId) .map(_toEntity) .toList(); } catch (e) { throw Exception('Failed to get products by category: $e'); } } @override Future saveProducts(List products) async { try { final models = products.map(_toModel).toList(); final Map productsMap = { for (var model in models) model.id: model }; await _box.putAll(productsMap); } catch (e) { throw Exception('Failed to save products: $e'); } } @override Future deleteAllProducts() async { try { await _box.clear(); } catch (e) { throw Exception('Failed to delete all products: $e'); } } /// Additional Hive-specific methods /// Save a single product Future saveProduct(Product product) async { try { final model = _toModel(product); await _box.put(model.id, model); } catch (e) { throw Exception('Failed to save product: $e'); } } /// Update an existing product Future updateProduct(Product product) async { try { if (!_box.containsKey(product.id)) { throw Exception('Product not found: ${product.id}'); } final model = _toModel(product); await _box.put(model.id, model); } catch (e) { throw Exception('Failed to update product: $e'); } } /// Delete a specific product Future deleteProduct(String id) async { try { await _box.delete(id); } catch (e) { throw Exception('Failed to delete product: $e'); } } /// Check if product exists Future productExists(String id) async { try { return _box.containsKey(id); } catch (e) { throw Exception('Failed to check product existence: $e'); } } /// Get available products only Future> getAvailableProducts() async { try { return _box.values .where((product) => product.isAvailable && product.stockQuantity > 0) .map(_toEntity) .toList(); } catch (e) { throw Exception('Failed to get available products: $e'); } } /// Get products with low stock Future> getLowStockProducts(int threshold) async { try { return _box.values .where((product) => product.stockQuantity <= threshold && product.stockQuantity > 0) .map(_toEntity) .toList(); } catch (e) { throw Exception('Failed to get low stock products: $e'); } } /// Search products by name or description Future> searchProducts(String query) async { try { final lowercaseQuery = query.toLowerCase(); return _box.values .where((product) => product.name.toLowerCase().contains(lowercaseQuery) || product.description.toLowerCase().contains(lowercaseQuery)) .map(_toEntity) .toList(); } catch (e) { throw Exception('Failed to search products: $e'); } } }