import 'dart:developer' as developer; import 'package:hive/hive.dart'; import '../models/offline_mutation_model.dart'; class OfflineMutationQueue { static const String _mutationsBoxName = 'offline_mutations'; late Box _mutationsBox; Future init() async { _mutationsBox = await Hive.openBox(_mutationsBoxName); } Future enqueueMutation(OfflineMutation mutation) async { await _mutationsBox.put(mutation.id, mutation); } Future> getPendingMutations() async { return _mutationsBox.values .where((mutation) => !mutation.isSynced) .toList() ..sort((a, b) => a.createdAt.compareTo(b.createdAt)); } Future markMutationAsSynced(String mutationId) async { final mutation = _mutationsBox.get(mutationId); if (mutation != null) { await _mutationsBox.put( mutationId, mutation.copyWith( isSynced: true, syncedAt: DateTime.now(), ), ); } } Future removeSyncedMutations() async { final syncedMutations = _mutationsBox.values .where((mutation) => mutation.isSynced) .toList(); for (var mutation in syncedMutations) { await _mutationsBox.delete(mutation.id); } } Future clearMutation(String mutationId) async { await _mutationsBox.delete(mutationId); } Future clearAllMutations() async { await _mutationsBox.clear(); } Future getPendingMutationCount() async { return _mutationsBox.values.where((m) => !m.isSynced).length; } Future syncPendingMutations({ required Future Function(OfflineMutation) onSync, }) async { final pendingMutations = await getPendingMutations(); for (var mutation in pendingMutations) { try { await onSync(mutation); await markMutationAsSynced(mutation.id); } catch (e, stackTrace) { // Log error but continue with next mutation developer.log( 'Error syncing mutation ${mutation.id}: $e', name: 'OfflineMutationQueue', error: e, stackTrace: stackTrace, ); } } await removeSyncedMutations(); } Future close() async { await _mutationsBox.close(); } }