public async Task <WorkoutPlan> GenerateWorkoutPlanAsync(GenerateWorkoutPlanInputModel inputModel)
        {
            WorkoutPlan result;

            switch (inputModel.WeekdaysCount)
            {
            case 1:
                result =
                    await this.GenerateShortPlan(inputModel); break;

            case 2:
                result =
                    await this.GenerateShortPlan(inputModel); break;

            default:
                result =
                    await this.GenerateLongWeekPlan(inputModel); break;
            }

            await this.workoutPlansRepository.AddAsync(result);

            await this.workoutPlansRepository.SaveChangesAsync();

            await this.notificationsService.CreateNotificationAsync(
                "You have sucessfully generated a workout program",
                $"/WorkoutPlans/Details/{result.Id}",
                result.UserId);

            return(result);
        }
        private async Task <WorkoutPlan> GenerateShortPlan(GenerateWorkoutPlanInputModel inputModel)
        {
            var workoutPlan = new WorkoutPlan()
            {
                ExpireDate = DateTime.UtcNow.AddDays(inputModel.DurationInDays),
                DaysInWeek = inputModel.WeekdaysCount,
                UserId     = inputModel.UserId,
            };

            switch (inputModel.Experience)
            {
            case Experience.Beginner:
                workoutPlan.Difficulty = Difficulty.Easy;
                break;

            case Experience.Intermediate:
                workoutPlan.Difficulty = Difficulty.Medium;
                break;

            case Experience.Advanced:
                workoutPlan.Difficulty = Difficulty.Hard;
                break;
            }

            for (int i = 0; i < inputModel.WeekdaysCount; i++)
            {
                TrainingDay trainingDay = await this.GenerateFullBodyDay(inputModel.Goal, workoutPlan.Difficulty, workoutPlan);

                workoutPlan.TrainingDays.Add(trainingDay);
            }

            return(workoutPlan);
        }
        public async Task <IActionResult> GenerateWorkoutPlan(GenerateWorkoutPlanInputModel inputModel)
        {
            if (!this.ModelState.IsValid)
            {
                return(this.View(inputModel));
            }

            var plan = await this.workoutPlansService.GenerateWorkoutPlanAsync(inputModel);

            return(this.Redirect($"/WorkoutPlans/Details/{plan.Id}"));
        }
        public async Task <IActionResult> GenerateWorkoutPlan()
        {
            string userId = this.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

            if (await this.workoutPlansService.HasUserActivePlan(userId))
            {
                return(this.Redirect($"/WorkoutPlans/Index?redirected=true"));
            }

            var viewModel = new GenerateWorkoutPlanInputModel();

            viewModel.UserId = userId;
            return(this.View(viewModel));
        }
        public async Task GenerateWorkoutPlanAsyncShouldGenerateProgramWuthAllGoals(Goal goal)
        {
            var service = await this.Before();

            var user = new ApplicationUser();

            var inputModel = new GenerateWorkoutPlanInputModel()
            {
                DurationInDays = 30,
                Experience     = Experience.Intermediate,
                Goal           = goal,
                UserId         = user.Id,
                WeekdaysCount  = 4,
            };

            var result = await service.GenerateWorkoutPlanAsync(inputModel);

            Assert.NotNull(result.Id);
        }
        public async Task GenerateWorkoutPlanAsyncShouldGenerateProgramForDifferentDaysCount(int daysCount)
        {
            var service = await this.Before();

            var user = new ApplicationUser();

            var inputModel = new GenerateWorkoutPlanInputModel()
            {
                DurationInDays = 30,
                Experience     = Experience.Intermediate,
                Goal           = Goal.Mantain,
                UserId         = user.Id,
                WeekdaysCount  = daysCount,
            };

            var result = await service.GenerateWorkoutPlanAsync(inputModel);

            Assert.NotNull(result.Id);
        }
        public async Task DeleteAsyncShouldDelete()
        {
            var service = await this.Before();

            var user = new ApplicationUser();

            var inputModel = new GenerateWorkoutPlanInputModel()
            {
                DurationInDays = 30,
                Experience     = Experience.Intermediate,
                Goal           = Goal.Mantain,
                UserId         = user.Id,
                WeekdaysCount  = 4,
            };

            var plan = await service.GenerateWorkoutPlanAsync(inputModel);

            var deletedPlan = await service.DeleteAsync(plan.Id);

            Assert.True(deletedPlan.IsDeleted);
        }
        public async Task GetWorkoutPlanAsyncShouldGiveTheCorrectPlan()
        {
            var service = await this.Before();

            var user = new ApplicationUser();

            var inputModel = new GenerateWorkoutPlanInputModel()
            {
                DurationInDays = 30,
                Experience     = Experience.Intermediate,
                Goal           = Goal.Mantain,
                UserId         = user.Id,
                WeekdaysCount  = 4,
            };

            var plan = await service.GenerateWorkoutPlanAsync(inputModel);

            var result = await service.GetWorkoutPlanAsync <TestWorkoutPlanModel>(plan.Id);

            Assert.Equal(plan.Id, result.Id);
            Assert.Equal(4, result.TrainingDaysCount);
        }
        private async Task <WorkoutPlan> GenerateLongWeekPlan(GenerateWorkoutPlanInputModel inputModel)
        {
            var workoutPlan = new WorkoutPlan()
            {
                ExpireDate = DateTime.UtcNow.AddDays(inputModel.DurationInDays),
                DaysInWeek = inputModel.WeekdaysCount,
                UserId     = inputModel.UserId,
            };

            switch (inputModel.Experience)
            {
            case Experience.Beginner:
                workoutPlan.Difficulty = Difficulty.Easy;
                break;

            case Experience.Intermediate:
                workoutPlan.Difficulty = Difficulty.Medium;
                break;

            case Experience.Advanced:
                workoutPlan.Difficulty = Difficulty.Hard;
                break;
            }

            var days         = new List <Day>();
            var muscleGroups = new List <List <ExerciseType> >();

            switch (inputModel.WeekdaysCount)
            {
            case 3:
            {
                days.Add(Day.Monday);
                days.Add(Day.Wednesday);
                days.Add(Day.Friday);
                break;
            }

            case 4:
            {
                days.Add(Day.Monday);
                days.Add(Day.Tuesday);
                days.Add(Day.Thursday);
                days.Add(Day.Friday);
                break;
            }

            case 5:
            {
                days.Add(Day.Monday);
                days.Add(Day.Tuesday);
                days.Add(Day.Wednesday);
                days.Add(Day.Thursday);
                days.Add(Day.Friday);
                break;
            }

            case 6:
            {
                days.Add(Day.Monday);
                days.Add(Day.Tuesday);
                days.Add(Day.Wednesday);
                days.Add(Day.Thursday);
                days.Add(Day.Friday);
                days.Add(Day.Saturday);
                break;
            }

            case 7:
            {
                days.Add(Day.Monday);
                days.Add(Day.Tuesday);
                days.Add(Day.Wednesday);
                days.Add(Day.Thursday);
                days.Add(Day.Friday);
                days.Add(Day.Saturday);
                days.Add(Day.Sunday);
                break;
            }

            default:
                break;
            }

            muscleGroups = this.GenerateMuscleGroupsPerDay(days.Count);
            for (int i = 0; i < days.Count; i++)
            {
                TrainingDay trainingDay =
                    await this.GenerateSeparateMusclesDay(inputModel.Goal, workoutPlan.Difficulty, workoutPlan, days[i], muscleGroups[i]);

                workoutPlan.TrainingDays.Add(trainingDay);
            }

            return(workoutPlan);
        }