private static object ProcessPropertyBagItem(object input)
 {
     return(input switch
     {
         IEnumerable <object> enumerableInput => enumerableInput.Select(ProcessPropertyBagItem).ToArray(),
         IPropertyBag propertyBagInput => propertyBagInput.AsDictionaryRecursive(),
         _ => input,
     });
        /// <inheritdoc/>
        public async Task <NotificationTemplate> GenerateTemplateAsync(
            INotificationTemplateStore templateStore,
            IPropertyBag body,
            List <CommunicationType> registeredCommunicationChannels,
            string notificationType)
        {
            EmailTemplate?  emailTemplate   = null;
            SmsTemplate?    smsTemplate     = null;
            WebPushTemplate?webPushTemplate = null;
            IReadOnlyDictionary <string, object> propertiesDictionary = body.AsDictionaryRecursive();
            var propertiesHash = Hash.FromReadOnlyDictionary(propertiesDictionary);

            foreach (CommunicationType channel in registeredCommunicationChannels)
            {
                switch (channel)
                {
                case CommunicationType.Email:
                    try
                    {
                        (EmailTemplate, string?)emailRawTemplate = await templateStore.GetAsync <EmailTemplate>(notificationType, CommunicationType.Email).ConfigureAwait(false);

                        string?emailBody = await this.GenerateTemplateForFieldAsync(emailRawTemplate.Item1.Body, propertiesHash).ConfigureAwait(false);

                        string?emailSubject = await this.GenerateTemplateForFieldAsync(emailRawTemplate.Item1.Subject, propertiesHash).ConfigureAwait(false);

                        if (string.IsNullOrEmpty(emailSubject))
                        {
                            this.logger.LogError($"The template for the communication type Email doesn't have subject which is necessary to trigger a {notificationType} notification.");
                            break;
                        }

                        if (string.IsNullOrEmpty(emailBody))
                        {
                            this.logger.LogError($"The template for the communication type Email doesn't have body which is necessary to trigger a {notificationType} notification.");
                            break;
                        }

                        emailTemplate = new EmailTemplate(
                            notificationType,
                            emailSubject,
                            emailBody);
                    }
                    catch (Exception)
                    {
                        this.logger.LogError("The template for the communication type Email doesn't exist");
                    }

                    break;

                case CommunicationType.Sms:
                    try
                    {
                        (SmsTemplate, string?)smsRawTemplate = await templateStore.GetAsync <SmsTemplate>(notificationType, CommunicationType.Sms).ConfigureAwait(false);

                        string?smsBody = await this.GenerateTemplateForFieldAsync(smsRawTemplate.Item1.Body !, propertiesHash).ConfigureAwait(false);

                        if (string.IsNullOrEmpty(smsBody))
                        {
                            this.logger.LogError($"The template for the communication type Sms doesn't have body which is necessary to trigger a {notificationType} notification.");
                            break;
                        }

                        smsTemplate = new SmsTemplate(notificationType, smsBody);
                    }
                    catch (Exception)
                    {
                        this.logger.LogError("The template for the communication type Sms doesn't exist");
                    }

                    break;

                case CommunicationType.WebPush:
                    try
                    {
                        (WebPushTemplate, string?)webPushRawTemplate = await templateStore.GetAsync <WebPushTemplate>(notificationType, CommunicationType.WebPush).ConfigureAwait(false);

                        string?webPushTitle = await this.GenerateTemplateForFieldAsync(webPushRawTemplate.Item1.Title, propertiesHash).ConfigureAwait(false);

                        string?webPushBody = await this.GenerateTemplateForFieldAsync(webPushRawTemplate.Item1.Body, propertiesHash).ConfigureAwait(false);

                        string?webPushImage = await this.GenerateTemplateForFieldAsync(webPushRawTemplate.Item1.Image, propertiesHash).ConfigureAwait(false);

                        string?actionUrl = await this.GenerateTemplateForFieldAsync(webPushRawTemplate.Item1.ActionUrl, propertiesHash).ConfigureAwait(false);

                        if (string.IsNullOrEmpty(webPushTitle))
                        {
                            this.logger.LogError($"The template for the communication type WebPush doesn't have title which is necessary to trigger a {notificationType} notification.");
                            break;
                        }

                        if (string.IsNullOrEmpty(webPushBody))
                        {
                            this.logger.LogError($"The template for the communication type WebPush doesn't have body which is necessary to trigger a {notificationType} notification.");
                            break;
                        }

                        webPushTemplate = new WebPushTemplate(
                            notificationType,
                            webPushTitle,
                            webPushBody,
                            webPushImage,
                            actionUrl);
                    }
                    catch (Exception)
                    {
                        this.logger.LogError("The template for the communication type WebPush doesn't exist");
                    }

                    break;
                }
            }

            return(new NotificationTemplate(
                       notificationType,
                       smsTemplate,
                       emailTemplate,
                       webPushTemplate));
        }