//TODO: Too many moving parts for tasks and notifications move all the logic into the messageService and use of helper methods is fine
        public void SendProductReviewNotifications()
        {
            // Last five years of delivered orders
            var orders = _orderService.SearchOrders(0, 0, 0, 0, 0, 0, 0, null,
                                                    DateTime.Now.AddYears(-5), null, new List <int>()
            {
                (int)OrderStatus.Complete
            }, null, new List <int>()
            {
                (int)ShippingStatus.Delivered
            },
                                                    null, string.Empty);

            var fiveDaysAgo = DateTime.Now.AddDays(-5);

            // Ensure the customer has had enough time to use the product (five days after delivery; most people are eager to try new products)
            var usedOrders = orders.Where(x => x.Shipments.Any(y => y.DeliveryDateUtc <= fiveDaysAgo));

            var customerOrders = usedOrders
                                 .GroupBy(o => o.CustomerId)
                                 .Select((ordrs, customerId) => new { Customer = ordrs.First().Customer, Orders = ordrs.ToList() })
                                 .ToList();

            foreach (var customerAndOrders in customerOrders)
            {
                var customer = customerAndOrders.Customer;
                var customerDistinctProducts   = customerAndOrders.Orders.SelectMany(o => o.OrderItems.Select(oi => oi.Product).Distinct());
                var customerDistinctProductIds = customerDistinctProducts.Select(p => p.Id).ToList();


                // send notification semi-annually (6 months) if customer has not written a review
                var notificationFromDate       = DateTime.Now.AddMonths(-6);
                var productReviewNotifications = _notificationService.GetProductReviewNotifications(customer.Id, customerDistinctProductIds, notificationFromDate);

                var productReviewNotificationsProductIds = productReviewNotifications.Select(prv => prv.ProductId);

                var unsentProductIds = customerDistinctProductIds.Except(productReviewNotificationsProductIds);

                if (unsentProductIds.Count() == 0)
                {
                    continue;
                }

                // Send one notificaiton for all products that have not had a review written by the customer; sending one notification per product would frustrate customers.
                var unreviewedProducts = _productService.GetProductsByIds(unsentProductIds.ToArray()).ToList();

                _mobSocialMessageService.SendProductReviewNotification(customer, unreviewedProducts, _workContext.WorkingLanguage.Id, _storeContext.CurrentStore.Id);

                _notificationService.UpdateProductReviewNotifications(customer, unreviewedProducts);
            }
        }