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<ApprovedActivityEvent, ApprovedActivityState> {
  final ActivityRepository _repository;
  final ErrorService _errorService;

  ApprovedActivityBloc({
    required ActivityRepository repository,
    required ErrorService errorService,
  })  : _repository = repository,
        _errorService = errorService,
        super(const ApprovedActivityInitial()) {
    
    on<LoadApprovedActivities>(_onLoadApprovedActivities);
    on<SearchApprovedActivities>(_onSearchApprovedActivities);
    on<FilterApprovedActivities>(_onFilterApprovedActivities);
    on<RefreshApprovedActivities>(_onRefreshApprovedActivities);
    on<ClearApprovedSearchResults>(_onClearApprovedSearchResults);
  }

  /// Charger les activités approuvées par tous les participants
  Future<void> _onLoadApprovedActivities(
    LoadApprovedActivities event,
    Emitter<ApprovedActivityState> 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<void> _onSearchApprovedActivities(
    SearchApprovedActivities event,
    Emitter<ApprovedActivityState> 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<void> _onFilterApprovedActivities(
    FilterApprovedActivities event,
    Emitter<ApprovedActivityState> emit,
  ) async {
    if (state is! ApprovedActivityLoaded) return;
    
    final currentState = state as ApprovedActivityLoaded;
    List<Activity> 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<void> _onRefreshApprovedActivities(
    RefreshApprovedActivities event,
    Emitter<ApprovedActivityState> emit,
  ) async {
    add(LoadApprovedActivities(
      tripId: event.tripId,
      tripParticipants: event.tripParticipants,
    ));
  }

  /// Effacer les résultats de recherche
  Future<void> _onClearApprovedSearchResults(
    ClearApprovedSearchResults event,
    Emitter<ApprovedActivityState> emit,
  ) async {
    if (state is ApprovedActivitySearchResults) {
      emit(const ApprovedActivityInitial());
    }
  }
}