import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow_core/core.dart';
import '../../../domain/usecases/submit_profile_setup_usecase.dart';

import '../../../domain/usecases/search_cities_usecase.dart';

import 'profile_setup_event.dart';
import 'profile_setup_state.dart';

export 'profile_setup_event.dart';
export 'profile_setup_state.dart';

/// BLoC responsible for managing the profile setup state and logic.
class ProfileSetupBloc extends Bloc<ProfileSetupEvent, ProfileSetupState>
    with BlocErrorHandler<ProfileSetupState> {
  ProfileSetupBloc({
    required SubmitProfileSetup submitProfileSetup,
    required SearchCitiesUseCase searchCities,
  }) : _submitProfileSetup = submitProfileSetup,
       _searchCities = searchCities,
       super(const ProfileSetupState()) {
    on<ProfileSetupFullNameChanged>(_onFullNameChanged);
    on<ProfileSetupBioChanged>(_onBioChanged);
    on<ProfileSetupLocationsChanged>(_onLocationsChanged);
    on<ProfileSetupDistanceChanged>(_onDistanceChanged);
    on<ProfileSetupSkillsChanged>(_onSkillsChanged);
    on<ProfileSetupIndustriesChanged>(_onIndustriesChanged);
    on<ProfileSetupSubmitted>(_onSubmitted);
    on<ProfileSetupLocationQueryChanged>(_onLocationQueryChanged);
    on<ProfileSetupClearLocationSuggestions>(_onClearLocationSuggestions);
  }

  final SubmitProfileSetup _submitProfileSetup;
  final SearchCitiesUseCase _searchCities;

  /// Handles the [ProfileSetupFullNameChanged] event.
  void _onFullNameChanged(
    ProfileSetupFullNameChanged event,
    Emitter<ProfileSetupState> emit,
  ) {
    emit(state.copyWith(fullName: event.fullName));
  }

  /// Handles the [ProfileSetupBioChanged] event.
  void _onBioChanged(
    ProfileSetupBioChanged event,
    Emitter<ProfileSetupState> emit,
  ) {
    emit(state.copyWith(bio: event.bio));
  }

  /// Handles the [ProfileSetupLocationsChanged] event.
  void _onLocationsChanged(
    ProfileSetupLocationsChanged event,
    Emitter<ProfileSetupState> emit,
  ) {
    emit(state.copyWith(preferredLocations: event.locations));
  }

  /// Handles the [ProfileSetupDistanceChanged] event.
  void _onDistanceChanged(
    ProfileSetupDistanceChanged event,
    Emitter<ProfileSetupState> emit,
  ) {
    emit(state.copyWith(maxDistanceMiles: event.distance));
  }

  /// Handles the [ProfileSetupSkillsChanged] event.
  void _onSkillsChanged(
    ProfileSetupSkillsChanged event,
    Emitter<ProfileSetupState> emit,
  ) {
    emit(state.copyWith(skills: event.skills));
  }

  /// Handles the [ProfileSetupIndustriesChanged] event.
  void _onIndustriesChanged(
    ProfileSetupIndustriesChanged event,
    Emitter<ProfileSetupState> emit,
  ) {
    emit(state.copyWith(industries: event.industries));
  }

  /// Handles the [ProfileSetupSubmitted] event.
  Future<void> _onSubmitted(
    ProfileSetupSubmitted event,
    Emitter<ProfileSetupState> emit,
  ) async {
    emit(state.copyWith(status: ProfileSetupStatus.loading));

    await handleError(
      emit: emit,
      action: () async {
        await _submitProfileSetup(
          fullName: state.fullName,
          bio: state.bio.isEmpty ? null : state.bio,
          preferredLocations: state.preferredLocations,
          maxDistanceMiles: state.maxDistanceMiles,
          industries: state.industries,
          skills: state.skills,
        );

        emit(state.copyWith(status: ProfileSetupStatus.success));
      },
      onError: (String errorKey) => state.copyWith(
        status: ProfileSetupStatus.failure,
        errorMessage: errorKey,
      ),
    );
  }

  Future<void> _onLocationQueryChanged(
    ProfileSetupLocationQueryChanged event,
    Emitter<ProfileSetupState> emit,
  ) async {
    if (event.query.isEmpty) {
      emit(state.copyWith(locationSuggestions: []));
      return;
    }

    // For search, we might want to handle errors silently or distinctively
    // Using simple try-catch here as it's a search-as-you-type feature where error dialogs are intrusive
    try {
      final results = await _searchCities(event.query);
      emit(state.copyWith(locationSuggestions: results));
    } catch (e) {
      // Quietly fail or clear
      emit(state.copyWith(locationSuggestions: []));
    }
  }

  void _onClearLocationSuggestions(
    ProfileSetupClearLocationSuggestions event,
    Emitter<ProfileSetupState> emit,
  ) {
    emit(state.copyWith(locationSuggestions: []));
  }
}

