import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:krow_domain/krow_domain.dart';
import 'package:meta/meta.dart';

import '../../../domain/usecases/get_available_shifts_usecase.dart';
import '../../../domain/arguments/get_available_shifts_arguments.dart';
import '../../../domain/usecases/get_my_shifts_usecase.dart';
import '../../../domain/usecases/get_pending_assignments_usecase.dart';

part 'shifts_event.dart';
part 'shifts_state.dart';

class ShiftsBloc extends Bloc<ShiftsEvent, ShiftsState> {
  final GetMyShiftsUseCase getMyShifts;
  final GetAvailableShiftsUseCase getAvailableShifts;
  final GetPendingAssignmentsUseCase getPendingAssignments;

  ShiftsBloc({
    required this.getMyShifts,
    required this.getAvailableShifts,
    required this.getPendingAssignments,
  }) : super(ShiftsInitial()) {
    on<LoadShiftsEvent>(_onLoadShifts);
    on<FilterAvailableShiftsEvent>(_onFilterAvailableShifts);
  }

  Future<void> _onLoadShifts(
    LoadShiftsEvent event,
    Emitter<ShiftsState> emit,
  ) async {
    if (state is! ShiftsLoaded) {
      emit(ShiftsLoading());
    }
    
    // Determine what to load based on current tab? 
    // Or load all for simplicity as per prototype logic which had them all in memory.
    
    try {
      final myShiftsResult = await getMyShifts();
      final pendingResult = await getPendingAssignments();
      
      // Initial available with defaults
      final availableResult = await getAvailableShifts(const GetAvailableShiftsArguments());

      emit(ShiftsLoaded(
        myShifts: myShiftsResult,
        pendingShifts: pendingResult,
        availableShifts: availableResult,
        searchQuery: '',
        jobType: 'all',
      ));
    } catch (_) {
      emit(const ShiftsError('Failed to load shifts'));
    }
  }

  Future<void> _onFilterAvailableShifts(
    FilterAvailableShiftsEvent event,
    Emitter<ShiftsState> emit,
  ) async {
    final currentState = state;
    if (currentState is ShiftsLoaded) {
      // Optimistic update or loading indicator?
      // Since it's filtering, we can just reload available.
      
      try {
        final result = await getAvailableShifts(GetAvailableShiftsArguments(
          query: event.query ?? currentState.searchQuery,
          type: event.jobType ?? currentState.jobType,
        ));

        emit(currentState.copyWith(
          availableShifts: result,
          searchQuery: event.query ?? currentState.searchQuery,
          jobType: event.jobType ?? currentState.jobType,
        ));
      } catch (_) {
        // Error handling if filter fails
      }
    }
  }
}
