public async Task <IActionResult> Courses(
            string level,
            Guid?courseId,
            Guid?courseRunId,
            string notificationTitle,
            string notificationMessage)
        {
            Session.SetString("Option", "Courses");
            int?UKPRN = Session.GetInt32("UKPRN");

            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 Courses = courseResult.Value.SelectMany(o => o.Value).SelectMany(i => i.Value).ToList();

            var filteredCourses = from Course c in Courses.Where(c => BitmaskHelper.IsSet(c.CourseStatus, RecordStatus.Live)).ToList().OrderBy(x => x.QualificationCourseTitle)
                                  select c;

            var pendingCourses = from Course c in Courses.Where(c => c.CourseStatus == RecordStatus.MigrationPending || c.CourseStatus == RecordStatus.BulkUploadPending)
                                 select c;

            foreach (var course in filteredCourses)
            {
                var filteredCourseRuns = new List <CourseRun>();

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

                course.CourseRuns = filteredCourseRuns;
            }

            var levelFilters = filteredCourses.GroupBy(x => x.NotionalNVQLevelv2).OrderBy(x => x.Key).ToList();

            var levelFiltersForDisplay = new List <QualificationLevelFilterViewModel>();

            var courseViewModels = new List <CourseViewModel>();

            if (string.IsNullOrWhiteSpace(level))
            {
                level = levelFilters.FirstOrDefault()?.Key;
            }
            else
            {
                if (!filteredCourses.Any(x => x.NotionalNVQLevelv2 == level))
                {
                    level = levelFilters.FirstOrDefault()?.Key;
                }
            }

            foreach (var levels in levelFilters)
            {
                var lf = new QualificationLevelFilterViewModel()
                {
                    Facet      = levels.ToList().Count().ToString(),
                    IsSelected = level == levels.Key,
                    Value      = levels.Key,
                    Name       = $"Level {levels.Key}",
                };

                levelFiltersForDisplay.Add(lf);

                foreach (var course in levels)
                {
                    if (course.NotionalNVQLevelv2 == level)
                    {
                        var courseVM = new CourseViewModel()
                        {
                            Id                 = course.id.ToString(),
                            AwardOrg           = course.AwardOrgCode,
                            LearnAimRef        = course.LearnAimRef,
                            NotionalNVQLevelv2 = course.NotionalNVQLevelv2,
                            QualificationTitle = course.QualificationCourseTitle,
                            QualificationType  = course.QualificationType,
                            Facet              = course.CourseRuns.Count().ToString(),
                            CourseRuns         = course.CourseRuns.Select(y => new CourseRunViewModel
                            {
                                Id                = y.id.ToString(),
                                CourseId          = y.ProviderCourseID,
                                AttendancePattern = y.AttendancePattern.ToDescription(),
                                Cost              = y.Cost.HasValue ? $"£ {y.Cost.Value:0.00}" : string.Empty,
                                CourseName        = y.CourseName,
                                DeliveryMode      = y.DeliveryMode.ToDescription(),
                                Duration          = y.DurationValue.HasValue
                                        ? $"{y.DurationValue.Value} {y.DurationUnit.ToDescription()}"
                                        : $"0 {y.DurationUnit.ToDescription()}",
                                Venue = y.VenueId.HasValue
                                        ? FormatAddress(GetVenueByIdFrom(venueResult.Value, y.VenueId.Value))
                                        : string.Empty,
                                Region = y.Regions != null
                                        ? FormattedRegionsByIds(allRegions, y.Regions)
                                        : string.Empty,
                                StartDate = y.FlexibleStartDate
                                        ? "Flexible start date"
                                        : y.StartDate?.ToString("dd/MM/yyyy"),
                                StudyMode = y.StudyMode == Services.Models.Courses.StudyMode.Undefined
                                        ? string.Empty
                                        : y.StudyMode.ToDescription(),
                                Url = y.CourseURL
                            })
                                                 .OrderBy(y => y.CourseName)
                                                 .ToList()
                        };

                        courseViewModels.Add(courseVM);
                    }
                }
            }

            if (string.IsNullOrWhiteSpace(level))
            {
                level = levelFiltersForDisplay.FirstOrDefault()?.Value;
                levelFiltersForDisplay.ForEach(x => { if (x.Value == level)
                                                      {
                                                          x.IsSelected = true;
                                                      }
                                               });
            }

            courseViewModels.OrderBy(x => x.QualificationTitle).ToList();

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

            if (courseId.HasValue && courseId.Value != Guid.Empty)
            {
                notificationCourseName = QualificationTitleByCourseId(courseViewModels, courseId.ToString());

                if (courseRunId.HasValue && courseRunId.Value != Guid.Empty)
                {
                    var courseRuns = courseViewModels.Find(x => x.Id == courseId.Value.ToString())?.CourseRuns;
                    notificationCourseName = CourseNameByCourseRunId(courseRuns, courseRunId.ToString());
                }
            }

            if (!courseRunId.HasValue)
            {
                notificationMessage = string.Empty;
            }

            notificationCourseName = Regex.Replace(notificationCourseName, "<.*?>", String.Empty);
            notificationAnchorTag  = courseRunId.HasValue
                ? $"<a id=\"courseeditlink\" class=\"govuk-link\" href=\"#\" data-courseid=\"{courseId}\" data-courserunid=\"{courseRunId}\" >{notificationMessage} {notificationCourseName}</a>"
                : $"<a id=\"courseeditlink\" class=\"govuk-link\" href=\"#\" data-courseid=\"{courseId}\">{notificationMessage} {notificationCourseName}</a>";

            var viewModel = new YourCoursesViewModel
            {
                Heading             = $"Level {level}",
                HeadingCaption      = "Your courses",
                Courses             = courseViewModels ?? new List <CourseViewModel>(),
                LevelFilters        = levelFiltersForDisplay,
                NotificationTitle   = notificationTitle,
                NotificationMessage = notificationAnchorTag,
                PendingCoursesCount = pendingCourses?.Count()
            };

            return(View(viewModel));
        }
        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));
        }