import 'dart:developer';

import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow/core/application/di/injectable.dart';
import 'package:krow/core/data/enums/state_status.dart';
import 'package:krow/features/profile/emergency_contacts/data/emergency_contact_repository.dart';
import 'package:krow/features/profile/emergency_contacts/data/models/emergency_contact_model.dart';

part 'emergency_contacts_event.dart';

part 'emergency_contacts_state.dart';

class EmergencyContactsBloc
    extends Bloc<EmergencyContactsEvent, EmergencyContactsState> {
  EmergencyContactsBloc() : super(const EmergencyContactsState()) {
    on<InitializeEmergencyContactsEvent>(_handleInitializeEvent);

    on<AddNewContactEvent>(_handleAddNewContactEvent);

    on<UpdateContactEvent>(_handleUpdateContactEvent);

    on<DeleteContactEvent>(_handleDeleteContactEvent);

    on<SaveContactsChanges>(_handleSaveContactsChanges);
  }

  Future<void> _handleInitializeEvent(
    InitializeEmergencyContactsEvent event,
    Emitter<EmergencyContactsState> emit,
  ) async {
    emit(
      state.copyWith(
        isInEditMode: event.isInEditMode,
        contacts: event.isInEditMode
            ? state.contacts
            : [const EmergencyContactModel.empty()],
        status: event.isInEditMode ? StateStatus.loading : StateStatus.idle,
      ),
    );
    if (!state.isInEditMode) return;

    try {
      await for (final emergencyContacts
          in getIt<EmergencyContactRepository>().getStaffEmergencyContacts()) {
        if (emergencyContacts.isEmpty) continue;

        emit(
          state.copyWith(
            contacts: emergencyContacts,
            status: StateStatus.idle,
            isListReducible: emergencyContacts.length > 1,
          ),
        );
      }
    } catch (except) {
      log(except.toString());
    }

    if (state.status == StateStatus.loading) {
      emit(state.copyWith(status: StateStatus.idle));
    }
  }

  void _handleAddNewContactEvent(
    AddNewContactEvent event,
    Emitter<EmergencyContactsState> emit,
  ) {
    emit(
      state.copyWith(
        contacts: [
          ...state.contacts,
          const EmergencyContactModel.empty(),
        ],
        isListReducible: true,
      ),
    );
  }

  void _handleUpdateContactEvent(
    UpdateContactEvent event,
    Emitter<EmergencyContactsState> emit,
  ) {
    final updatedContact = state.contacts[event.index].copyWith(
      firstName: event.firstName,
      lastName: event.lastName,
      phoneNumber: event.phoneNumber,
    );

    emit(
      state.copyWith(
        contacts: List.from(state.contacts)..[event.index] = updatedContact,
      ),
    );
  }

  void _handleDeleteContactEvent(
    DeleteContactEvent event,
    Emitter<EmergencyContactsState> emit,
  ) {
    emit(
      state.copyWith(
        contacts: List.from(state.contacts)..removeAt(event.index),
        isListReducible: state.contacts.length > 2,
      ),
    );
  }

  Future<void> _handleSaveContactsChanges(
    SaveContactsChanges event,
    Emitter<EmergencyContactsState> emit,
  ) async {
    emit(state.copyWith(status: StateStatus.loading));

    try {
      await getIt<EmergencyContactRepository>().updateEmergencyContacts(
        state.contacts,
      );
    } catch (except) {
      log(except.toString());
    }

    emit(state.copyWith(status: StateStatus.success));
  }
}
