import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:meta/meta.dart'; import '../../core/utils/app_logger.dart'; import '../../data/datasources/event_remote_data_source.dart'; import '../../data/models/event_model.dart'; // Déclaration des événements @immutable abstract class EventEvent extends Equatable { const EventEvent(); @override List get props => []; } class LoadEvents extends EventEvent { const LoadEvents(this.userId); final String userId; @override List get props => [userId]; } class AddEvent extends EventEvent { const AddEvent(this.event); final EventModel event; @override List get props => [event]; } class CloseEvent extends EventEvent { const CloseEvent(this.eventId); final String eventId; @override List get props => [eventId]; } class ReopenEvent extends EventEvent { const ReopenEvent(this.eventId); final String eventId; @override List get props => [eventId]; } // Déclaration des états @immutable abstract class EventState extends Equatable { const EventState(); @override List get props => []; } class EventInitial extends EventState { const EventInitial(); @override List get props => []; } class EventLoading extends EventState { const EventLoading(); @override List get props => []; } class EventLoaded extends EventState { const EventLoaded(this.events); final List events; @override List get props => [events]; } class EventError extends EventState { const EventError(this.message); final String message; @override List get props => [message]; } // Bloc pour la gestion des événements class EventBloc extends Bloc { EventBloc({required this.remoteDataSource}) : super(const EventInitial()) { on(_onLoadEvents); on(_onAddEvent); on(_onCloseEvent); on(_onReopenEvent); on(_onRemoveEvent); // Ajout du gestionnaire pour RemoveEvent } final EventRemoteDataSource remoteDataSource; // Gestion du chargement des événements Future _onLoadEvents(LoadEvents event, Emitter emit) async { emit(const EventLoading()); AppLogger.i('Début du chargement des événements pour l\'utilisateur ${event.userId}', tag: 'EventBloc'); try { final events = await remoteDataSource.getEventsCreatedByUserAndFriends(event.userId); AppLogger.i('Événements chargés: ${events.length} éléments récupérés.', tag: 'EventBloc'); emit(EventLoaded(events)); } catch (e, stackTrace) { AppLogger.e('Erreur lors du chargement des événements', error: e, stackTrace: stackTrace, tag: 'EventBloc'); emit(EventError('Erreur lors du chargement des événements.')); } } // Gestion de l'ajout d'un nouvel événement Future _onAddEvent(AddEvent event, Emitter emit) async { emit(const EventLoading()); try { await remoteDataSource.createEvent(event.event); final events = await remoteDataSource.getAllEvents(); emit(EventLoaded(events)); } catch (e) { emit(EventError('Erreur lors de l\'ajout de l\'événement.')); } } // Gestion de la fermeture d'un événement Future _onCloseEvent(CloseEvent event, Emitter emit) async { final currentState = state; // Sauvegarder l'état actuel avant d'émettre EventLoading emit(const EventLoading()); // Affiche le chargement try { await remoteDataSource.closeEvent(event.eventId); // Mise à jour de l'événement spécifique dans l'état if (currentState is EventLoaded) { final updatedEvents = List.from((currentState as EventLoaded).events); try { final updatedEvent = updatedEvents.firstWhere((e) => e.id == event.eventId); updatedEvent.status = 'fermé'; // Modifier l'état de l'événement localement // Émettre un nouvel état avec l'événement mis à jour emit(EventLoaded(updatedEvents)); AppLogger.i('Événement fermé et mis à jour localement.', tag: 'EventBloc'); } catch (_) { // Événement non trouvé, restaurer l'état précédent emit(currentState); } } } catch (e, stackTrace) { AppLogger.e('Erreur lors de la fermeture de l\'événement', error: e, stackTrace: stackTrace, tag: 'EventBloc'); emit(EventError('Erreur lors de la fermeture de l\'événement.')); } } Future _onReopenEvent(ReopenEvent event, Emitter emit) async { final currentState = state; // Sauvegarder l'état actuel avant d'émettre EventLoading emit(const EventLoading()); // Affiche le chargement try { // Appel au service backend pour réouvrir l'événement await remoteDataSource.reopenEvent(event.eventId); // Mise à jour de l'événement spécifique dans l'état if (currentState is EventLoaded) { final updatedEvents = List.from((currentState as EventLoaded).events); try { final updatedEvent = updatedEvents.firstWhere((e) => e.id == event.eventId); // Mise à jour du statut local de l'événement updatedEvent.status = 'ouvert'; // Émettre un nouvel état avec l'événement mis à jour emit(EventLoaded(updatedEvents)); AppLogger.i('Événement réouvert et mis à jour localement.', tag: 'EventBloc'); } catch (_) { // Événement non trouvé, restaurer l'état précédent emit(currentState); } } } catch (e, stackTrace) { // En cas d'erreur, émettre un état d'erreur AppLogger.e('Erreur lors de la réouverture de l\'événement', error: e, stackTrace: stackTrace, tag: 'EventBloc'); emit(EventError('Erreur lors de la réouverture de l\'événement.')); } } // Gestion de la suppression locale d'un événement Future _onRemoveEvent(RemoveEvent event, Emitter emit) async { final currentState = state; // Sauvegarder l'état actuel if (currentState is EventLoaded) { // Supprimer l'événement de la liste locale sans recharger tout final List updatedEvents = List.from((currentState as EventLoaded).events) ..removeWhere((e) => e.id == event.eventId); // Toujours émettre le nouvel état, même si la liste est identique // (car removeWhere peut ne rien faire si l'événement n'existe pas) emit(EventLoaded(updatedEvents)); } } } class RemoveEvent extends EventEvent { const RemoveEvent(this.eventId); final String eventId; @override List get props => [eventId]; }