import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
import 'package:syncrow_web/pages/space_tree/model/pagination_model.dart';
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
import 'package:syncrow_web/services/space_mana_api.dart';
part 'space_tree_dropdown_event.dart';
part 'space_tree_dropdown_state.dart';

class SpaceTreeDropdownBloc
    extends Bloc<SpaceTreeDropdownEvent, SpaceTreeDropdownState> {
  SpaceTreeDropdownBloc(String? initialId)
      : super(SpaceTreeDropdownState(selectedSpaceId: initialId)) {
    on<SpaceTreeDropdownSelectEvent>(_onSelect);
    on<SpaceTreeDropdownResetEvent>(_onReset);
    on<FetchSpacesEvent>(_fetchSpaces);
    on<SearchQueryEvent>(_onSearch);
    on<PaginationEvent>(_onPagination);
    on<DebouncedSearchEvent>(_onDebouncedSearch);
  }
  Timer? _debounceTimer;

  void _onSelect(
    SpaceTreeDropdownSelectEvent event,
    Emitter<SpaceTreeDropdownState> emit,
  ) {
    final exists = state.communities.any((c) => c.uuid == event.spaceId);

    if (!exists) {
      final community = state.filteredCommunities.firstWhere(
        (c) => c.uuid == event.spaceId,
        orElse: () => CommunityModel(
            uuid: event.spaceId!,
            name: 'Loading...',
            createdAt: DateTime.now(),
            updatedAt: DateTime.now(),
            spaces: [],
            description: ''),
      );

      emit(state.copyWith(
        selectedSpaceId: event.spaceId,
        communities: [...state.communities, community],
      ));
    } else {
      emit(state.copyWith(selectedSpaceId: event.spaceId));
    }
  }

  void _onReset(
    SpaceTreeDropdownResetEvent event,
    Emitter<SpaceTreeDropdownState> emit,
  ) {
    emit(state.copyWith(selectedSpaceId: event.initialId));
  }

  Future<void> _fetchSpaces(
    FetchSpacesEvent event,
    Emitter<SpaceTreeDropdownState> emit,
  ) async {
    if (state.status != SpaceTreeDropdownStatus.initial) return;
    emit(state.copyWith(status: SpaceTreeDropdownStatus.loading));
    try {
      final projectUuid = await ProjectManager.getProjectUUID() ?? '';
      final paginationModel = await CommunitySpaceManagementApi()
          .fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1);

      emit(state.copyWith(
        status: SpaceTreeDropdownStatus.success,
        communities: paginationModel.communities,
        filteredCommunities: paginationModel.communities,
        paginationModel: paginationModel,
      ));
    } catch (e) {
      emit(state.copyWith(
        status: SpaceTreeDropdownStatus.failure,
        errorMessage: 'Error loading communities: $e',
      ));
    }
  }

  void _onSearch(
    SearchQueryEvent event,
    Emitter<SpaceTreeDropdownState> emit,
  ) {
    _debounceTimer?.cancel();
    _debounceTimer = Timer(const Duration(seconds: 1), () {
      add(DebouncedSearchEvent(event.searchQuery));
    });
  }

  Future<void> _onDebouncedSearch(
    DebouncedSearchEvent event,
    Emitter<SpaceTreeDropdownState> emit,
  ) async {
    emit(state.copyWith(isSearching: true));

    try {
      final projectUuid = await ProjectManager.getProjectUUID() ?? '';
      final paginationModel =
          await CommunitySpaceManagementApi().fetchCommunitiesAndSpaces(
        projectId: projectUuid,
        page: 1,
        search: event.searchQuery,
      );

      emit(state.copyWith(
        filteredCommunities: paginationModel.communities,
        isSearching: false,
        searchQuery: event.searchQuery,
        paginationModel: paginationModel,
      ));
    } catch (e) {
      emit(state.copyWith(
        isSearching: false,
        errorMessage: 'Error searching communities: $e',
      ));
    }
  }

  @override
  Future<void> close() {
    _debounceTimer?.cancel();
    return super.close();
  }

  Future<void> _onPagination(
    PaginationEvent event,
    Emitter<SpaceTreeDropdownState> emit,
  ) async {
    if (state.paginationIsLoading || state.paginationModel?.hasNext != true) {
      return;
    }

    emit(state.copyWith(paginationIsLoading: true));

    try {
      final nextPage = state.paginationModel!.pageNum;
      final projectUuid = await ProjectManager.getProjectUUID() ?? '';
      final newPagination = await CommunitySpaceManagementApi()
          .fetchCommunitiesAndSpaces(projectId: projectUuid, page: nextPage);

      final combinedCommunities = [
        ...state.communities,
        ...newPagination.communities
      ];
      List<CommunityModel> filteredCommunities;
      if (state.searchQuery.isNotEmpty) {
        final query = state.searchQuery.toLowerCase();
        filteredCommunities = combinedCommunities.where((community) {
          return community.name.toLowerCase().contains(query);
        }).toList();
      } else {
        filteredCommunities = combinedCommunities;
      }

      emit(state.copyWith(
        communities: combinedCommunities,
        filteredCommunities: filteredCommunities,
        paginationModel: newPagination,
        paginationIsLoading: false,
      ));
    } catch (e) {
      emit(state.copyWith(
        paginationIsLoading: false,
        errorMessage: 'Error loading more communities: $e',
      ));
    }
  }
}
