import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../models/activity.dart'; import '../../../repositories/activity_repository.dart'; import '../../../services/error_service.dart'; import 'approved_activity_event.dart'; import 'approved_activity_state.dart'; /// BLoC pour gérer les activités approuvées par tous les participants class ApprovedActivityBloc extends Bloc { final ActivityRepository _repository; final ErrorService _errorService; ApprovedActivityBloc({ required ActivityRepository repository, required ErrorService errorService, }) : _repository = repository, _errorService = errorService, super(const ApprovedActivityInitial()) { on(_onLoadApprovedActivities); on(_onSearchApprovedActivities); on(_onFilterApprovedActivities); on(_onRefreshApprovedActivities); on(_onClearApprovedSearchResults); } /// Charger les activités approuvées par tous les participants Future _onLoadApprovedActivities( LoadApprovedActivities event, Emitter emit, ) async { try { emit(const ApprovedActivityLoading()); final allActivities = await _repository.getActivitiesByTrip(event.tripId); // Filtrer les activités qui ont reçu des votes positifs de TOUS les participants final approvedActivities = allActivities.where((activity) { // Une activité est approuvée si tous les participants ont voté positivement final positiveVoters = activity.votes.entries .where((entry) => entry.value > 0) .map((entry) => entry.key) .toSet(); // Vérifier que tous les participants ont voté positivement return event.tripParticipants.every((participant) => positiveVoters.contains(participant)); }).toList(); // Trier par nombre total de votes puis par rating approvedActivities.sort((a, b) { final aVotes = a.totalVotes; final bVotes = b.totalVotes; if (aVotes != bVotes) { return bVotes.compareTo(aVotes); } return (b.rating ?? 0).compareTo(a.rating ?? 0); }); emit(ApprovedActivityLoaded( approvedActivities: approvedActivities, tripParticipants: event.tripParticipants, )); } catch (e) { _errorService.logError('approved_activity_bloc', 'Erreur chargement activités approuvées: $e'); emit(const ApprovedActivityError('Impossible de charger les activités approuvées')); } } /// Rechercher dans les activités approuvées Future _onSearchApprovedActivities( SearchApprovedActivities event, Emitter emit, ) async { try { emit(const ApprovedActivitySearching()); // Charger d'abord toutes les activités approuvées final allActivities = await _repository.getActivitiesByTrip(event.tripId); // Filtrer les approuvées puis rechercher final approvedActivities = allActivities.where((activity) { final positiveVoters = activity.votes.entries .where((entry) => entry.value > 0) .map((entry) => entry.key) .toSet(); return event.tripParticipants.every((participant) => positiveVoters.contains(participant)); }).toList(); // Rechercher dans les activités approuvées final results = approvedActivities .where((activity) => activity.name.toLowerCase().contains(event.query.toLowerCase()) || activity.description.toLowerCase().contains(event.query.toLowerCase()) || activity.category.toLowerCase().contains(event.query.toLowerCase())) .toList(); emit(ApprovedActivitySearchResults( results: results, query: event.query, tripParticipants: event.tripParticipants, )); } catch (e) { _errorService.logError('approved_activity_bloc', 'Erreur recherche approuvées: $e'); emit(const ApprovedActivityError('Erreur lors de la recherche')); } } /// Filtrer les activités approuvées Future _onFilterApprovedActivities( FilterApprovedActivities event, Emitter emit, ) async { if (state is! ApprovedActivityLoaded) return; final currentState = state as ApprovedActivityLoaded; List filteredActivities = List.from(currentState.approvedActivities); // Filtrer par catégorie if (event.category != null && event.category!.isNotEmpty) { filteredActivities = filteredActivities .where((activity) => activity.category == event.category) .toList(); } // Filtrer par rating minimum if (event.minRating != null) { filteredActivities = filteredActivities .where((activity) => (activity.rating ?? 0) >= event.minRating!) .toList(); } emit(currentState.copyWith(approvedActivities: filteredActivities)); } /// Rafraîchir les activités approuvées Future _onRefreshApprovedActivities( RefreshApprovedActivities event, Emitter emit, ) async { add(LoadApprovedActivities( tripId: event.tripId, tripParticipants: event.tripParticipants, )); } /// Effacer les résultats de recherche Future _onClearApprovedSearchResults( ClearApprovedSearchResults event, Emitter emit, ) async { if (state is ApprovedActivitySearchResults) { emit(const ApprovedActivityInitial()); } } }