/// A BLoC (Business Logic Component) that manages balance-related operations for groups. /// /// This bloc handles the calculation and management of user balances within groups, /// including optimal settlement calculations and marking settlements as completed. /// /// The bloc processes three main events: /// - [LoadGroupBalances]: Loads and calculates all user balances for a specific group /// - [RefreshBalance]: Refreshes the balance data while maintaining the current state when possible /// - [MarkSettlementAsCompleted]: Records a settlement transaction between users /// /// Dependencies: /// - [BalanceRepository]: Repository for balance data operations /// - [BalanceService]: Service for balance calculations and settlement logic /// - [ErrorService]: Service for error logging and handling /// /// Example usage: /// ```dart /// final balanceBloc = BalanceBloc( /// balanceRepository: balanceRepository, /// expenseRepository: expenseRepository, /// ); /// /// // Load balances for a group /// balanceBloc.add(LoadGroupBalances('groupId123')); /// /// // Mark a settlement as completed /// balanceBloc.add(MarkSettlementAsCompleted( /// groupId: 'groupId123', /// fromUserId: 'user1', /// toUserId: 'user2', /// amount: 50.0, /// )); /// ``` import 'package:flutter_bloc/flutter_bloc.dart'; import '../../repositories/balance_repository.dart'; import '../../repositories/expense_repository.dart'; import '../../services/balance_service.dart'; import '../../services/error_service.dart'; import 'balance_event.dart'; import 'balance_state.dart'; class BalanceBloc extends Bloc { final BalanceRepository _balanceRepository; final BalanceService _balanceService; final ErrorService _errorService; BalanceBloc({ required BalanceRepository balanceRepository, required ExpenseRepository expenseRepository, BalanceService? balanceService, ErrorService? errorService, }) : _balanceRepository = balanceRepository, _balanceService = balanceService ?? BalanceService(balanceRepository: balanceRepository, expenseRepository: expenseRepository), _errorService = errorService ?? ErrorService(), super(BalanceInitial()) { on(_onLoadGroupBalance); on(_onRefreshBalance); on(_onMarkSettlementAsCompleted); } Future _onLoadGroupBalance( LoadGroupBalances event, Emitter emit, ) async { try { emit(BalanceLoading()); // Calculer les balances du groupe final userBalances = await _balanceRepository.calculateGroupUserBalances(event.groupId); // Calculer les règlements optimisés final settlements = await _balanceService.calculateOptimalSettlements(event.groupId); emit(GroupBalancesLoaded( balances: userBalances, settlements: settlements, )); } catch (e) { _errorService.logError('BalanceBloc', 'Erreur chargement balance: $e'); emit(BalanceError(e.toString())); } } Future _onRefreshBalance( RefreshBalance event, Emitter emit, ) async { try { // Garde l'état actuel pendant le refresh si possible if (state is! GroupBalancesLoaded) { emit(BalanceLoading()); } // Calculer les balances du groupe final userBalances = await _balanceRepository.calculateGroupUserBalances(event.groupId); // Calculer les règlements optimisés final settlements = await _balanceService.calculateOptimalSettlements(event.groupId); emit(GroupBalancesLoaded( balances: userBalances, settlements: settlements, )); } catch (e) { _errorService.logError('BalanceBloc', 'Erreur refresh balance: $e'); emit(BalanceError(e.toString())); } } Future _onMarkSettlementAsCompleted( MarkSettlementAsCompleted event, Emitter emit, ) async { try { await _balanceService.markSettlementAsCompleted( groupId: event.groupId, fromUserId: event.fromUserId, toUserId: event.toUserId, amount: event.amount, ); emit(const BalanceOperationSuccess('Règlement marqué comme effectué')); // Recharger la balance après le règlement add(RefreshBalance(event.groupId)); } catch (e) { _errorService.logError('BalanceBloc', 'Erreur mark settlement: $e'); emit(BalanceError(e.toString())); } } }