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<AgentProfile> agents;
  final List<AgentType> agentTypes;
  final List<FilterableField> filterFields;
  final bool isLoading;
  final bool isLoadingMore;
  final String? error;
  final String searchQuery;
  final String? selectedAgentTypeId;
  final int currentPage;
  final int totalPages;
  final Map<String, List<String>> 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<AgentProfile>? agents,
    List<AgentType>? agentTypes,
    List<FilterableField>? filterFields,
    bool? isLoading,
    bool? isLoadingMore,
    String? error,
    String? searchQuery,
    String? selectedAgentTypeId,
    bool clearAgentTypeId = false,
    int? currentPage,
    int? totalPages,
    Map<String, List<String>>? 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<SearchAgentsState> {
  final AgentsRepository _repository;

  SearchAgentsNotifier(this._repository)
      : super(const SearchAgentsState(isLoading: true)) {
    _init();
  }

  Future<void> _init() async {
    try {
      final results = await Future.wait([
        _repository.getAgentTypes(),
        _repository.getFilterableFields(),
      ]);
      if (!mounted) return;
      state = state.copyWith(
        agentTypes: results[0] as List<AgentType>,
        filterFields: results[1] as List<FilterableField>,
      );
      await _fetchAgents(page: 1);
    } catch (e) {
      if (!mounted) return;
      state = state.copyWith(isLoading: false, error: e.toString());
    }
  }

  Future<void> _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<String, List<String>> 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<void> refresh() async {
    state = state.copyWith(isLoading: true, currentPage: 1);
    await _fetchAgents(page: 1);
  }
}

final searchAgentsProvider =
    StateNotifierProvider.autoDispose<SearchAgentsNotifier, SearchAgentsState>(
        (ref) {
  final repository = ref.watch(agentsRepositoryProvider);
  return SearchAgentsNotifier(repository);
});
