namespace Hims.Domain.Helpers
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using RestSharp;

    using Hims.Shared.EntityModels;
    using Hims.Shared.Library.Enums;

    /// <summary>
    /// The Push Notification Factory interface.
    /// </summary>
    public interface IPushNotificationHelper
    {
        /// <summary> The send async.</summary>
        /// <param name="title"> The title.</param>
        /// <param name="body"> The body.</param>
        /// <param name="message"> The message.</param>
        /// <param name="deviceTokensForAndroid"> The device tokens for android.</param>
        /// <param name="deviceTokensForIOS"> The device tokens for ios.</param>
        /// <param name="type"> The type.</param>
        /// <returns>The <see cref="Task"/>.</returns>
        Task<IRestResponse> SendAsync(
            string title,
            string body,
            string message,
            IEnumerable<string> deviceTokensForAndroid,
            IEnumerable<string> deviceTokensForIOS,
            NotificationType? type);

        /// <summary> The send async.</summary>
        /// <param name="title"> The title.</param>
        /// <param name="body"> The body.</param>
        /// <param name="message"> The message.</param>
        /// <param name="deviceTokensForAndroid"> The device tokens for android.</param>
        /// <param name="deviceTokensForIOS"> The device tokens for ios.</param>
        /// <param name="doctorName"> The doctor name.</param>
        /// <param name="date"> The date.</param>
        /// <param name="prevDate"> The prevous date.</param>
        /// <param name="type"> The type.</param>
        /// <returns>The <see cref="Task"/>.</returns>
        Task<IRestResponse> SendAltAsync(
            string title,
            string body,
            string message,
            IEnumerable<string> deviceTokensForAndroid,
            IEnumerable<string> deviceTokensForIOS,
            string doctorName,
            string date,
            string prevDate = null,
            NotificationType? type = null);

        /// <summary>
        /// The intimate async.
        /// </summary>
        /// <param name="title">
        /// The title.
        /// </param>
        /// <param name="body">
        /// The body.
        /// </param>
        /// <param name="message">
        /// The message.
        /// </param>
        /// <param name="deviceTokensForAndroid">
        /// The device tokens for android.
        /// </param>
        /// <param name="deviceTokensForIOS">
        /// The device tokens for ios.
        /// </param>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="type"> 
        /// The type.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IRestResponse> IntimateAsync(
            string title,
            string body,
            string message,
            IEnumerable<string> deviceTokensForAndroid,
            IEnumerable<string> deviceTokensForIOS,
            string id,
            NotificationType? type = null);

        /// <summary>
        /// The intimate async.
        /// </summary>
        /// <param name="title">
        /// The title.
        /// </param>
        /// <param name="body">
        /// The body.
        /// </param>
        /// <param name="message">
        /// The message.
        /// </param>
        /// <param name="deviceTokensForAndroid">
        /// The device tokens for android.
        /// </param>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="type">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IRestResponse> IntimateAndroidAsync(
            string title,
            string body,
            string message,
            IEnumerable<string> deviceTokensForAndroid,
            string id,
            NotificationType? type = null);

        /// <summary>
        /// The intimate async.
        /// </summary>
        /// <param name="title">
        /// The title.
        /// </param>
        /// <param name="body">
        /// The body.
        /// </param>
        /// <param name="message">
        /// The message.
        /// </param>
        /// <param name="deviceTokensForIOS">
        /// The device tokens for ios.
        /// </param>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="type">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IRestResponse> IntimateIOSAsync(
            string title,
            string body,
            string message,
            IEnumerable<string> deviceTokensForIOS,
            string id,
            NotificationType? type = null);

        /// <summary> The send single async.</summary>
        /// <param name="title"> The title.</param>
        /// <param name="body"> The body.</param>
        /// <param name="message"> The message.</param>
        /// <param name="deviceTokens"> The device tokens.</param>
        /// <param name="deviceType"> The device type.</param>
        /// <param name="type"> The type.</param>
        /// <returns>The <see cref="Task"/>.</returns>
        Task<IRestResponse> SendSingleAsync(string title, string body, string message, string deviceTokens, int deviceType, NotificationType? type = null);

        /// <summary>
        /// The send video call notifications async.
        /// </summary>
        /// <param name="title">
        /// The title.
        /// </param>
        /// <param name="body">
        /// The body.
        /// </param>
        /// <param name="message">
        /// The message.
        /// </param>
        /// <param name="deviceTokens">
        /// The device tokens.
        /// </param>
        /// <param name="doctorName">
        /// The doctor name.
        /// </param>
        /// <param name="doctorEmail">
        /// The doctor email.
        /// </param>
        /// <param name="deviceId">
        /// The device id.
        /// </param>
        /// <param name="type">
        /// The type.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IRestResponse> SendVideoCallNotificationsAsync(string title, string body, string message, string deviceTokens, string doctorName, string doctorEmail, string deviceId, NotificationType? type = null);

        /// <summary> The send chat notifications async.</summary>
        /// <param name="title"> The title.</param>
        /// <param name="body"> The body.</param>
        /// <param name="payload"> The payload.</param>
        /// <param name="deviceTokensAndroid"> The device tokens android.</param>
        /// <param name="deviceTokensIOS"> The device tokens ios.</param>
        /// <param name="type">
        /// The type.
        /// </param>
        /// <returns>The <see cref="Task"/>.</returns>
        Task<IRestResponse> SendChatNotificationsAsync(string title, string body, string payload, IEnumerable<string> deviceTokensAndroid, IEnumerable<string> deviceTokensIOS, NotificationType? type = null);

        /// <summary>The send video call notifications to all devices async.</summary>
        /// <param name="title">The title.</param>
        /// <param name="body">The body.</param>
        /// <param name="message">The message.</param>
        /// <param name="deviceTokens">The device tokens.</param>
        /// <param name="doctorName">The doctor name.</param>
        /// <param name="doctorEmail">The doctor email.</param>
        /// <param name="deviceId">The device id.</param>
        /// <param name="type">
        /// The type.
        /// </param>
        /// <returns>The <see cref="Task"/>.</returns>
        Task<IRestResponse> SendVideoCallNotificationsToAllDevicesAsync(
            string title,
            string body,
            string message,
            IEnumerable<string> deviceTokens,
            string doctorName,
            string doctorEmail,
            string deviceId,
            NotificationType? type = null);

        /// <summary>
        /// The telemedicine call notification.
        /// </summary>
        /// <param name="source">
        /// The source.
        /// </param>
        /// <param name="message">
        /// The message.
        /// </param>
        /// <param name="deviceTokens">
        /// The device tokens.
        /// </param>
        /// <param name="doctorName">
        /// The doctor name.
        /// </param>
        /// <param name="telemedicineId">
        /// The telemedicine id.
        /// </param>
        /// <param name="type">
        /// The type.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IRestResponse> TelemedicineCallNotification(
            string source,
            string message,
            List<string> deviceTokens,
            string doctorName,
            int telemedicineId,
            NotificationType? type = null);

        /// <summary>
        /// Customs the notification.
        /// </summary>
        /// <param name="payload">The payload.</param>
        /// <returns></returns>
        Task<IRestResponse> CustomNotification(string payload);

        /// <summary>
        /// The telemedicine call notification.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        /// <param name="type">
        /// The model.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IRestResponse> TelemedicineCallNotification(NotificationIntimateModel model, NotificationType? type = null);

        /// <summary>
        /// Tests the notification.
        /// </summary>
        /// <param name="deviceToken">The device token.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        Task<IRestResponse> TestNotification(string deviceToken, NotificationType? type = null);
    }
}