import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_core/core.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()) {
    on<PersonalInfoLoadRequested>(_onLoadRequested);
    on<PersonalInfoFieldUpdated>(_onFieldUpdated);
    on<PersonalInfoSaveRequested>(_onSaveRequested);
    on<PersonalInfoPhotoUploadRequested>(_onPhotoUploadRequested);
  }

  /// 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();
      emit(state.copyWith(
        status: PersonalInfoStatus.loaded,
        staff: staff,
      ));
    } catch (e) {
      emit(state.copyWith(
        status: PersonalInfoStatus.error,
        errorMessage: e.toString(),
      ));
    }
  }

  /// Handles updating a field value in the current staff profile.
  void _onFieldUpdated(
    PersonalInfoFieldUpdated event,
    Emitter<PersonalInfoState> emit,
  ) {
    if (state.staff == null) return;

    final Staff updatedStaff = _updateField(state.staff!, event.field, event.value);
    emit(state.copyWith(staff: updatedStaff));
  }

  /// Updates a specific field in the Staff entity.
  ///
  /// Returns a new Staff instance with the updated field.
  Staff _updateField(Staff staff, String field, String value) {
    // Note: Staff entity doesn't have a copyWith method or bio/languages/locations fields
    // These fields would need to be added to the Staff entity or handled differently
    // For now, we're just returning the same staff
    // TODO: Add support for bio, languages, preferred locations to Staff entity
    switch (field) {
      case 'phone':
        // Since Staff is immutable and doesn't have copyWith, we'd need to create a new instance
        return Staff(
          id: staff.id,
          authProviderId: staff.authProviderId,
          name: staff.name,
          email: staff.email,
          phone: value,
          status: staff.status,
          address: staff.address,
          avatar: staff.avatar,
        );
      case 'address':
        return Staff(
          id: staff.id,
          authProviderId: staff.authProviderId,
          name: staff.name,
          email: staff.email,
          phone: staff.phone,
          status: staff.status,
          address: value,
          avatar: staff.avatar,
        );
      default:
        return staff;
    }
  }

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

    emit(state.copyWith(status: PersonalInfoStatus.saving));
    try {
      final Staff updatedStaff = await _updatePersonalInfoUseCase(
        state.staff!,
      );
      emit(state.copyWith(
        status: PersonalInfoStatus.saved,
        staff: updatedStaff,
      ));
    } catch (e) {
      emit(state.copyWith(
        status: PersonalInfoStatus.error,
        errorMessage: e.toString(),
      ));
    }
  }

  /// Handles uploading a profile photo.
  Future<void> _onPhotoUploadRequested(
    PersonalInfoPhotoUploadRequested event,
    Emitter<PersonalInfoState> emit,
  ) async {
    if (state.staff == null) return;

    emit(state.copyWith(status: PersonalInfoStatus.uploadingPhoto));
    try {
      // TODO: Implement photo upload when repository method is available
      // final photoUrl = await _repository.uploadProfilePhoto(event.filePath);
      // final updatedStaff = Staff(...);
      // emit(state.copyWith(
      //   status: PersonalInfoStatus.loaded,
      //   staff: updatedStaff,
      // ));
      
      // For now, just return to loaded state
      emit(state.copyWith(status: PersonalInfoStatus.loaded));
    } catch (e) {
      emit(state.copyWith(
        status: PersonalInfoStatus.error,
        errorMessage: e.toString(),
      ));
    }
  }

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