import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../models/activity.dart'; import '../../../repositories/activity_repository.dart'; import '../../../services/activity_places_service.dart'; import '../../../services/error_service.dart'; import 'google_activity_event.dart'; import 'google_activity_state.dart'; /// BLoC pour gérer les activités Google Places class GoogleActivityBloc extends Bloc { final ActivityPlacesService _placesService; final ActivityRepository _repository; final ErrorService _errorService; GoogleActivityBloc({ required ActivityPlacesService placesService, required ActivityRepository repository, required ErrorService errorService, }) : _placesService = placesService, _repository = repository, _errorService = errorService, super(const GoogleActivityInitial()) { on(_onLoadGoogleActivities); on(_onLoadMoreGoogleActivities); on(_onUpdateGoogleActivities); on(_onAddGoogleActivityToDb); on(_onSearchGoogleActivitiesByCategory); on(_onClearGoogleActivities); } /// Charger les activités Google Places avec pagination (6 par page) Future _onLoadGoogleActivities( LoadGoogleActivities event, Emitter emit, ) async { try { emit(const GoogleActivitySearching()); final result = await _placesService.searchActivitiesPaginated( destination: event.destination, latitude: event.latitude, longitude: event.longitude, tripId: event.tripId, category: event.category, pageSize: 6, ); emit(GoogleActivityLoaded( googleActivities: result['activities'] as List, nextPageToken: result['nextPageToken'] as String?, hasMoreData: result['hasMoreData'] as bool? ?? false, query: event.category?.displayName ?? 'Toutes les activités', )); } catch (e) { _errorService.logError('google_activity_bloc', 'Erreur chargement activités Google: $e'); emit(const GoogleActivityError('Impossible de charger les activités Google')); } } /// Charger plus d'activités (pagination) Future _onLoadMoreGoogleActivities( LoadMoreGoogleActivities event, Emitter emit, ) async { if (state is! GoogleActivityLoaded) return; final currentState = state as GoogleActivityLoaded; if (!currentState.hasMoreData || currentState.nextPageToken == null) return; try { emit(GoogleActivityLoadingMore( currentActivities: currentState.googleActivities, query: currentState.query, )); final result = await _placesService.searchActivitiesPaginated( destination: event.destination, latitude: event.latitude, longitude: event.longitude, tripId: event.tripId, category: event.category, pageSize: 6, nextPageToken: currentState.nextPageToken, ); final newActivities = result['activities'] as List; final allActivities = [...currentState.googleActivities, ...newActivities]; emit(GoogleActivityLoaded( googleActivities: allActivities, nextPageToken: result['nextPageToken'] as String?, hasMoreData: result['hasMoreData'] as bool? ?? false, query: currentState.query, )); } catch (e) { _errorService.logError('google_activity_bloc', 'Erreur chargement plus activités: $e'); emit(const GoogleActivityError('Impossible de charger plus d\'activités')); } } /// Mettre à jour les activités Google Future _onUpdateGoogleActivities( UpdateGoogleActivities event, Emitter emit, ) async { emit(GoogleActivityLoaded( googleActivities: event.activities, nextPageToken: event.nextPageToken, hasMoreData: event.hasMoreData, query: event.query, )); } /// Ajouter une activité Google à la base de données Future _onAddGoogleActivityToDb( AddGoogleActivityToDb event, Emitter emit, ) async { try { // Vérifier si l'activité existe déjà if (event.activity.placeId != null) { final existingActivity = await _repository.findExistingActivity( event.activity.tripId, event.activity.placeId!, ); if (existingActivity != null) { emit(const GoogleActivityOperationSuccess('Cette activité est déjà dans votre voyage')); return; } } await _repository.addActivity(event.activity); emit(const GoogleActivityOperationSuccess('Activité ajoutée au voyage')); } catch (e) { _errorService.logError('google_activity_bloc', 'Erreur ajout activité: $e'); emit(const GoogleActivityError('Impossible d\'ajouter l\'activité')); } } /// Rechercher par catégorie Future _onSearchGoogleActivitiesByCategory( SearchGoogleActivitiesByCategory event, Emitter emit, ) async { add(LoadGoogleActivities( tripId: event.tripId, destination: event.destination, latitude: event.latitude, longitude: event.longitude, category: event.category, )); } /// Effacer les activités Google Future _onClearGoogleActivities( ClearGoogleActivities event, Emitter emit, ) async { emit(const GoogleActivityInitial()); } }