import 'package:flutter_bloc/flutter_bloc.dart';
import '../../domain/arguments/get_coverage_stats_arguments.dart';
import '../../domain/arguments/get_shifts_for_date_arguments.dart';
import 'package:krow_core/core.dart';
import 'package:krow_domain/krow_domain.dart';
import '../../domain/usecases/get_coverage_stats_usecase.dart';
import '../../domain/usecases/get_shifts_for_date_usecase.dart';
import 'coverage_event.dart';
import 'coverage_state.dart';

/// BLoC for managing coverage feature state.
///
/// This BLoC handles:
/// - Loading shifts for a specific date
/// - Loading coverage statistics
/// - Refreshing coverage data
class CoverageBloc extends Bloc<CoverageEvent, CoverageState>
    with BlocErrorHandler<CoverageState> {
  /// Creates a [CoverageBloc].
  CoverageBloc({
    required GetShiftsForDateUseCase getShiftsForDate,
    required GetCoverageStatsUseCase getCoverageStats,
  }) : _getShiftsForDate = getShiftsForDate,
       _getCoverageStats = getCoverageStats,
       super(const CoverageState()) {
    on<CoverageLoadRequested>(_onLoadRequested);
    on<CoverageRefreshRequested>(_onRefreshRequested);
  }

  final GetShiftsForDateUseCase _getShiftsForDate;
  final GetCoverageStatsUseCase _getCoverageStats;

  /// Handles the load requested event.
  Future<void> _onLoadRequested(
    CoverageLoadRequested event,
    Emitter<CoverageState> emit,
  ) async {
    emit(
      state.copyWith(
        status: CoverageStatus.loading,
        selectedDate: event.date,
      ),
    );

    await handleError(
      emit: emit,
      action: () async {
        // Fetch shifts and stats concurrently
        final List<Object> results = await Future.wait<Object>(<Future<Object>>[
          _getShiftsForDate(GetShiftsForDateArguments(date: event.date)),
          _getCoverageStats(GetCoverageStatsArguments(date: event.date)),
        ]);

        final List<CoverageShift> shifts = results[0] as List<CoverageShift>;
        final CoverageStats stats = results[1] as CoverageStats;

        emit(
          state.copyWith(
            status: CoverageStatus.success,
            shifts: shifts,
            stats: stats,
          ),
        );
      },
      onError: (String errorKey) => state.copyWith(
        status: CoverageStatus.failure,
        errorMessage: errorKey,
      ),
    );
  }

  /// Handles the refresh requested event.
  Future<void> _onRefreshRequested(
    CoverageRefreshRequested event,
    Emitter<CoverageState> emit,
  ) async {
    if (state.selectedDate == null) return;

    // Reload data for the current selected date
    add(CoverageLoadRequested(date: state.selectedDate!));
  }
}

