import 'package:comunic/lists/notifications_list.dart';
import 'package:comunic/models/api_request.dart';
import 'package:comunic/models/count_unread_notifications.dart';
import 'package:comunic/models/notification.dart';

/// Notifications helper
///
/// @author Pierre HUBERT

const _NotificationElementTypeAPImapping = {
  "user_page": NotificationElementType.USER_PAGE,
  "group_page": NotificationElementType.GROUP_PAGE,
  "conversation": NotificationElementType.CONVERSATION,
  "conversation_message": NotificationElementType.CONVERSATION_MESSAGE,
  "post": NotificationElementType.POST,
  "post_text": NotificationElementType.POST_TEXT,
  "post_img": NotificationElementType.POST_IMAGE,
  "post_youtube": NotificationElementType.POST_YOUTUBE,
  "post_movie": NotificationElementType.POST_MOVIE,
  "post_weblink": NotificationElementType.POST_WEBLINK,
  "post_pdf": NotificationElementType.POST_PDF,
  "post_timer": NotificationElementType.POST_TIMER,
  "post_survey": NotificationElementType.POST_SURVEY,
  "comment": NotificationElementType.COMMENT,
  "friend_request": NotificationElementType.FRIENDSHIP_REQUEST,
  "group_membership": NotificationElementType.GROUP_MEMBERSHIP,
};

const _NotificationsTypeAPImapping = {
  "comment_created": NotificationType.COMMENT_CREATED,
  "sent_friend_request": NotificationType.SENT_FRIEND_REQUEST,
  "accepted_friend_request": NotificationType.ACCEPTED_FRIEND_REQUEST,
  "rejected_friend_request": NotificationType.REJECTED_FRIEND_REQUEST,
  "elem_created": NotificationType.ELEM_CREATED,
  "elem_updated": NotificationType.ELEM_UPDATED,
  "sent_group_membership_invitation":
      NotificationType.SENT_GROUP_MEMBERSHIP_INVITATION,
  "accepted_group_membership_invitation":
      NotificationType.ACCEPTED_GROUP_MEMBERSHIP_INVITATION,
  "rejected_group_membership_invitation":
      NotificationType.REJECTED_GROUP_MEMBERSHIP_INVITATION,
  "sent_group_membership_request":
      NotificationType.SENT_GROUP_MEMBERSHIP_REQUEST,
  "accepted_group_membership_request":
      NotificationType.ACCEPTED_GROUP_MEMBERSHIP_REQUEST,
  "rejected_group_membership_request":
      NotificationType.REJECTED_GROUP_MEMBERSHIP_REQUEST,
};

class NotificationsHelper {
  /// Get the number of unread notifications
  ///
  /// This method throws in case of error
  Future<CountUnreadNotifications> countUnread() async {
    final response =
        await APIRequest(uri: "notifications/count_all_news", needLogin: true)
            .exec();

    final content = response.assertOk().getObject();

    return CountUnreadNotifications(
      notifications: content["notifications"],
      conversations: content["conversations"],
    );
  }

  /// Get the list of unread notifications of the user
  Future<NotificationsList> getUnread() async {
    final response =
        await APIRequest(uri: "notifications/get_list_unread", needLogin: true)
            .exec();

    if (!response.isOK)
      throw Exception("Could not get the list of notifications!");

    // Parse the list of notifications
    return NotificationsList()
      ..addAll(response
          .getArray()
          .map((f) => Notification(
              id: f["id"],
              timeCreate: f["time_create"],
              seen: f["seen"],
              fromUser: f["from_user_id"],
              onElemId: f["on_elem_id"],
              onElemType: _NotificationElementTypeAPImapping[f["on_elem_type"]],
              type: _NotificationsTypeAPImapping[f["type"]],
              fromContainerId: f["from_container_id"],
              fromContainerType: f["from_container_type"] == ""
                  ? null
                  : _NotificationElementTypeAPImapping[
                      f["from_container_type"]]))
          .toList());
  }

  /// Mark a notification as seen
  Future<bool> markSeen(Notification n) async => (await APIRequest(
        uri: "notifications/mark_seen",
        needLogin: true,
        args: {
          "notifID": n.id.toString(),
        },
      ).exec())
          .isOK;

  /// Delete all unread notifications
  Future<bool> deleteAllNotifications() async =>
      (await APIRequest(uri: "notifications/delete_all", needLogin: true)
              .exec())
          .isOK;
}