/// A BLoC (Business Logic Component) that manages account-related state and operations. /// /// This bloc handles account operations such as loading accounts by user ID, /// creating new accounts, and managing real-time updates from the account repository. /// It uses stream subscriptions to listen for account changes and emits corresponding states. /// /// The bloc supports the following operations: /// - Loading accounts by user ID with real-time updates /// - Creating a single account without members /// - Creating an account with associated members /// /// All errors are logged using [ErrorService] and emitted as [AccountError] states. /// /// Example usage: /// ```dart /// final accountBloc = AccountBloc(accountRepository); /// accountBloc.add(LoadAccountsByUserId('user123')); /// ``` /// /// Remember to close the bloc when done to cancel active subscriptions: /// ```dart /// accountBloc.close(); /// ``` library; import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:travel_mate/services/error_service.dart'; import 'account_event.dart'; import 'account_state.dart'; import '../../repositories/account_repository.dart'; import '../../models/account.dart'; class AccountBloc extends Bloc { final AccountRepository _repository; StreamSubscription? _accountsSubscription; final _errorService = ErrorService(); AccountBloc(this._repository) : super(AccountInitial()) { on(_onLoadAccountsByUserId); on<_AccountsUpdated>(_onAccountsUpdated); on(_onCreateAccount); on(_onCreateAccountWithMembers); } Future _onLoadAccountsByUserId( LoadAccountsByUserId event, Emitter emit, ) async { try { emit(AccountLoading()); await _accountsSubscription?.cancel(); _accountsSubscription = _repository.getAccountByUserId(event.userId).listen( (accounts) { add(_AccountsUpdated(accounts)); }, onError: (error) { add(_AccountsUpdated([], error: error.toString())); }, ); } catch (e, stackTrace) { _errorService.logError(e.toString(), stackTrace); emit(AccountError(e.toString())); } } Future _onAccountsUpdated( _AccountsUpdated event, Emitter emit, ) async { if (event.error != null) { _errorService.logError(event.error!, StackTrace.current); emit(AccountError(event.error!)); } else { emit(AccountsLoaded(event.accounts)); } } Future _onCreateAccount( CreateAccount event, Emitter emit, ) async { try { emit(AccountLoading()); final accountId = await _repository.createAccountWithMembers( account: event.account, members: [], ); emit(AccountOperationSuccess('Compte créé avec succès. ID: $accountId')); } catch (e, stackTrace) { _errorService.logError(e.toString(), stackTrace); emit(AccountError('Erreur lors de la création du compte: ${e.toString()}')); } } Future _onCreateAccountWithMembers( CreateAccountWithMembers event, Emitter emit, ) async { try{ emit(AccountLoading()); final accountId = await _repository.createAccountWithMembers( account: event.account, members: event.members, ); emit(AccountOperationSuccess('Compte créé avec succès. ID: $accountId')); } catch (e, stackTrace) { _errorService.logError(e.toString(), stackTrace); emit(AccountError('Erreur lors de la création du compte: ${e.toString()}')); } } @override Future close() { _accountsSubscription?.cancel(); return super.close(); } } class _AccountsUpdated extends AccountEvent { final List accounts; final String? error; const _AccountsUpdated(this.accounts, {this.error}); @override List get props => [accounts, error]; }