import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow_domain/krow_domain.dart';
import '../../domain/arguments/get_emergency_contacts_arguments.dart';
import '../../domain/arguments/save_emergency_contacts_arguments.dart';
import '../../domain/usecases/get_emergency_contacts_usecase.dart';
import '../../domain/usecases/save_emergency_contacts_usecase.dart';
import 'emergency_contact_event.dart';
import 'emergency_contact_state.dart';

export 'emergency_contact_event.dart';
export 'emergency_contact_state.dart';

// BLoC
class EmergencyContactBloc
    extends Bloc<EmergencyContactEvent, EmergencyContactState> {
  final GetEmergencyContactsUseCase getEmergencyContacts;
  final SaveEmergencyContactsUseCase saveEmergencyContacts;

  EmergencyContactBloc({
    required this.getEmergencyContacts,
    required this.saveEmergencyContacts,
  }) : super(const EmergencyContactState()) {
    on<EmergencyContactsLoaded>(_onLoaded);
    on<EmergencyContactAdded>(_onAdded);
    on<EmergencyContactRemoved>(_onRemoved);
    on<EmergencyContactUpdated>(_onUpdated);
    on<EmergencyContactsSaved>(_onSaved);

    add(EmergencyContactsLoaded());
  }
  

  Future<void> _onLoaded(
    EmergencyContactsLoaded event,
    Emitter<EmergencyContactState> emit,
  ) async {
    emit(state.copyWith(status: EmergencyContactStatus.loading));
    try {
      final contacts = await getEmergencyContacts(
        const GetEmergencyContactsArguments(),
      );
      emit(state.copyWith(
        status: EmergencyContactStatus.loaded,
        contacts: contacts.isNotEmpty
            ? contacts
            : [EmergencyContact.empty()],
      ));
    } catch (e) {
      emit(state.copyWith(
        status: EmergencyContactStatus.failure,
        errorMessage: e.toString(),
      ));
    }
  }

  void _onAdded(
    EmergencyContactAdded event,
    Emitter<EmergencyContactState> emit,
  ) {
    final updatedContacts = List<EmergencyContact>.from(state.contacts)
      ..add(EmergencyContact.empty());
    emit(state.copyWith(contacts: updatedContacts));
  }

  void _onRemoved(
    EmergencyContactRemoved event,
    Emitter<EmergencyContactState> emit,
  ) {
    final updatedContacts = List<EmergencyContact>.from(state.contacts)
      ..removeAt(event.index);
    emit(state.copyWith(contacts: updatedContacts));
  }

  void _onUpdated(
    EmergencyContactUpdated event,
    Emitter<EmergencyContactState> emit,
  ) {
    final updatedContacts = List<EmergencyContact>.from(state.contacts);
    updatedContacts[event.index] = event.contact;
    emit(state.copyWith(contacts: updatedContacts));
  }

  Future<void> _onSaved(
    EmergencyContactsSaved event,
    Emitter<EmergencyContactState> emit,
  ) async {
    emit(state.copyWith(status: EmergencyContactStatus.saving));
    try {
      await saveEmergencyContacts(
        SaveEmergencyContactsArguments(
          contacts: state.contacts,
        ),
      );
      emit(state.copyWith(status: EmergencyContactStatus.saved));
    } catch (e) {
      emit(state.copyWith(
        status: EmergencyContactStatus.failure,
        errorMessage: e.toString(),
      ));
    }
  }
}
