import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:real_estate_mobile/features/agents/data/agents_repository.dart'; import 'package:real_estate_mobile/features/agents/data/models/agent_profile.dart'; import 'package:real_estate_mobile/features/agents/data/models/agent_type.dart'; import 'package:real_estate_mobile/features/agents/data/models/filterable_field.dart'; import 'package:real_estate_mobile/features/agents/presentation/providers/agents_provider.dart'; class SearchAgentsState { final List agents; final List agentTypes; final List filterFields; final bool isLoading; final bool isLoadingMore; final String? error; final String searchQuery; final String? selectedAgentTypeId; final int currentPage; final int totalPages; final Map> activeFilters; const SearchAgentsState({ this.agents = const [], this.agentTypes = const [], this.filterFields = const [], this.isLoading = false, this.isLoadingMore = false, this.error, this.searchQuery = '', this.selectedAgentTypeId, this.currentPage = 1, this.totalPages = 1, this.activeFilters = const {}, }); bool get hasMore => currentPage < totalPages; SearchAgentsState copyWith({ List? agents, List? agentTypes, List? filterFields, bool? isLoading, bool? isLoadingMore, String? error, String? searchQuery, String? selectedAgentTypeId, bool clearAgentTypeId = false, int? currentPage, int? totalPages, Map>? activeFilters, }) { return SearchAgentsState( agents: agents ?? this.agents, agentTypes: agentTypes ?? this.agentTypes, filterFields: filterFields ?? this.filterFields, isLoading: isLoading ?? this.isLoading, isLoadingMore: isLoadingMore ?? this.isLoadingMore, error: error, searchQuery: searchQuery ?? this.searchQuery, selectedAgentTypeId: clearAgentTypeId ? null : (selectedAgentTypeId ?? this.selectedAgentTypeId), currentPage: currentPage ?? this.currentPage, totalPages: totalPages ?? this.totalPages, activeFilters: activeFilters ?? this.activeFilters, ); } } class SearchAgentsNotifier extends StateNotifier { final AgentsRepository _repository; SearchAgentsNotifier(this._repository) : super(const SearchAgentsState(isLoading: true)) { _init(); } Future _init() async { try { final results = await Future.wait([ _repository.getAgentTypes(), _repository.getFilterableFields(), ]); if (!mounted) return; state = state.copyWith( agentTypes: results[0] as List, filterFields: results[1] as List, ); await _fetchAgents(page: 1); } catch (e) { if (!mounted) return; state = state.copyWith(isLoading: false, error: e.toString()); } } Future _fetchAgents({required int page, bool append = false}) async { try { final response = await _repository.searchAgents( search: state.searchQuery.isNotEmpty ? state.searchQuery : null, agentTypeId: state.selectedAgentTypeId, page: page, limit: 10, filters: state.activeFilters.isNotEmpty ? state.activeFilters : null, ); if (!mounted) return; state = state.copyWith( agents: append ? [...state.agents, ...response.data] : response.data, currentPage: response.page, totalPages: response.totalPages, isLoading: false, isLoadingMore: false, ); } catch (e) { if (!mounted) return; state = state.copyWith( isLoading: false, isLoadingMore: false, error: e.toString(), ); } } void search(String query) { state = state.copyWith( searchQuery: query, isLoading: true, currentPage: 1, ); _fetchAgents(page: 1); } void filterByAgentType(String? agentTypeId) { state = state.copyWith( selectedAgentTypeId: agentTypeId, clearAgentTypeId: agentTypeId == null, isLoading: true, currentPage: 1, ); _fetchAgents(page: 1); } void applyFilters(Map> filters) { state = state.copyWith( activeFilters: filters, isLoading: true, currentPage: 1, ); _fetchAgents(page: 1); } void clearFilters() { state = state.copyWith( activeFilters: const {}, isLoading: true, currentPage: 1, ); _fetchAgents(page: 1); } void loadMore() { if (state.isLoadingMore || !state.hasMore) return; state = state.copyWith(isLoadingMore: true); _fetchAgents(page: state.currentPage + 1, append: true); } Future refresh() async { state = state.copyWith(isLoading: true, currentPage: 1); await _fetchAgents(page: 1); } } final searchAgentsProvider = StateNotifierProvider.autoDispose( (ref) { final repository = ref.watch(agentsRepositoryProvider); return SearchAgentsNotifier(repository); });