import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_domain/krow_domain.dart';

import '../../domain/usecases/get_personal_info_usecase.dart';
import '../../domain/usecases/update_personal_info_usecase.dart';
import 'personal_info_event.dart';
import 'personal_info_state.dart';

/// BLoC responsible for managing staff profile information state.
///
/// This BLoC handles loading, updating, and saving staff profile information
/// during onboarding or profile editing. It delegates business logic to
/// use cases following Clean Architecture principles.
class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
    implements Disposable {
  final GetPersonalInfoUseCase _getPersonalInfoUseCase;
  final UpdatePersonalInfoUseCase _updatePersonalInfoUseCase;

  /// Creates a [PersonalInfoBloc].
  ///
  /// Requires the use cases to load and update the profile.
  PersonalInfoBloc({
    required GetPersonalInfoUseCase getPersonalInfoUseCase,
    required UpdatePersonalInfoUseCase updatePersonalInfoUseCase,
  })  : _getPersonalInfoUseCase = getPersonalInfoUseCase,
        _updatePersonalInfoUseCase = updatePersonalInfoUseCase,
        super(const PersonalInfoState.initial()) {
    on<PersonalInfoLoadRequested>(_onLoadRequested);
    on<PersonalInfoFieldChanged>(_onFieldChanged);
    on<PersonalInfoAddressSelected>(_onAddressSelected);
    on<PersonalInfoFormSubmitted>(_onSubmitted);

    add(const PersonalInfoLoadRequested());
  }

  /// Handles loading staff profile information.
  Future<void> _onLoadRequested(
    PersonalInfoLoadRequested event,
    Emitter<PersonalInfoState> emit,
  ) async {
    emit(state.copyWith(status: PersonalInfoStatus.loading));
    try {
      final Staff staff = await _getPersonalInfoUseCase();
      
      // Initialize form values from staff entity
      // Note: Staff entity currently stores address as a string, but we want to map it to 'preferredLocations'
      final Map<String, dynamic> initialValues = {
        'name': staff.name,
        'email': staff.email,
        'phone': staff.phone,
        'preferredLocations': staff.address != null 
            ? [staff.address] 
            : [], // TODO: Map correctly when Staff entity supports list
        'avatar': staff.avatar,
      };

      emit(state.copyWith(
        status: PersonalInfoStatus.loaded,
        staff: staff,
        formValues: initialValues,
      ));
    } catch (e) {
      emit(state.copyWith(
        status: PersonalInfoStatus.error,
        errorMessage: e.toString(),
      ));
    }
  }

  /// Handles updating a field value in the current staff profile.
  void _onFieldChanged(
    PersonalInfoFieldChanged event,
    Emitter<PersonalInfoState> emit,
  ) {
    final Map<String, dynamic> updatedValues = Map.from(state.formValues);
    updatedValues[event.field] = event.value;
    emit(state.copyWith(formValues: updatedValues));
  }

  /// Handles saving staff profile information.
  Future<void> _onSubmitted(
    PersonalInfoFormSubmitted event,
    Emitter<PersonalInfoState> emit,
  ) async {
    if (state.staff == null) return;

    emit(state.copyWith(status: PersonalInfoStatus.saving));
    try {
      final Staff updatedStaff = await _updatePersonalInfoUseCase(
        UpdatePersonalInfoParams(
          staffId: state.staff!.id,
          data: state.formValues,
        ),
      );
      
      // Update local state with the returned staff and keep form values in sync
      final Map<String, dynamic> newValues = {
        'name': updatedStaff.name,
        'email': updatedStaff.email,
        'phone': updatedStaff.phone,
        'preferredLocations': updatedStaff.address != null 
            ? [updatedStaff.address] 
            : [],
        'avatar': updatedStaff.avatar,
      };

      emit(state.copyWith(
        status: PersonalInfoStatus.saved,
        staff: updatedStaff,
        formValues: newValues,
      ));
    } catch (e) {
      emit(state.copyWith(
        status: PersonalInfoStatus.error,
        errorMessage: e.toString(),
      ));
    }
  }

  void _onAddressSelected(
    PersonalInfoAddressSelected event,
    Emitter<PersonalInfoState> emit,
  ) {
      // TODO: Implement Google Places logic if needed
  }

  /// With _onPhotoUploadRequested and _onSaveRequested removed or renamed,
  /// there are no errors pointing to them here.

  @override
  void dispose() {
    close();
  }
}
