import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import '../../domain/entities/dashboard_entity.dart';
import '../../domain/usecases/get_dashboard_data.dart';
import '../../../../core/error/failures.dart';

part 'dashboard_event.dart';
part 'dashboard_state.dart';

class DashboardBloc extends Bloc<DashboardEvent, DashboardState> {
  final GetDashboardData getDashboardData;
  final GetDashboardStats getDashboardStats;
  final GetRecentActivities getRecentActivities;
  final GetUpcomingEvents getUpcomingEvents;

  DashboardBloc({
    required this.getDashboardData,
    required this.getDashboardStats,
    required this.getRecentActivities,
    required this.getUpcomingEvents,
  }) : super(DashboardInitial()) {
    on<LoadDashboardData>(_onLoadDashboardData);
    on<RefreshDashboardData>(_onRefreshDashboardData);
    on<LoadDashboardStats>(_onLoadDashboardStats);
    on<LoadRecentActivities>(_onLoadRecentActivities);
    on<LoadUpcomingEvents>(_onLoadUpcomingEvents);
  }

  Future<void> _onLoadDashboardData(
    LoadDashboardData event,
    Emitter<DashboardState> emit,
  ) async {
    emit(DashboardLoading());

    final result = await getDashboardData(
      GetDashboardDataParams(
        organizationId: event.organizationId,
        userId: event.userId,
      ),
    );

    result.fold(
      (failure) => emit(DashboardError(_mapFailureToMessage(failure))),
      (dashboardData) => emit(DashboardLoaded(dashboardData)),
    );
  }

  Future<void> _onRefreshDashboardData(
    RefreshDashboardData event,
    Emitter<DashboardState> emit,
  ) async {
    // Garde l'état actuel pendant le refresh
    if (state is DashboardLoaded) {
      emit(DashboardRefreshing((state as DashboardLoaded).dashboardData));
    } else {
      emit(DashboardLoading());
    }

    final result = await getDashboardData(
      GetDashboardDataParams(
        organizationId: event.organizationId,
        userId: event.userId,
      ),
    );

    result.fold(
      (failure) => emit(DashboardError(_mapFailureToMessage(failure))),
      (dashboardData) => emit(DashboardLoaded(dashboardData)),
    );
  }

  Future<void> _onLoadDashboardStats(
    LoadDashboardStats event,
    Emitter<DashboardState> emit,
  ) async {
    final result = await getDashboardStats(
      GetDashboardStatsParams(
        organizationId: event.organizationId,
        userId: event.userId,
      ),
    );

    result.fold(
      (failure) => emit(DashboardError(_mapFailureToMessage(failure))),
      (stats) {
        if (state is DashboardLoaded) {
          final currentData = (state as DashboardLoaded).dashboardData;
          final updatedData = DashboardEntity(
            stats: stats,
            recentActivities: currentData.recentActivities,
            upcomingEvents: currentData.upcomingEvents,
            userPreferences: currentData.userPreferences,
            organizationId: currentData.organizationId,
            userId: currentData.userId,
          );
          emit(DashboardLoaded(updatedData));
        }
      },
    );
  }

  Future<void> _onLoadRecentActivities(
    LoadRecentActivities event,
    Emitter<DashboardState> emit,
  ) async {
    final result = await getRecentActivities(
      GetRecentActivitiesParams(
        organizationId: event.organizationId,
        userId: event.userId,
        limit: event.limit,
      ),
    );

    result.fold(
      (failure) => emit(DashboardError(_mapFailureToMessage(failure))),
      (activities) {
        if (state is DashboardLoaded) {
          final currentData = (state as DashboardLoaded).dashboardData;
          final updatedData = DashboardEntity(
            stats: currentData.stats,
            recentActivities: activities,
            upcomingEvents: currentData.upcomingEvents,
            userPreferences: currentData.userPreferences,
            organizationId: currentData.organizationId,
            userId: currentData.userId,
          );
          emit(DashboardLoaded(updatedData));
        }
      },
    );
  }

  Future<void> _onLoadUpcomingEvents(
    LoadUpcomingEvents event,
    Emitter<DashboardState> emit,
  ) async {
    final result = await getUpcomingEvents(
      GetUpcomingEventsParams(
        organizationId: event.organizationId,
        userId: event.userId,
        limit: event.limit,
      ),
    );

    result.fold(
      (failure) => emit(DashboardError(_mapFailureToMessage(failure))),
      (events) {
        if (state is DashboardLoaded) {
          final currentData = (state as DashboardLoaded).dashboardData;
          final updatedData = DashboardEntity(
            stats: currentData.stats,
            recentActivities: currentData.recentActivities,
            upcomingEvents: events,
            userPreferences: currentData.userPreferences,
            organizationId: currentData.organizationId,
            userId: currentData.userId,
          );
          emit(DashboardLoaded(updatedData));
        }
      },
    );
  }

  String _mapFailureToMessage(Failure failure) {
    switch (failure.runtimeType) {
      case ServerFailure:
        return 'Erreur serveur. Veuillez réessayer.';
      case NetworkFailure:
        return 'Pas de connexion internet. Vérifiez votre connexion.';
      default:
        return 'Une erreur inattendue s\'est produite.';
    }
  }
}
