import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fcs/data/services/services.dart';
import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/domain/vo/privilege.dart';
import 'package:fcs/helpers/firebase_helper.dart';
import 'package:fcs/pages/main/model/base_model.dart';
import 'package:logging/logging.dart';

class StaffModel extends BaseModel {
  final log = Logger('StaffModel');
  StreamSubscription<QuerySnapshot> listener;
  StreamSubscription<QuerySnapshot> privilegeListener;

  List<User> employees = [];
  List<Privilege> privileges = [];

  @override
  void privilegeChanged() {
    super.privilegeChanged();
    _loadPrivileges();
    _loadEmployees();
  }

  @override
  logout() async {
    if (listener != null) listener.cancel();
    if (privilegeListener != null) privilegeListener.cancel();
    employees = [];
    privileges = [];
  }

  Future<void> _loadEmployees() async {
    if (user == null || !user.hasStaffs()) return;

    try {
      if (listener != null) listener.cancel();

      listener = Firestore.instance
          .collection("/$user_collection")
          .where("is_employee", isEqualTo: true)
          .where("is_sys_admin", isEqualTo: false)
          .snapshots()
          .listen((QuerySnapshot snapshot) {
        employees.clear();
        employees = snapshot.documents.map((documentSnapshot) {
          var user =
              User.fromMap(documentSnapshot.data, documentSnapshot.documentID);
          return user;
        }).toList();
        notifyListeners();
      });
    } catch (e) {
      log.warning("Error!! $e");
    }
  }

  Future<void> _loadPrivileges() async {
    try {
      privilegeListener = Firestore.instance
          .collection("/$privilege_collection")
          .snapshots()
          .listen((QuerySnapshot snapshot) {
        privileges.clear();
        privileges = snapshot.documents.map((documentSnapshot) {
          var privilege = Privilege.fromMap(
              documentSnapshot.data, documentSnapshot.documentID);
          return privilege;
        }).toList();
        notifyListeners();
      });
    } catch (e) {
      log.warning("Error!! $e");
    }
  }

  Future<void> updatePrivileges(String userID, List<String> privileges) async {
    await request("/employee/privileges", "PUT",
        payload: {"id": userID, "privileges": privileges},
        token: await getToken());
  }

  Future<User> findUser(String phoneNumber) {
    return Services.instance.userService.findUser(phoneNumber);
  }

  Future<List<User>> getPickupEmployees() async {
    if (user == null || !user.hasShipment()) return [];
    return _getUsers(privilege_shipment);
  }

  Future<List<User>> _getUsers(String privilege) async {
    List<User> users = [];
    try {
      var snaps = await Firestore.instance
          .collection("/$user_collection")
          .where("is_employee", isEqualTo: true)
          .where("is_sys_admin", isEqualTo: false)
          .where("privileges", arrayContains: privilege)
          .getDocuments(source: Source.server);
      users = snaps.documents.map((documentSnapshot) {
        var user =
            User.fromMap(documentSnapshot.data, documentSnapshot.documentID);
        return user;
      }).toList();
    } catch (e) {
      log.warning("Error!! $e");
    }
    return users;
  }
}
