import 'dart:collection';

import 'package:flutter/foundation.dart';
import 'package:result_monad/result_monad.dart';

import '../friendica_client/friendica_client.dart';
import '../friendica_client/paged_response.dart';
import '../friendica_client/paging_data.dart';
import '../models/auth/profile.dart';
import '../models/exec_error.dart';
import '../models/follow_request.dart';

class FollowRequestsManager extends ChangeNotifier {
  static const maxIterations = 20;
  final Profile profile;
  final _requests = <String, FollowRequest>{};

  FollowRequestsManager(this.profile);

  List<FollowRequest> get requests => UnmodifiableListView(_requests.values);

  void clear() {
    _requests.clear();
  }

  Result<FollowRequest, ExecError> getByUserId(String id) {
    final request = _requests[id];
    return request != null
        ? Result.ok(request)
        : buildErrorResult(
            type: ErrorType.notFound,
            message: 'Request for $id not found',
          );
  }

  Future<void> update() async {
    var result = await _processPage(PagingData());
    var count = 0;
    final updatedRequests = <FollowRequest>{};
    while (result.isSuccess &&
        result.value.hasMorePages &&
        count < maxIterations) {
      result
          .andThenSuccess((requests) => updatedRequests.addAll(requests.data));
      result = await _processPage(result.value.next);
      count++;
    }

    _requests.clear();
    for (final r in updatedRequests) {
      _requests[r.connection.id] = r;
    }
    notifyListeners();
  }

  FutureResult<PagedResponse<List<FollowRequest>>, ExecError> _processPage(
      PagingData? page) async {
    if (page == null) {
      return buildErrorResult(type: ErrorType.rangeError);
    }
    final result = await RelationshipsClient(profile).getFollowRequests(page);

    return result;
  }
}
