import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart';

import '../constants.dart';

DateFormat dayFormat = DateFormat("MMM dd yyyy");
DateFormat timeFormat = DateFormat("HH:mm");
final DateFormat dateFormat = DateFormat("d MMM yyyy");

class User {
  String id;
  String name;
  String phoneNumber;
  String status;
  String fcsID;
  DateTime lastMessageTime;
  String lastMessage;
  int userUnseenCount;
  int fcsUnseenCount;
  String preferCurrency;

  String get initial => name != null && name != "" ? name.substring(0, 1) : "?";

  String get getLastMessage {
    var msg = lastMessage ?? "Say hi to $name";
    if (msg.length > 30) return msg.substring(0, 30) + " ... ";
    return msg;
  }

  String get getLastMessageTime {
    if (lastMessageTime == null) return "";
    DateTime today = DateTime.now();
    if (lastMessageTime.year == today.year &&
        lastMessageTime.month == today.month &&
        lastMessageTime.day == today.day) {
      return timeFormat.format(lastMessageTime);
    } else {
      return dateFormat.format(lastMessageTime);
    }
  }

  String get getUserUnseenCount => userUnseenCount != null
      ? userUnseenCount > 100 ? "99+" : userUnseenCount.toString()
      : "0";
  String get getFcsUnseenCount => fcsUnseenCount != null
      ? fcsUnseenCount > 100 ? "99+" : fcsUnseenCount.toString()
      : "0";

  List<String> privileges = [];

  String get phone => phoneNumber != null && phoneNumber.startsWith("959")
      ? "0${phoneNumber.substring(2)}"
      : phoneNumber;
  bool get joined => status != null && status == user_joined_status;
  bool get invited => status != null && status == user_invited_status;
  bool get requested => status != null && status == user_requested_status;
  bool get disabled => status != null && status == user_disabled_status;

  String get share => "Your phone number:$phoneNumber";
  User(
      {this.id,
      this.name,
      this.phoneNumber,
      this.fcsID,
      this.status,
      this.privileges,
      this.lastMessage,
      this.lastMessageTime,
      this.userUnseenCount,
      this.fcsUnseenCount,
      this.preferCurrency});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'],
      name: json['user_name'],
      fcsID: json['fcs_id'],
      phoneNumber: json['phone_number'],
      status: json['status'],
      lastMessage: json['last_message'],
    );
  }

  Map<String, dynamic> toJson() => {
        'id': id,
        'user_name': name,
        'phone_number': phoneNumber,
      };

  Map<String, dynamic> toMap() {
    return {
      'user_name': name,
      'phone_number': phoneNumber,
    };
  }

  factory User.fromMap(Map<String, dynamic> map, String docID) {
    var _date = (map['message_time'] as Timestamp);

    List<String> _privileges =
        map['privileges'] == null ? [] : map['privileges'].cast<String>();

    return User(
        id: docID,
        name: map['user_name'],
        phoneNumber: map['phone_number'],
        status: map['status'],
        fcsID: map['fcs_id'],
        privileges: _privileges,
        lastMessage: map['last_message'],
        userUnseenCount: map['user_unseen_count'],
        fcsUnseenCount: map['fcs_unseen_count'],
        preferCurrency: map['preferred_currency'],
        lastMessageTime: _date == null ? null : _date.toDate());
  }

  bool diffPrivileges(User another) {
    another.privileges.sort((a, b) => a.compareTo(b));
    privileges.sort((a, b) => a.compareTo(b));
    return !listEquals(another.privileges, privileges);
  }

  bool isCustomer() {
    return privileges == null || privileges.length == 0;
  }

  bool hasSysAdmin() {
    return _has(privilege_sys_admin);
  }

  bool hasAdmin() {
    return _has(privilege_admin);
  }

  bool hasCustomers() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_customer);
  }

  bool hasFcsShipments() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_fcs_shipment);
  }

  bool hasStaffs() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_staff);
  }

  bool hasSupport() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_support);
  }

  bool hasPackages() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_package);
  }

  bool hasReceiving() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_receiving);
  }

  bool hasProcessing() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_processing);
  }

  bool hasDeliveries() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_delivery);
  }

  bool hasInvoices() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_invoice);
  }

  bool hasShipment() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_shipment);
  }

  bool hasCarton() {
    return hasSysAdmin() || hasAdmin() || _has(privilege_carton);
  }

  bool _has(String privilege) {
    return (privileges != null ? privileges.contains(privilege) : false);
  }

  @override
  String toString() {
    return 'User{id:$id, name: $name, phoneNumber: $phoneNumber,status:$status}';
  }
}
