/// BLoC pour la gestion des rapports (Clean Architecture)
library reports_bloc;

import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../../domain/usecases/get_reports.dart';
import '../../domain/usecases/generate_report.dart';
import '../../domain/usecases/export_report_pdf.dart';
import '../../domain/usecases/export_report_excel.dart';
import '../../domain/usecases/schedule_report.dart';
import '../../domain/usecases/get_scheduled_reports.dart';
import '../../domain/repositories/reports_repository.dart';

part 'reports_event.dart';
part 'reports_state.dart';

/// BLoC pour la gestion des rapports (Clean Architecture)
@injectable
class ReportsBloc extends Bloc<ReportsEvent, ReportsState> {
  final GetReports _getReports;
  final GenerateReport _generateReport;
  final ExportReportPdf _exportReportPdf;
  final ExportReportExcel _exportReportExcel;
  final ScheduleReport _scheduleReport;
  final GetScheduledReports _getScheduledReports;
  final IReportsRepository _repository; // Pour méthodes non-couvertes (statistics, analytics)

  ReportsBloc(
    this._getReports,
    this._generateReport,
    this._exportReportPdf,
    this._exportReportExcel,
    this._scheduleReport,
    this._getScheduledReports,
    this._repository,
  ) : super(const ReportsInitial()) {
    on<LoadDashboardReports>(_onLoadDashboard);
    on<ScheduleReportRequested>(_onScheduleReport);
    on<GenerateReportRequested>(_onGenerateReport);
  }

  /// Charge le tableau de bord des rapports
  Future<void> _onLoadDashboard(
    LoadDashboardReports event,
    Emitter<ReportsState> emit,
  ) async {
    try {
      emit(const ReportsLoading());
      final anneeActuelle = DateTime.now().year;

      // Appels parallèles pour les performances
      final results = await Future.wait([
        _repository.getPerformanceGlobale(),
        _repository.getStatistiquesMembres(),
        _repository.getStatistiquesCotisations(anneeActuelle),
        _repository.getStatistiquesEvenements(),
      ]);

      emit(ReportsDashboardLoaded(
        performance: results[0],
        statsMembres: results[1],
        statsCotisations: results[2],
        statsEvenements: results[3],
      ));
    } catch (e) {
      emit(ReportsError('Erreur lors du chargement des rapports : $e'));
    }
  }

  /// Programme un rapport automatique
  Future<void> _onScheduleReport(
    ScheduleReportRequested event,
    Emitter<ReportsState> emit,
  ) async {
    try {
      await _scheduleReport(cronExpression: event.cronExpression);
      emit(const ReportScheduled());
    } catch (e) {
      emit(ReportsError('Impossible de programmer le rapport : $e'));
    }
  }

  /// Génère un rapport
  Future<void> _onGenerateReport(
    GenerateReportRequested event,
    Emitter<ReportsState> emit,
  ) async {
    try {
      await _generateReport(event.type, format: event.format);
      emit(ReportGenerated(event.type));
    } catch (e) {
      emit(ReportsError('Impossible de générer le rapport : $e'));
    }
  }
}
