public ActionResult FirstWeekAndAllViewVideoCatPopover(int catId, int year)
        {
            var videoReports = _videoRepository.GetMany(v => v.CategoryId == catId && v.DisplayTime.Year == year).AsEnumerable()
                               .Select(v => new CompareVideoItemModel()
            {
                VideoId     = v.Id,
                DisplayTime = v.DisplayTime
            }).ToList();

            foreach (var vd in videoReports)
            {
                var firstWeekReport = _videoRepository.GetFirstWeekReport(vd.VideoId, vd.DisplayTime, null);
                vd.FirstWeek = firstWeekReport;

                var alltimeReport = _videoRepository.GetAllTimeReport(vd.VideoId);
                vd.AllTime = alltimeReport;
            }

            var model = new CompareVideoModel
            {
                FirstWeekView    = videoReports.Count() == 0 ? 0 : videoReports.Sum(x => x.FirstWeek.PageView),
                AllTimeView      = videoReports.Count() == 0 ? 0 : videoReports.Sum(v => v.AllTime.PageView),
                FirstWeekHighest = videoReports.Count() == 0 ? 0 : videoReports.Max(m => m.FirstWeek.Highest),
                FirstWeekLowest  = videoReports.Count() == 0 ? 0 : videoReports.Min(m => m.FirstWeek.Lowest),
                AllTimeHighest   = videoReports.Count() == 0 ? 0 : videoReports.Max(m => m.AllTime.Highest),
                AllTimeLowest    = videoReports.Count() == 0 ? 0 : videoReports.Max(m => m.AllTime.Lowest),
            };

            return(PartialView("_FirstWeekAndAllViewVideoCatPopover", model));
        }
        public JsonResult AjaxCompareVideoSameWeekReport(int videoId)
        {
            var video = _videoRepository.Find(videoId);

            var dateOffset = (video.DisplayTime.DayOfWeek - DayOfWeek.Monday + 7) % 7;
            var monday     = video.DisplayTime.AddDays(-dateOffset);
            var nextMonday = monday.AddDays(7);

            var catTypeId     = video.Category.TypeId;
            var specializeIds = new List <int> {
                3, 4
            };

            if (!catTypeId.HasValue || !specializeIds.Contains(catTypeId.Value))
            {
                return(Json(new { success = false }, JsonRequestBehavior.AllowGet));
            }
            //var week = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(video.DisplayTime, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
            var videoReports = _videoRepository.GetMany(v => v.Category.TypeId.HasValue && specializeIds.Contains(v.Category.TypeId.Value) && v.DisplayTime < nextMonday && v.DisplayTime >= monday).AsEnumerable()
                               .Select(v => new CompareVideoItemModel()
            {
                VideoId       = v.Id,
                Title         = v.Title,
                CategoryName  = v.Category.Name,
                VideoDuration = v.Duration.ToString(@"hh\:mm\:ss"),
                VideoPeriod   = (DateTime.Now - v.DisplayTime).Days,
                DisplayTime   = v.DisplayTime
            }).ToList();

            foreach (var vd in videoReports)
            {
                var firstWeekReport = _videoRepository.GetFirstWeekReport(vd.VideoId, vd.DisplayTime, null);
                vd.FirstWeek = firstWeekReport;

                var alltimeReport = _videoRepository.GetAllTimeReport(vd.VideoId);
                vd.AllTime = alltimeReport;

                vd.ReviewReport = new VideoReviewReport
                {
                    PageView      = vd.AllTime.PageView - vd.FirstWeek.PageView,
                    ViewDateCount = vd.AllTime.ViewDateCount - vd.FirstWeek.ViewDateCount,
                };
            }

            var tabledata = new CompareVideoModel
            {
                CurrentId        = videoId,
                Videos           = videoReports,
                FirstWeekView    = videoReports.Sum(v => v.FirstWeek.PageView),
                AllTimeView      = videoReports.Sum(v => v.AllTime.PageView),
                FirstWeekAverage = Math.Round(videoReports.Average(v => v.FirstWeek.PageView), 2),
                AllTimeAverage   = Math.Round(videoReports.Average(v => v.AllTime.PageView), 2)
            };

            foreach (var vd in videoReports)
            {
                vd.FirstWeek.AverageChange   = Math.Round(vd.FirstWeek.PageView - tabledata.FirstWeekAverage, 2);
                vd.FirstWeek.PercentPageView = Math.Round(vd.FirstWeek.PageView * 100D / tabledata.FirstWeekView, 2);

                vd.AllTime.AverageChange   = Math.Round(vd.AllTime.PageView - tabledata.AllTimeAverage, 2);
                vd.AllTime.PercentPageView = Math.Round(vd.AllTime.PageView * 100D / tabledata.AllTimeView, 2);

                vd.ReviewReport.PercentPageView = vd.AllTime.PageView == 0? 0 : Math.Round(vd.ReviewReport.PageView * 100D / vd.AllTime.PageView, 2);
            }
            ;

            var chartData       = new ArrayList();
            var firstWeek       = new { name = "Tuần đầu", data = new ArrayList() };
            var review          = new { name = "Xem lại", data = new ArrayList() };
            var chartCategories = new ArrayList();

            foreach (var vd in tabledata.Videos.OrderBy(v => v.CategoryName))
            {
                chartCategories.Add(vd.CategoryName);
                //foreach (var vd in cat)
                {
                    firstWeek.data.Add(new { name = vd.Title, y = vd.FirstWeek.PageView });
                    review.data.Add(new { name = vd.Title, y = vd.ReviewReport.PageView });
                }
            }
            chartData.Add(review);
            chartData.Add(firstWeek);

            return(Json(new { table = tabledata, chart = chartData, categories = chartCategories }, JsonRequestBehavior.AllowGet));
            //return PartialView("_CompareVideoSameWeekReport", model);
        }
        //testsang
        private CompareVideoModel GetCompareVideoReport(int catId, int year)
        {
            var cat          = _videoCatRepository.Find(catId);
            var videoReports = _videoRepository.GetMany(v => v.CategoryId == catId && v.DisplayTime.Year == year).AsEnumerable()
                               .Select(v => new CompareVideoItemModel()
            {
                CategoryName     = v.Category.Name,
                CategoryTypeName = v.Category.Type.Name,
                VideoId          = v.Id,
                Title            = v.Title,
                Month            = v.DisplayTime.Month,
                Week             = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(v.DisplayTime, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday),
                VideoDuration    = v.Duration.ToString(@"hh\:mm\:ss"),
                VideoPeriod      = (DateTime.Now - v.DisplayTime).Days,
                DisplayTime      = v.DisplayTime
            }).ToList();

            foreach (var vd in videoReports)
            {
                var firstWeekReport = _videoRepository.GetFirstWeekReport(vd.VideoId, vd.DisplayTime, null);
                vd.FirstWeek = firstWeekReport;

                var alltimeReport = _videoRepository.GetAllTimeReport(vd.VideoId);
                vd.AllTime = alltimeReport;

                vd.ReviewReport = new VideoReviewReport
                {
                    PageView      = vd.AllTime.PageView - vd.FirstWeek.PageView,
                    ViewDateCount = vd.AllTime.ViewDateCount - vd.FirstWeek.ViewDateCount,
                };
            }

            var model = new CompareVideoModel
            {
                FirstWeekHighestVideoId = videoReports.Count() == 0 ? 0 : videoReports.Where(v => v.FirstWeek.Highest == videoReports.Max(s => s.FirstWeek.Highest)).FirstOrDefault().VideoId,
                FirstWeekLowestVideoId  = videoReports.Count() == 0 ? 0 : videoReports.Where(v => v.FirstWeek.Lowest == videoReports.Min(s => s.FirstWeek.Lowest)).FirstOrDefault().VideoId,
                AllTimeHighestVideoId   = videoReports.Count() == 0 ? 0 : videoReports.Where(v => v.AllTime.Highest == videoReports.Max(s => s.AllTime.Highest)).FirstOrDefault().VideoId,
                AllTimeLowestVideoId    = videoReports.Count() == 0 ? 0 : videoReports.Where(v => v.AllTime.Lowest == videoReports.Min(s => s.AllTime.Lowest)).FirstOrDefault().VideoId,
                AllTimeAverageHighest   = videoReports.Count() == 0 ? 0 : Math.Round((double)videoReports.Sum(v => v.AllTime.Highest) / videoReports.Select(v => v.AllTime.Highest).Count(), 2),
                FirstWeekAverageHighest = videoReports.Count() == 0 ? 0 : Math.Round((double)videoReports.Sum(v => v.FirstWeek.Highest) / videoReports.Select(v => v.FirstWeek.Highest).Count(), 2),
                VideoCount       = videoReports.Count(),
                CategoryTypeName = cat.Type != null? cat.Type.Name: "",
                CategoryName     = cat.Name,
                FirstWeekView    = videoReports.Count() == 0 ? 0 : videoReports.Sum(x => x.FirstWeek.PageView),
                AllTimeView      = videoReports.Count() == 0 ? 0 : videoReports.Sum(v => v.AllTime.PageView),
                Review           = videoReports.Count() == 0 ? 0 : videoReports.Sum(v => v.AllTime.PageView) - videoReports.Sum(x => x.FirstWeek.PageView),
                AllTimeMedian    = videoReports.Count() == 0 ? 0 : GetMedian(videoReports, 1),
                FirstWeekMedian  = videoReports.Count() == 0 ? 0 : GetMedian(videoReports, 2),
                FirstWeekHighest = videoReports.Count() == 0 ? 0 : videoReports.Max(m => m.FirstWeek.Highest),
                FirstWeekLowest  = videoReports.Count() == 0 ? 0 : videoReports.Min(m => m.FirstWeek.Lowest),
                AllTimeHighest   = videoReports.Count() == 0 ? 0 : videoReports.Max(m => m.AllTime.Highest),
                AllTimeLowest    = videoReports.Count() == 0 ? 0 : videoReports.Max(m => m.AllTime.Lowest),
                FirstWeekAverage = videoReports.Count() == 0 ? 0 : Math.Round(videoReports.Average(v => v.FirstWeek.PageView), 2),
                AllTimeAverage   = videoReports.Count() == 0 ? 0 : Math.Round(videoReports.Average(v => v.AllTime.PageView), 2)
            };

            //foreach (var vd in videoReports)
            //{
            //    vd.FirstWeek.AverageChange = vd.FirstWeek.PageView - model.FirstWeekAverage;
            //    vd.FirstWeek.PercentPageView = Math.Round(vd.FirstWeek.PageView * 100D / model.FirstWeekView, 2);

            //    vd.AllTime.AverageChange = vd.AllTime.PageView - model.AllTimeAverage;
            //    vd.AllTime.PercentPageView = Math.Round(vd.AllTime.PageView * 100D / model.AllTimeView, 2);

            //    vd.ReviewReport.PercentPageView = Math.Round(vd.ReviewReport.PageView * 100D / vd.AllTime.PageView, 2);
            //};
            return(model);
        }