namespace Hims.Api.Helper
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;

    using Hims.Domain.Helpers;
    using Hims.Domain.Services;
    using Hims.Shared.EntityModels;
    using Hims.Shared.Library.Enums;

    /// <summary>
    /// The notification helper.
    /// </summary>
    public static class NotificationHelper
    {
        /// <summary>
        /// The notification helper.
        /// </summary>
        /// <param name="providerOrPatientId">
        /// The provider Or Patient Id.
        /// </param>
        /// <param name="role">
        /// The role.
        /// </param>
        /// <param name="intimate">
        /// The intimate.
        /// </param>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="accountSessionServices">
        /// The account Session Services.
        /// </param>
        /// <param name="pushNotificationHelper">
        /// The push Notification Helper.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        public static async Task<bool> Notification(
            int providerOrPatientId,
            Roles role,
            NotificationIntimate intimate,
            string id,
            IAccountSessionService accountSessionServices,
            IPushNotificationHelper pushNotificationHelper)
        {
            var message = string.Empty;
            var type = string.Empty;

            switch (intimate)
            {
                case NotificationIntimate.PrescriptionAdded:
                    message = "Doctor has added prescription";
                    type = "UpdateOnPrescription";
                    break;
                case NotificationIntimate.PrescriptionUpdated:
                    message = "Doctor has updated prescription";
                    type = "UpdateOnPrescription";
                    break;
                case NotificationIntimate.FullTranscriptionAdded:
                    message = "Doctor has added full transcription";
                    type = "UpdateOnFullTranscription";
                    break;
                case NotificationIntimate.FullTranscriptionUpdated:
                    message = "Doctor has updated full transcription";
                    type = "UpdateOnFullTranscription";
                    break;
                case NotificationIntimate.DoctorUploadedDocuments:
                    message = "Doctor has uploaded document(s)";
                    type = "UpdateOnUploadedDocuments";
                    break;
                case NotificationIntimate.DoctorEditedDocuments:
                    message = "Doctor has edited document(s)";
                    type = "UpdateOnEditedDocuments";
                    break;
                case NotificationIntimate.PatientUploadedDocuments:
                    message = "Patient has uploaded document(s)";
                    type = "UpdateOnUploadedDocuments";
                    break;
                case NotificationIntimate.PatientEditedDocuments:
                    message = "Patient has edited document(s)";
                    type = "UpdateOnEditedDocuments";
                    break;
            }

            if (role == Roles.Provider)
            {
                var accountSessionProviderModel = await accountSessionServices.FetchDeviceTokenAsync(providerOrPatientId, Roles.Provider);
                var sessionProviderModel = accountSessionProviderModel as AccountSessionModel[] ?? accountSessionProviderModel.ToArray();
                if (sessionProviderModel.Any())
                {
                    var deviceTokenForProviderAndroid = sessionProviderModel.Where(d => d.DeviceType == 2).Select(s => s.DeviceToken).ToList();
                    var deviceTokenForProviderIOS = sessionProviderModel.Where(d => d.DeviceType == 3).Select(s => s.DeviceToken).ToList();

                    if (deviceTokenForProviderAndroid != null)
                    {
                        await pushNotificationHelper.IntimateAsync(
                        "Hims",
                        message,
                        type,
                        deviceTokenForProviderAndroid,
                        new List<string>(),
                        id);
                    }

                    if (deviceTokenForProviderIOS != null)
                    {
                        await pushNotificationHelper.IntimateAsync(
                        "Hims",
                        message,
                        type,
                        new List<string>(),
                        deviceTokenForProviderIOS,
                        id);
                    }
                }
            }

            if (role == Roles.Patient)
            {
                var accountSessionPatientModel = await accountSessionServices.FetchDeviceTokenAsync(providerOrPatientId, Roles.Patient);
                var accountSessionModels = accountSessionPatientModel as AccountSessionModel[] ?? accountSessionPatientModel.ToArray();
                if (accountSessionModels.Any())
                {
                    var deviceTokenForProviderAndroid = accountSessionModels.Where(d => d.DeviceType == 2).Select(s => s.DeviceToken).ToList();
                    var deviceTokenForProviderIOS = accountSessionModels.Where(d => d.DeviceType == 3).Select(s => s.DeviceToken).ToList();

                    if (deviceTokenForProviderAndroid != null)
                    {
                        await pushNotificationHelper.IntimateAsync(
                        "Hims",
                        message,
                        type,
                        deviceTokenForProviderAndroid,
                        new List<string>(),
                        id);
                    }

                    if (deviceTokenForProviderIOS != null)
                    {
                        await pushNotificationHelper.IntimateAsync(
                        "Hims",
                        message,
                        type,
                        new List<string>(),
                        deviceTokenForProviderIOS,
                        id);
                    }
                }
            }

            return true;
        }
    }
}
