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<GoogleActivityEvent, GoogleActivityState> {
  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<LoadGoogleActivities>(_onLoadGoogleActivities);
    on<LoadMoreGoogleActivities>(_onLoadMoreGoogleActivities);
    on<UpdateGoogleActivities>(_onUpdateGoogleActivities);
    on<AddGoogleActivityToDb>(_onAddGoogleActivityToDb);
    on<SearchGoogleActivitiesByCategory>(_onSearchGoogleActivitiesByCategory);
    on<ClearGoogleActivities>(_onClearGoogleActivities);
  }

  /// Charger les activités Google Places avec pagination (6 par page)
  Future<void> _onLoadGoogleActivities(
    LoadGoogleActivities event,
    Emitter<GoogleActivityState> 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<Activity>,
        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<void> _onLoadMoreGoogleActivities(
    LoadMoreGoogleActivities event,
    Emitter<GoogleActivityState> 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<Activity>;
      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<void> _onUpdateGoogleActivities(
    UpdateGoogleActivities event,
    Emitter<GoogleActivityState> 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<void> _onAddGoogleActivityToDb(
    AddGoogleActivityToDb event,
    Emitter<GoogleActivityState> 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<void> _onSearchGoogleActivitiesByCategory(
    SearchGoogleActivitiesByCategory event,
    Emitter<GoogleActivityState> 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<void> _onClearGoogleActivities(
    ClearGoogleActivities event,
    Emitter<GoogleActivityState> emit,
  ) async {
    emit(const GoogleActivityInitial());
  }
}