public async Task <IActionResult> FilterCourses(ProviderCoursesRequestModel requestModel)
        {
            Session.SetString("Option", "Courses");
            int?UKPRN = Session.GetInt32("UKPRN");

            if (!UKPRN.HasValue)
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Please select a Provider." }));
            }

            var model = new ProviderCoursesViewModel();

            model.ProviderCourseRuns = Session.GetObject <List <ProviderCourseRunViewModel> >("ProviderCourses");

            //var courseResult = (await _courseService.GetCoursesByLevelForUKPRNAsync(new CourseSearchCriteria(UKPRN))).Value;
            var venueResult = (await _venueService.SearchAsync(new VenueSearchCriteria(UKPRN.ToString(), string.Empty))).Value;
            var allRegions  = _courseService.GetRegions().RegionItems;

            List <ProviderCoursesFilterItemModel> levelFilterItems          = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> deliveryModelFilterItems  = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> venueFilterItems          = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> regionFilterItems         = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> attendanceModeFilterItems = new List <ProviderCoursesFilterItemModel>();

            if (!string.IsNullOrEmpty(requestModel.Keyword))
            {
                model.ProviderCourseRuns = model.ProviderCourseRuns
                                           .Where(x => x.CourseName.ToLower().Contains(requestModel.Keyword.ToLower()) ||
                                                  x.QualificationCourseTitle.ToLower().Contains(requestModel.Keyword.ToLower()) ||
                                                  x.LearnAimRef.ToLower().Contains(requestModel.Keyword.ToLower()) ||
                                                  x.AttendancePattern.ToLower().Contains(requestModel.Keyword.ToLower()) ||
                                                  x.DeliveryMode.ToLower().Contains(requestModel.Keyword.ToLower()) ||
                                                  x.Venue.ToLower().Contains(requestModel.Keyword.ToLower()) ||
                                                  x.Region.ToLower().Contains(requestModel.Keyword.ToLower()) ||
                                                  (!string.IsNullOrEmpty(x.CourseTextId) && x.CourseTextId.ToLower().Contains(requestModel.Keyword.ToLower()))
                                                  ).ToList();
            }

            if (requestModel.LevelFilter.Length > 0)
            {
                model.ProviderCourseRuns = model.ProviderCourseRuns.Where(x => requestModel.LevelFilter.Contains(x.NotionalNVQLevelv2)).ToList();
            }

            if (requestModel.DeliveryModeFilter.Length > 0)
            {
                model.ProviderCourseRuns = model.ProviderCourseRuns.Where(x => requestModel.DeliveryModeFilter.Contains(x.DeliveryMode)).ToList();
            }


            if (requestModel.VenueFilter.Length > 0)
            {
                model.ProviderCourseRuns = model.ProviderCourseRuns.Where(x => requestModel.VenueFilter.Contains(x.Venue)).ToList();
            }

            if (requestModel.AttendancePatternFilter.Length > 0)
            {
                model.ProviderCourseRuns = model.ProviderCourseRuns.Where(x => requestModel.AttendancePatternFilter.Contains(x.AttendancePattern)).ToList();
            }


            if (requestModel.RegionFilter.Length > 0)
            {
                List <ProviderCourseRunViewModel> allResults    = model.ProviderCourseRuns.ToList();
                List <ProviderCourseRunViewModel> filterResults = new List <ProviderCourseRunViewModel>();
                foreach (var regionFilter in requestModel.RegionFilter)
                {
                    var region = _courseService.GetRegions().RegionItems
                                 .Where(x => string.Equals(x.Id, regionFilter, StringComparison.CurrentCultureIgnoreCase))
                                 .Select(d => d.RegionName).FirstOrDefault();

                    var results = allResults.Where(x => x.Region.Contains(region));

                    filterResults.AddRange(results);

                    allResults.RemoveAll(x => x.Region.Contains(region));
                }

                model.ProviderCourseRuns = filterResults;
            }

            model.ProviderCourseRuns = model.ProviderCourseRuns.OrderBy(x => x.CourseName).ToList();

            // _session.SetObject("ProviderCourses", model.ProviderCourseRuns.OrderBy(x=>x.CourseName));


            int s = 0;

            levelFilterItems = model.ProviderCourseRuns.GroupBy(x => x.NotionalNVQLevelv2).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id         = "level-" + s++.ToString(),
                Value      = r.Key,
                Text       = "Level " + r.Key,
                Name       = "level",
                IsSelected = requestModel.LevelFilter.Length > 0 && requestModel.LevelFilter.Contains(r.Key)
            }).ToList();

            s = 0;
            deliveryModelFilterItems = model.ProviderCourseRuns.GroupBy(x => x.DeliveryMode).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id         = "deliverymode-" + s++.ToString(),
                Value      = r.Key,
                Text       = r.Key,
                Name       = "deliverymode",
                IsSelected = requestModel.DeliveryModeFilter.Length > 0 && requestModel.DeliveryModeFilter.Contains(r.Key)
            }).ToList();


            venueFilterItems = model.ProviderCourseRuns.Where(x => !string.IsNullOrEmpty(x.Venue)).GroupBy(x => x.Venue).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id         = "venue-" + s++.ToString(),
                Value      = r.Key,
                Text       = r.Key,
                Name       = "venue",
                IsSelected = requestModel.VenueFilter.Length > 0 && requestModel.VenueFilter.Contains(r.Key)
            }).ToList();

            attendanceModeFilterItems = model.ProviderCourseRuns.Where(x => x.AttendancePattern != AttendancePattern.Undefined.ToString()).GroupBy(x => x.AttendancePattern).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id         = "attendancepattern-" + s++.ToString(),
                Value      = r.Key,
                Text       = r.Key,
                Name       = "attendancepattern",
                IsSelected = requestModel.AttendancePatternFilter.Length > 0 && requestModel.AttendancePatternFilter.Contains(r.Key)
            }).ToList();

            List <string> allRegionsList   = new List <string>();
            var           regionsForCourse = model.ProviderCourseRuns.GroupBy(x => x.Region).Where(x => !string.IsNullOrEmpty(x.Key)).OrderBy(x => x.Key).ToList();

            foreach (var regions in regionsForCourse)
            {
                var regionsList = regions.Key.Split(",");
                foreach (var region in regionsList)
                {
                    allRegionsList.Add(region.Trim());
                }
            }

            allRegionsList = allRegionsList.Distinct().ToList();

            s = 0;
            foreach (var regionValue in allRegionsList)
            {
                var regionId = _courseService.GetRegions().RegionItems
                               .Where(x => string.Equals(x.RegionName, regionValue, StringComparison.CurrentCultureIgnoreCase))
                               .Select(d => d.Id).FirstOrDefault();

                var regionFilterItem = new ProviderCoursesFilterItemModel
                {
                    Value      = regionId,
                    Text       = regionValue,
                    Id         = "region-" + s++,
                    Name       = "region",
                    IsSelected = requestModel.RegionFilter.Length > 0 && requestModel.RegionFilter.Contains(regionId)
                };

                regionFilterItems.Add(regionFilterItem);
            }



            model.HasFilters        = levelFilterItems.Any(x => x.IsSelected) || deliveryModelFilterItems.Any(x => x.IsSelected) || venueFilterItems.Any(x => x.IsSelected) || regionFilterItems.Any(x => x.IsSelected) || attendanceModeFilterItems.Any(x => x.IsSelected);
            model.Levels            = levelFilterItems;
            model.DeliveryModes     = deliveryModelFilterItems;
            model.Venues            = venueFilterItems;
            model.Regions           = regionFilterItems;
            model.AttendancePattern = attendanceModeFilterItems;

            return(ViewComponent(nameof(ViewComponents.ProviderCoursesResults.ProviderCoursesResults), model));
        }
        public async Task <IActionResult> Index(
            Guid?courseRunId,
            string notificationTitle,
            string notificationMessage)
        {
            Session.SetString("Option", "Courses");
            int?UKPRN = Session.GetInt32("UKPRN");

            if (!UKPRN.HasValue)
            {
                return(RedirectToAction("Index", "Home", new { errmsg = "Please select a Provider." }));
            }

            var courseResult = (await _courseService.GetCoursesByLevelForUKPRNAsync(new CourseSearchCriteria(UKPRN))).Value;
            var venueResult  = (await _venueService.SearchAsync(new VenueSearchCriteria(UKPRN.ToString(), string.Empty))).Value;
            var allRegions   = _courseService.GetRegions().RegionItems;

            var allCourses = courseResult.Value.SelectMany(o => o.Value).SelectMany(i => i.Value).ToList();

            var filteredLiveCourses = from Course c in allCourses.Where(c => BitmaskHelper.IsSet(c.CourseStatus, RecordStatus.Live)).ToList().OrderBy(x => x.QualificationCourseTitle) select c;
            var pendingCourses      = from Course c in allCourses.Where(c => c.CourseStatus == RecordStatus.MigrationPending || c.CourseStatus == RecordStatus.BulkUploadPending)
                                      select c;

            var model = new ProviderCoursesViewModel()
            {
                PendingCoursesCount = pendingCourses?.SelectMany(c => c.CourseRuns)?.Count(),
                ProviderCourseRuns  = new List <ProviderCourseRunViewModel>()
            };

            List <ProviderCoursesFilterItemModel> levelFilterItems          = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> deliveryModelFilterItems  = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> venueFilterItems          = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> regionFilterItems         = new List <ProviderCoursesFilterItemModel>();
            List <ProviderCoursesFilterItemModel> attendanceModeFilterItems = new List <ProviderCoursesFilterItemModel>();

            foreach (var course in filteredLiveCourses)
            {
                var filteredLiveCourseRuns = new List <CourseRun>();

                filteredLiveCourseRuns = course.CourseRuns.ToList();
                filteredLiveCourseRuns.RemoveAll(x => x.RecordStatus != RecordStatus.Live);

                foreach (var cr in filteredLiveCourseRuns)
                {
                    var national = cr.DeliveryMode == DeliveryMode.WorkBased & !cr.National.HasValue ||
                                   cr.National.GetValueOrDefault();

                    ProviderCourseRunViewModel courseRunModel = new ProviderCourseRunViewModel()
                    {
                        AwardOrgCode             = course.AwardOrgCode,
                        LearnAimRef              = course.LearnAimRef,
                        NotionalNVQLevelv2       = course.NotionalNVQLevelv2,
                        QualificationType        = course.QualificationType,
                        CourseId                 = course.id,
                        QualificationCourseTitle = course.QualificationCourseTitle,
                        CourseRunId              = cr.id.ToString(),
                        CourseTextId             = cr.ProviderCourseID,
                        AttendancePattern        = cr.AttendancePattern.ToDescription(),
                        Cost         = cr.Cost.HasValue ? $"£ {cr.Cost.Value:0.00}" : string.Empty,
                        CourseName   = cr.CourseName,
                        DeliveryMode = cr.DeliveryMode.ToDescription(),
                        Duration     = cr.DurationValue.HasValue
                                                        ? $"{cr.DurationValue.Value} {cr.DurationUnit.ToDescription()}"
                                                        : $"0 {cr.DurationUnit.ToDescription()}",
                        Venue = cr.VenueId.HasValue
                                                        ? FormatAddress(GetVenueByIdFrom(venueResult.Value, cr.VenueId.Value))
                                                        : string.Empty,
                        StartDate = cr.FlexibleStartDate
                                                        ? "Flexible start date"
                                                        : cr.StartDate?.ToString("dd MMM yyyy"),
                        StudyMode = cr.StudyMode == Services.Models.Courses.StudyMode.Undefined
                                                        ? string.Empty
                                                        : cr.StudyMode.ToDescription(),
                        Url      = cr.CourseURL,
                        National = national
                    };
                    //If National
                    if (national)
                    {
                        courseRunModel.Region       = string.Join(", ", allRegions.Select(x => x.RegionName).ToList());
                        courseRunModel.RegionIdList = string.Join(", ", allRegions.Select(x => x.Id).ToList());
                    }
                    else
                    {
                        courseRunModel.Region = cr.Regions != null?FormattedRegionsByIds(allRegions, cr.Regions) : string.Empty;

                        courseRunModel.RegionIdList = cr.Regions != null?FormattedRegionIds(allRegions, cr.Regions) : string.Empty;
                    }
                    model.ProviderCourseRuns.Add(courseRunModel);
                }
            }

            Session.SetObject("ProviderCourses", model.ProviderCourseRuns);

            int s           = 0;
            var textValue   = string.Empty;
            var levelFilter = model.ProviderCourseRuns.GroupBy(x => x.NotionalNVQLevelv2).OrderBy(x => x.Key).ToList();

            foreach (var level in levelFilter)
            {
                textValue = string.Empty;

                switch (level.Key.ToLower())
                {
                case "e":
                    textValue = "Entry level";
                    break;

                case "x":
                    textValue = "X - Not applicable/unknown";
                    break;

                case "h":
                    textValue = "Higher";
                    break;

                case "m":
                    textValue = "Mixed";
                    break;

                default:
                    textValue = "Level " + level.Key;
                    break;
                }

                ProviderCoursesFilterItemModel itemModel = new ProviderCoursesFilterItemModel()
                {
                    Id    = "level-" + s++.ToString(),
                    Value = level.Key,
                    Text  = textValue,
                    Name  = "level"
                };

                levelFilterItems.Add(itemModel);
            }

            var entryItem = levelFilterItems.Where(x => x.Text.ToLower().Contains("entry")).SingleOrDefault();

            if (entryItem != null)
            {
                levelFilterItems.Remove(entryItem);
                levelFilterItems.Insert(0, entryItem);
            }

            s = 0;
            deliveryModelFilterItems = model.ProviderCourseRuns.GroupBy(x => x.DeliveryMode).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id    = "deliverymode-" + s++.ToString(),
                Value = r.Key,
                Text  = r.Key,
                Name  = "deliverymode"
            }).ToList();

            s = 0;
            venueFilterItems = model.ProviderCourseRuns.Where(x => !string.IsNullOrEmpty(x.Venue)).GroupBy(x => x.Venue).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id    = "venue-" + s++.ToString(),
                Value = r.Key,
                Text  = r.Key,
                Name  = "venue"
            }).ToList();

            attendanceModeFilterItems = model.ProviderCourseRuns.Where(x => x.AttendancePattern != AttendancePattern.Undefined.ToString()).GroupBy(x => x.AttendancePattern).OrderBy(x => x.Key).Select(r => new ProviderCoursesFilterItemModel()
            {
                Id    = "attendancepattern-" + s++.ToString(),
                Value = r.Key,
                Text  = r.Key,
                Name  = "attendancepattern"
            }).ToList();

            List <string> allRegionsList = new List <string>();

            var regionsForCourse = model.ProviderCourseRuns.GroupBy(x => x.Region).Where(x => !string.IsNullOrEmpty(x.Key)).OrderBy(x => x.Key).ToList();

            foreach (var regions in regionsForCourse)
            {
                var regionsList = regions.Key.Split(",");
                foreach (var region in regionsList)
                {
                    allRegionsList.Add(region.Trim());
                }
            }

            allRegionsList = allRegionsList.Distinct().ToList();

            s = 0;
            foreach (var regionValue in allRegionsList)
            {
                var regionId = _courseService.GetRegions().RegionItems
                               .Where(x => string.Equals(x.RegionName, regionValue, StringComparison.CurrentCultureIgnoreCase))
                               .Select(d => d.Id).FirstOrDefault();

                var regionFilterItem = new ProviderCoursesFilterItemModel
                {
                    Value = regionId,
                    Text  = regionValue,
                    Id    = "region-" + s++,
                    Name  = "region"
                };

                regionFilterItems.Add(regionFilterItem);
            }

            var notificationCourseName = string.Empty;
            var notificationAnchorTag  = string.Empty;

            if (courseRunId.HasValue && courseRunId.Value != Guid.Empty)
            {
                model.CourseRunId = courseRunId.Value.ToString();
                bool courseRunExists = model.ProviderCourseRuns.Any(x => x.CourseRunId == courseRunId.ToString());

                if (courseRunExists == false)
                {
                    model.NotificationTitle   = notificationTitle;
                    model.NotificationMessage = notificationMessage;
                }
                else
                {
                    notificationCourseName = Regex.Replace(
                        model.ProviderCourseRuns.Where(x => x.CourseRunId == courseRunId.Value.ToString()).Select(x => x.CourseName).FirstOrDefault().ToString(), "<.*?>"
                        , String.Empty);

                    notificationAnchorTag = courseRunId.HasValue
                  ? $"<a id=\"courseeditlink\" class=\"govuk-link\" href=\"#\" data-courserunid=\"{courseRunId}\" >{notificationMessage} {notificationCourseName}</a>"
                  : $"<a id=\"courseeditlink\" class=\"govuk-link\" href=\"#\">{notificationMessage} {notificationCourseName}</a>";
                    model.NotificationTitle   = notificationTitle;
                    model.NotificationMessage = notificationAnchorTag;
                }
            }
            else
            {
                notificationTitle     = string.Empty;
                notificationAnchorTag = string.Empty;
            }



            model.HasFilters        = false;
            model.Levels            = levelFilterItems;
            model.DeliveryModes     = deliveryModelFilterItems;
            model.Venues            = venueFilterItems;
            model.AttendancePattern = attendanceModeFilterItems;
            model.Regions           = regionFilterItems;

            //Setup backlink to go to the dashboard
            ViewBag.BackLinkController = "Home";
            ViewBag.BackLinkAction     = "Index";

            return(View(model));
        }