import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fcs/pages/widgets/callbacks.dart';
import 'package:logging/logging.dart';

typedef ToObj = Function(Map<String, dynamic> data, String id);

/*
 * Pagination load data in page 
 */
class Paginator<T> {
  final log = Logger('Paginator');

  final int rowPerLoad;
  DocumentSnapshot prev;
  bool ended = false;
  bool isLoading = false;
  List<T> values = [];
  ToObj toObj;

  Query pageQuery;

  Paginator(this.pageQuery, {this.rowPerLoad = 20, this.toObj}) {
    _clearState();
  }

  void _clearState() {
    prev = null;
    ended = false;
    isLoading = false;
    values = [];
  }

  void close() {
    _clearState();
  }

  Future<void> refresh({CallBack onFinished}) async {
    _clearState();
    await load();
    if (onFinished != null) onFinished();
  }

  Future<bool> load({CallBack onFinished}) async {
    if (ended) return null;
    isLoading = true;
    Query _query =
        prev != null ? pageQuery.startAfterDocument(prev) : pageQuery;
    try {
      await _query
          .limit(rowPerLoad)
          .getDocuments(source: Source.server)
          .then((QuerySnapshot snapshot) {
        int count = snapshot.documents.length;
        ended = count < rowPerLoad;
        prev = count > 0 ? snapshot.documents[count - 1] : prev;
        snapshot.documents.forEach((e) {
          values.add(toObj(e.data, e.documentID));
        });
      });
    } catch (e) {
      log.warning("Error!! $e");
    } finally {
      isLoading = false;
      if (onFinished != null) onFinished();
    }
    return ended;
  }
}
