import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:real_estate_mobile/features/agents/data/agents_repository.dart';

class AgentNetworkState {
  final List<Map<String, dynamic>> pendingRequests;
  final List<Map<String, dynamic>> connections;
  final bool isLoading;
  final String? error;
  final Set<String> processingIds;

  const AgentNetworkState({
    this.pendingRequests = const [],
    this.connections = const [],
    this.isLoading = true,
    this.error,
    this.processingIds = const {},
  });

  AgentNetworkState copyWith({
    List<Map<String, dynamic>>? pendingRequests,
    List<Map<String, dynamic>>? connections,
    bool? isLoading,
    String? error,
    Set<String>? processingIds,
    bool clearError = false,
  }) {
    return AgentNetworkState(
      pendingRequests: pendingRequests ?? this.pendingRequests,
      connections: connections ?? this.connections,
      isLoading: isLoading ?? this.isLoading,
      error: clearError ? null : (error ?? this.error),
      processingIds: processingIds ?? this.processingIds,
    );
  }
}

class AgentNetworkNotifier extends StateNotifier<AgentNetworkState> {
  final AgentsRepository _repo;

  AgentNetworkNotifier(this._repo) : super(const AgentNetworkState()) {
    loadData();
  }

  Future<void> loadData() async {
    state = state.copyWith(isLoading: true, clearError: true);
    try {
      final results = await Future.wait([
        _repo.getReceivedRequests('PENDING'),
        _repo.getReceivedRequests('ACCEPTED'),
      ]);
      state = state.copyWith(
        pendingRequests: results[0],
        connections: results[1],
        isLoading: false,
      );
    } catch (e) {
      state = state.copyWith(
        isLoading: false,
        error: 'Failed to load network data',
      );
    }
  }

  Future<void> acceptRequest(String requestId) async {
    if (state.processingIds.contains(requestId)) return;
    state = state.copyWith(
      processingIds: {...state.processingIds, requestId},
    );

    final success = await _repo.respondToRequest(requestId, 'ACCEPTED');
    if (success) {
      // Move from pending to connections
      final request = state.pendingRequests.firstWhere(
        (r) => r['id'] == requestId,
        orElse: () => <String, dynamic>{},
      );
      state = state.copyWith(
        pendingRequests:
            state.pendingRequests.where((r) => r['id'] != requestId).toList(),
        connections: request.isNotEmpty
            ? [request, ...state.connections]
            : state.connections,
        processingIds: state.processingIds
            .where((id) => id != requestId)
            .toSet(),
      );
    } else {
      state = state.copyWith(
        processingIds: state.processingIds
            .where((id) => id != requestId)
            .toSet(),
      );
    }
  }

  Future<void> rejectRequest(String requestId) async {
    if (state.processingIds.contains(requestId)) return;
    state = state.copyWith(
      processingIds: {...state.processingIds, requestId},
    );

    final success = await _repo.respondToRequest(requestId, 'REJECTED');
    if (success) {
      state = state.copyWith(
        pendingRequests:
            state.pendingRequests.where((r) => r['id'] != requestId).toList(),
        processingIds: state.processingIds
            .where((id) => id != requestId)
            .toSet(),
      );
    } else {
      state = state.copyWith(
        processingIds: state.processingIds
            .where((id) => id != requestId)
            .toSet(),
      );
    }
  }
}

final agentNetworkProvider =
    StateNotifierProvider.autoDispose<AgentNetworkNotifier, AgentNetworkState>(
  (ref) => AgentNetworkNotifier(AgentsRepository()),
);
