import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../repositories/expense_repository.dart'; import '../../services/expense_service.dart'; import '../../services/error_service.dart'; import 'expense_event.dart'; import 'expense_state.dart'; class ExpenseBloc extends Bloc { final ExpenseRepository _expenseRepository; final ExpenseService _expenseService; final ErrorService _errorService; StreamSubscription? _expensesSubscription; ExpenseBloc({ required ExpenseRepository expenseRepository, ExpenseService? expenseService, ErrorService? errorService, }) : _expenseRepository = expenseRepository, _expenseService = expenseService ?? ExpenseService(expenseRepository: expenseRepository), _errorService = errorService ?? ErrorService(), super(ExpenseInitial()) { on(_onLoadExpensesByGroup); on(_onExpensesUpdated); on(_onCreateExpense); on(_onUpdateExpense); on(_onDeleteExpense); on(_onMarkSplitAsPaid); on(_onArchiveExpense); } Future _onLoadExpensesByGroup( LoadExpensesByGroup event, Emitter emit, ) async { try { emit(ExpenseLoading()); await _expensesSubscription?.cancel(); _expensesSubscription = _expenseRepository .getExpensesStream(event.groupId) .listen( (expenses) => add(ExpensesUpdated(expenses)), onError: (error) => add(ExpensesUpdated([], error: error.toString())), ); } catch (e) { _errorService.logError('ExpenseBloc', 'Erreur chargement expenses: $e'); emit(ExpenseError(e.toString())); } } Future _onExpensesUpdated( ExpensesUpdated event, Emitter emit, ) async { if (event.error != null) { emit(ExpenseError(event.error!)); } else { emit(ExpensesLoaded(expenses: event.expenses)); } } Future _onCreateExpense( CreateExpense event, Emitter emit, ) async { try { await _expenseService.createExpenseWithValidation(event.expense, event.receiptImage); emit(const ExpenseOperationSuccess('Dépense créée avec succès')); } catch (e) { _errorService.logError('ExpenseBloc', 'Erreur création expense: $e'); emit(ExpenseError(e.toString())); } } Future _onUpdateExpense( UpdateExpense event, Emitter emit, ) async { try { await _expenseService.updateExpenseWithValidation(event.expense, event.newReceiptImage); emit(const ExpenseOperationSuccess('Dépense modifiée avec succès')); } catch (e) { _errorService.logError('ExpenseBloc', 'Erreur mise à jour expense: $e'); emit(ExpenseError(e.toString())); } } Future _onDeleteExpense( DeleteExpense event, Emitter emit, ) async { try { await _expenseRepository.deleteExpense(event.expenseId); emit(const ExpenseOperationSuccess('Dépense supprimée avec succès')); } catch (e) { _errorService.logError('ExpenseBloc', 'Erreur suppression expense: $e'); emit(ExpenseError(e.toString())); } } Future _onMarkSplitAsPaid( MarkSplitAsPaid event, Emitter emit, ) async { try { await _expenseRepository.markSplitAsPaid(event.expenseId, event.userId); emit(const ExpenseOperationSuccess('Paiement marqué comme effectué')); } catch (e) { _errorService.logError('ExpenseBloc', 'Erreur mark split paid: $e'); emit(ExpenseError(e.toString())); } } Future _onArchiveExpense( ArchiveExpense event, Emitter emit, ) async { try { await _expenseRepository.archiveExpense(event.expenseId); emit(const ExpenseOperationSuccess('Dépense archivée avec succès')); } catch (e) { _errorService.logError('ExpenseBloc', 'Erreur archivage expense: $e'); emit(ExpenseError(e.toString())); } } @override Future close() { _expensesSubscription?.cancel(); return super.close(); } }