import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/community_model.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/params/load_communities_param.dart';
import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/services/communities_service.dart';
import 'package:syncrow_web/services/api/api_exception.dart';

part 'communities_event.dart';
part 'communities_state.dart';

class CommunitiesBloc extends Bloc<CommunitiesEvent, CommunitiesState> {
  CommunitiesBloc({
    required CommunitiesService communitiesService,
  })  : _communitiesService = communitiesService,
        super(const CommunitiesState()) {
    on<LoadCommunities>(_onLoadCommunities);
    on<LoadMoreCommunities>(_onLoadMoreCommunities);
    on<InsertCommunity>(_onInsertCommunity);
  }

  final CommunitiesService _communitiesService;

  Future<void> _onLoadCommunities(
    LoadCommunities event,
    Emitter<CommunitiesState> emit,
  ) async {
    try {
      emit(
        state.copyWith(status: CommunitiesStatus.loading),
      );

      final paginationResponse = await _communitiesService.getCommunity(
        event.param,
      );

      emit(
        CommunitiesState(
          status: CommunitiesStatus.success,
          communities: paginationResponse.data,
          hasNext: paginationResponse.hasNext,
          currentPage: paginationResponse.page,
          searchQuery: event.param.search,
          isLoadingMore: false,
        ),
      );
    } on APIException catch (e) {
      _onApiException(e, emit);
    } catch (e) {
      _onError(e, emit);
    }
  }

  Future<void> _onLoadMoreCommunities(
    LoadMoreCommunities event,
    Emitter<CommunitiesState> emit,
  ) async {
    if (!state.hasNext || state.isLoadingMore) return;

    try {
      emit(state.copyWith(isLoadingMore: true));

      final param = LoadCommunitiesParam(
        page: state.currentPage + 1,
        search: state.searchQuery,
      );

      final paginationResponse = await _communitiesService.getCommunity(param);

      final updatedCommunities = List<CommunityModel>.from(state.communities)
        ..addAll(paginationResponse.data);

      emit(
        state.copyWith(
          status: CommunitiesStatus.success,
          communities: updatedCommunities,
          hasNext: paginationResponse.hasNext,
          currentPage: paginationResponse.page,
          isLoadingMore: false,
        ),
      );
    } on APIException catch (e) {
      _onApiException(e, emit);
    } catch (e) {
      _onError(e, emit);
    }
  }

  void _onApiException(
    APIException e,
    Emitter<CommunitiesState> emit,
  ) {
    emit(
      state.copyWith(
        status: CommunitiesStatus.failure,
        isLoadingMore: false,
        errorMessage: e.message,
      ),
    );
  }

  void _onError(Object e, Emitter<CommunitiesState> emit) {
    emit(
      state.copyWith(
        status: CommunitiesStatus.failure,
        isLoadingMore: false,
        errorMessage: e.toString(),
      ),
    );
  }

  void _onInsertCommunity(
    InsertCommunity event,
    Emitter<CommunitiesState> emit,
  ) {
    emit(state.copyWith(communities: [event.community, ...state.communities]));
  }
}
