//public async Task<ActionResult> Campaigns()
        //{
        //    var model = new CampaignsViewModel();
        //    model.Currency = "RM"; //TODO: eugene: implement currency
        //    var user = _wca.GetContext().CurrentUser;
        //    var teeyootUser = user.ContentItem.Get(typeof(TeeyootUserPart));
        //    var campaignsQuery = _campaignService.GetCampaignsOfUser(teeyootUser != null ? teeyootUser.Id : 0);
        //    var productsOrderedQuery = _orderService.GetProductsOrderedOfCampaigns(campaignsQuery.Select(c => c.Id).ToArray());

        //    await FillCampaigns(model, campaignsQuery);
        //    FillOverviews(model, productsOrderedQuery, campaignsQuery);

        //    return View(model);
        //}

        public ActionResult Campaigns(bool? isError, string result)
        {
            var model = new CampaignsViewModel();
            
            //model.IDCurrencyCode = _currencyRepository.Table.Where(c => c.CurrencyCulture == "id-ID").FirstOrDefault().Code;
            //model.SGCurrencyCode = _currencyRepository.Table.Where(c => c.CurrencyCulture == "en-SG").FirstOrDefault().Code;
            var user = _wca.GetContext().CurrentUser;
            var teeyootUser = (TeeyootUserPart)user.ContentItem.Get(typeof(TeeyootUserPart));

            model.CurrencyCode = teeyootUser.CurrencyRecord.Code;

            var campaignsQuery = _campaignService.GetCampaignsOfUser(user.Id);
            var productsOrderedQuery = _orderService
                .GetProductsOrderedOfCampaigns(campaignsQuery.Select(c => c.Id).ToArray());

            var campaignList = new List<CampaignRecord>();
            foreach (var campaign in campaignsQuery)
            {
                var productsOfCampaign = _orderService.GetProductsOrderedOfCampaign(campaign.Id).ToList();
                if (productsOfCampaign != null)
                {
                    if (campaign.ProductMinimumGoal <= productsOfCampaign.Select(p => p.Count).Sum())
                    {
                        campaignList.Add(campaign);
                    }
                }
            }

            var productsOrderedQueryWithMinimum = _orderService
              .GetProductsOrderedOfCampaigns(campaignList.Select(c => c.Id).ToArray());

            FillCampaigns(model, campaignsQuery);
            FillOverviews(model, productsOrderedQueryWithMinimum, productsOrderedQuery, campaignsQuery);

            return View(model);
        }
        private void FillOverviews(CampaignsViewModel model, IQueryable<LinkOrderCampaignProductRecord> productsOrderedQueryWithMinimum, IQueryable<LinkOrderCampaignProductRecord> productsOrderedQuery, IQueryable<CampaignRecord> campaignsQuery)
        {
            model.Overviews.Add(new CampaignsOverview
            {
                Type = OverviewType.Today,
                ProductsOrdered = productsOrderedQuery
                            .FilterByType(OverviewType.Today)
                            .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved")
                            .Sum(p => (int?)p.Count) ?? 0,
                MYProfit = Math.Round(productsOrderedQueryWithMinimum
                            .FilterByType(OverviewType.Today)
                             .Where(p => p.OrderRecord.OrderStatusRecord.Id != int.Parse(OrderStatus.Cancelled.ToString("d")) && p.OrderRecord.OrderStatusRecord.Id != int.Parse(OrderStatus.Unapproved.ToString("d")))
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                SGProfit = Math.Round(productsOrderedQueryWithMinimum
                            .FilterByType(OverviewType.Today)
                             .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.OrderRecord.CurrencyRecord.CurrencyCulture == "en-SG")
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                IDProfit = Math.Round(productsOrderedQueryWithMinimum
                            .FilterByType(OverviewType.Today)
                             .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.OrderRecord.CurrencyRecord.CurrencyCulture == "id-ID")
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                //MYToBePaid = Math.Round(_payoutService.GetAllPayouts()
                //        .Where(p => p.IsPlus == true && p.IsProfitPaid != null && p.IsProfitPaid == false && p.Status != "Pending" && p.UserId == _workContextAccessor.GetContext().CurrentUser.Id && p.Date.Day == DateTime.Now.Day && p.IsCampiaign != null && p.IsCampiaign)
                //        .Select(p => new { Amount = p.Amount })
                //        .Sum(entry => (double?)entry.Amount) ?? 0, 2),
                //MYToBeAllPaid = Math.Round(_payoutService.GetAllPayouts()
                //        .Where(p => p.IsProfitPaid != null && p.IsProfitPaid && p.Status != "Pending" && p.UserId == _workContextAccessor.GetContext().CurrentUser.Id && p.Date.Day == DateTime.Now.Day)
                //        .Select(p => new { Amount = p.Amount })
                //        .Sum(entry => (double?)entry.Amount) ?? 0, 2)
                //,
                //ToBePaid = productsOrderedQuery
                //            .FilterByType(OverviewType.Today)
                //            .Where(p => !p.OrderRecord.Reserved.HasValue)
                //            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                //            .Sum(entry => entry.Profit)
                MYToBeAllPaid = 0
            });

            model.Overviews.Add(new CampaignsOverview
            {
                Type = OverviewType.Yesterday,
                ProductsOrdered = productsOrderedQuery
                            .FilterByType(OverviewType.Yesterday)
                            .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved")
                            .Sum(p => (int?)p.Count) ?? 0,
                MYProfit = Math.Round(productsOrderedQueryWithMinimum
                            .FilterByType(OverviewType.Yesterday)
                             .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved")
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                SGProfit = Math.Round(productsOrderedQueryWithMinimum
                            .FilterByType(OverviewType.Yesterday)
                             .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.OrderRecord.CurrencyRecord.CurrencyCulture == "en-SG")
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                IDProfit = Math.Round(productsOrderedQueryWithMinimum
                            .FilterByType(OverviewType.Yesterday)
                             .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.OrderRecord.CurrencyRecord.CurrencyCulture == "id-ID")
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                //MYToBeAllPaid = Math.Round(_payoutService.GetAllPayouts()
                //          .Where(p => p.IsProfitPaid != null && p.IsProfitPaid && p.Status != "Pending" && p.UserId == _workContextAccessor.GetContext().CurrentUser.Id && p.Date.Day == DateTime.Now.AddDays(-1).Day)
                //          .Select(p => new { Amount = p.Amount })
                //           .Sum(entry => (double?)entry.Amount) ?? 0, 2)
                //,
                //ToBePaid = productsOrderedQuery
                //            .FilterByType(OverviewType.Yesterday)
                //            .Where(p => !p.OrderRecord.Reserved.HasValue)
                //            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                //            .Sum(entry => entry.Profit)
                MYToBeAllPaid = 0
            });

            model.Overviews.Add(new CampaignsOverview
            {
                Type = OverviewType.Active,

                ProductsOrdered = productsOrderedQuery
                            .FilterByType(OverviewType.Active, campaignsQuery)
                            .Where(p => p.OrderRecord.OrderStatusRecord.Id != int.Parse(OrderStatus.Cancelled.ToString("d")) && p.OrderRecord.OrderStatusRecord.Id != int.Parse(OrderStatus.Unapproved.ToString("d")) && p.OrderRecord.IsActive)
                            .Sum(p => (int?)p.Count) ?? 0,
                MYProfit = Math.Round(productsOrderedQueryWithMinimum
                            .Where(p => p.OrderRecord.OrderStatusRecord.Id != int.Parse(OrderStatus.Cancelled.ToString("d")) && p.OrderRecord.OrderStatusRecord.Id != int.Parse(OrderStatus.Unapproved.ToString("d")) && p.OrderRecord.IsActive)
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                SGProfit = Math.Round(productsOrderedQueryWithMinimum
                             .FilterByType(OverviewType.Active, campaignsQuery)
                             .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.OrderRecord.CurrencyRecord.CurrencyCulture == "en-SG")
                             .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                             .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                IDProfit = Math.Round(productsOrderedQueryWithMinimum
                             .FilterByType(OverviewType.Active, campaignsQuery)
                             .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.OrderRecord.CurrencyRecord.CurrencyCulture == "id-ID")
                             .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                             .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                MYToBeAllPaid = Math.Round(_payoutService.GetAllPayouts()
                          .Where(p => p.IsProfitPaid != null && p.IsProfitPaid && p.Status != "Pending" && p.UserId == _workContextAccessor.GetContext().CurrentUser.Id)
                          .Select(p => new { Amount = p.Amount })
                           .Sum(entry => (double?)entry.Amount) ?? 0, 2)
            });

            model.Overviews.Add(new CampaignsOverview
            {
                Type = OverviewType.AllTime,
                ProductsOrdered = productsOrderedQuery
                             .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved")
                            .Sum(p => (int?)p.Count) ?? 0,
                MYProfit = Math.Round(productsOrderedQueryWithMinimum
                            .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved")
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                SGProfit = Math.Round(productsOrderedQueryWithMinimum
                            .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.OrderRecord.CurrencyRecord.CurrencyCulture == "en-SG")
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                IDProfit = Math.Round(productsOrderedQueryWithMinimum
                            .Where(p => p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.OrderRecord.CurrencyRecord.CurrencyCulture == "id-ID")
                            .Select(p => new { Profit = p.Count * (p.CampaignProductRecord.Price - p.CampaignProductRecord.BaseCost) })
                            .Sum(entry => (double?)entry.Profit) ?? 0, 2),
                //MYToBeAllPaid = Math.Round(_payoutService.GetAllPayouts()
                //           .Where(p => (p.IsPlus == false && p.UserId == _workContextAccessor.GetContext().CurrentUser.Id && p.Status == "Pending") || (p.IsProfitPaid != null && p.IsProfitPaid && p.Status != "Pending" && p.UserId == _workContextAccessor.GetContext().CurrentUser.Id))
                //           .Select(p => new { Amount = p.Amount })
                //            .Sum(entry => (double?)entry.Amount) ?? 0, 2)
                MYToBeAllPaid = 0

            });
            foreach (var item in model.Overviews)
            {
                item.MYProfit = item.MYProfit - item.MYToBeAllPaid;
                if (item.MYProfit < 0)
                    item.MYProfit = item.MYProfit * -1;
            }

        }
        //private async Task FillCampaigns(CampaignsViewModel model, IQueryable<CampaignRecord> campaignsQuery)
        //{
        //    var campaignSummaries = new List<CampaignSummary>();
        //    var campaigns = campaignsQuery.OrderBy(c => c.StartDate).ToList();

        //    foreach (var c in campaigns)
        //    {
        //        campaignSummaries.Add(new CampaignSummary
        //        {
        //            Alias = c.Alias,
        //            EndDate = c.EndDate,
        //            Goal = c.ProductCountGoal,
        //            Id = c.Id,
        //            Name = c.Title,
        //            Sold = c.ProductCountSold,
        //            StartDate = c.StartDate,
        //            Status = c.CampaignStatusRecord,
        //            ShowBack = c.BackSideByDefault,
        //            FirstProductId = c.Products[0].Id,
        //            Profit = await _orderService.GetProfitOfCampaign(c.Id)                   
        //        });
        //    }
        //    model.Campaigns = campaignSummaries;
        //}

        private void FillCampaigns(CampaignsViewModel model, IQueryable<CampaignRecord> campaignsQuery)
        {
            var campaignProducts = _campaignService.GetAllCampaignProducts();
            var orderedProducts = _orderService.GetAllOrderedProducts();

            var campaignSummaries = campaignsQuery
                .Select(c => new CampaignSummary
                    {
                        Alias = c.Alias,
                        EndDate = c.EndDate,
                        Goal = c.ProductCountGoal,
                        Id = c.Id,
                        Name = c.Title,
                        Sold = c.ProductCountSold,
                        Minimum = c.ProductMinimumGoal,
                        StartDate = c.StartDate,
                        Status = c.CampaignStatusRecord,
                        IsActive = c.IsActive,
                        IsArchived = c.IsArchived,
                        ShowBack = c.BackSideByDefault,
                        IsPrivate = c.IsPrivate
                    })
                .OrderBy(c => c.StartDate)
                .ToArray();

            foreach (var item in campaignSummaries)
            {
                item.CountRequests = _campaignService.GetCountOfReservedRequestsOfCampaign(item.Id);
                var prods = campaignProducts.Where(c => c.WhenDeleted == null).FirstOrDefault(p => p.CampaignRecord_Id == item.Id);
                item.FirstProductId = prods != null ? prods.Id : 0;
                item.Profit = orderedProducts
                                    .Where(p => p.OrderRecord.IsActive && p.OrderRecord.OrderStatusRecord.Name != "Cancelled" && p.OrderRecord.OrderStatusRecord.Name != "Unapproved" && p.CampaignProductRecord.CampaignRecord_Id == item.Id)
                                    .Select(pr => new { Profit = pr.Count * (pr.CampaignProductRecord.Price - pr.CampaignProductRecord.BaseCost) })
                                    .Sum(entry => (double?)entry.Profit) ?? 0;
                item.SummaryCurrency = _currencyRepository.Table.Where(c => c.CurrencyCulture == (_campaignService.GetCampaignById(item.Id).CampaignCulture)).FirstOrDefault().Code;
            }

            campaignSummaries = campaignSummaries.Where(c => c.FirstProductId > 0).ToArray();

            model.Campaigns = campaignSummaries;
        }