workouttest_app/lib/repository/training_plan_repository.dart

452 lines
18 KiB
Dart

import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer_training_plan.dart';
import 'package:aitrainer_app/model/customer_training_plan_details.dart';
import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/fitness_state.dart';
import 'package:aitrainer_app/model/training_plan.dart';
import 'package:aitrainer_app/model/training_plan_detail.dart';
import 'package:aitrainer_app/repository/training_plan_day_repository.dart';
import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/util/common.dart';
class TrainingPlanRepository {
ExerciseTree? parentTree;
List<TrainingPlan> getPlansByParent(String parent) {
final List<TrainingPlan> resultList = [];
final List<ExerciseTree>? exerciseTree = Cache().getExerciseTree();
int? parentId;
if (exerciseTree != null) {
exerciseTree.forEach((element) {
if (element.internalName == parent) {
parentId = element.treeId;
parentTree = element;
}
});
}
final List<TrainingPlan>? plans = Cache().getTrainingPlans();
if (plans != null && parentId != null) {
plans.forEach((element) {
if (element.treeId == parentId) {
resultList.add(element);
}
});
}
return resultList;
}
/// 1. deactivate old training plans - update all
/// 2. calculate customer_training_plan_details weights / repleats
/// 3. create new customer_training_plan
CustomerTrainingPlan? activateTrainingPlan(int trainingPlanId) {
print(" **** Activate Plan: $trainingPlanId");
// 1. deactivate
if (Cache().getCustomerTrainingPlans() != null) {
Cache().getCustomerTrainingPlans()!.forEach((plan) {
plan.active = false;
if (plan.customerTrainingPlanId != null) {
//TrainingPlanApi().updateCustomerTrainingPlan(plan, plan.customerTrainingPlanId!);
}
});
}
CustomerTrainingPlan plan = CustomerTrainingPlan();
plan.customerId = Cache().userLoggedIn!.customerId;
plan.trainingPlanId = trainingPlanId;
plan.active = true;
plan.status = "open";
plan.dateAdd = DateTime.now();
TrainingPlan? trainingPlan = this.getTrainingPlanById(trainingPlanId);
if (trainingPlan == null || trainingPlan.details == null) {
print("trainingPlan null");
return null;
}
plan.name = trainingPlan.nameTranslations[AppLanguage().appLocal.toString()];
// 3 calculate weights
int index = 0;
int exerciseTypeIdOrig = 0;
trainingPlan.details!.forEach((elem) {
List<CustomerTrainingPlanDetails> list = createDetail(plan, elem, exerciseTypeIdOrig, index);
exerciseTypeIdOrig = elem.exerciseTypeId;
list.forEach((element) {
plan.details.add(element);
index++;
});
});
Cache().myTrainingPlan = plan;
return plan;
}
CustomerTrainingPlanDetails? getDetailById(CustomerTrainingPlan? plan, int customerTrainingPlanDetailsId) {
CustomerTrainingPlanDetails? foundDetail;
if (plan == null || plan.details.length == 0 || customerTrainingPlanDetailsId == 0) {
return foundDetail;
}
for (var detail in plan.details) {
if (detail.customerTrainingPlanDetailsId == customerTrainingPlanDetailsId) {
foundDetail = detail;
break;
}
}
return foundDetail;
}
CustomerTrainingPlanDetails createAlternativeDetail(
CustomerTrainingPlan plan, CustomerTrainingPlanDetails detail, TrainingPlanDetail elem, int exerciseTypeId) {
CustomerTrainingPlanDetails alternativeDetail = CustomerTrainingPlanDetails();
alternativeDetail.copy(detail);
alternativeDetail.exerciseTypeId = exerciseTypeId;
alternativeDetail.exerciseType = Cache().getExerciseTypeById(exerciseTypeId);
if (elem.weight == -1) {
if (alternativeDetail.exerciseType!.unitQuantityUnit != null) {
alternativeDetail = getCalculatedWeightRepeats(elem.exerciseTypeId, alternativeDetail);
} else {
alternativeDetail.weight = 0;
}
} else if (elem.weight == -2) {
final CustomerTrainingPlanDetails calculated = this.isWeightCalculatedByExerciseType(elem.exerciseTypeId, alternativeDetail, plan);
if (calculated.weight != -1) {
alternativeDetail.weight = calculated.weight;
} else {
alternativeDetail.weight = -2;
}
} else {
alternativeDetail.weight = elem.weight;
}
//print("Detail $alternativeDetail exerciseType: ${alternativeDetail.exerciseType!.exerciseTypeId}");
return alternativeDetail;
}
List<CustomerTrainingPlanDetails> createDetail(CustomerTrainingPlan plan, TrainingPlanDetail elem, int exerciseTypeIdOrig, int index,
{bool changeExerciseType = false}) {
List<CustomerTrainingPlanDetails> list = [];
CustomerTrainingPlanDetails detail = CustomerTrainingPlanDetails();
detail.customerTrainingPlanDetailsId = ++index;
detail.trainingPlanDetailsId = elem.trainingPlanDetailId;
detail.exerciseTypeId = changeExerciseType ? exerciseTypeIdOrig : elem.exerciseTypeId;
detail.repeats = elem.repeats;
detail.set = elem.set;
detail.dayId = elem.dayId;
TrainingPlanDayRepository trainingPlanDayRepository = TrainingPlanDayRepository();
detail.day = trainingPlanDayRepository.getNameById(elem.dayId);
detail.parallel = elem.parallel;
detail.restingTime = elem.restingTime;
detail.exerciseType = Cache().getExerciseTypeById(detail.exerciseTypeId!);
detail.alternatives = Common.getExerciseTypeAlternatives(detail.exerciseTypeId);
if (elem.weight == -1) {
if (detail.exerciseType!.unitQuantityUnit != null) {
detail = getCalculatedWeightRepeats(elem.exerciseTypeId, detail);
} else {
detail.weight = 0;
}
} else if (elem.weight == -2) {
final CustomerTrainingPlanDetails calculated = this.isWeightCalculatedByExerciseType(elem.exerciseTypeId, detail, plan);
if (calculated.weight != -1) {
detail.weight = calculated.weight;
} else {
detail.weight = -2;
}
} else {
detail.weight = elem.weight;
}
print("Detail $detail exerciseType: ${detail.exerciseType!.exerciseTypeId}");
detail.state = ExercisePlanDetailState.start;
if (detail.weight != null && detail.weight! > 0) {
detail.baseOneRepMax = Common.calculate1RM(detail.weight!, detail.repeats!.toDouble());
}
// first repeat: 50% more
if (detail.weight != null && detail.weight! > 0 && exerciseTypeIdOrig != detail.exerciseTypeId && detail.repeats! > 0) {
CustomerTrainingPlanDetails firstDetail = CustomerTrainingPlanDetails();
firstDetail.copy(detail);
firstDetail.repeats = (detail.repeats! * 1.5).round();
firstDetail.baseOneRepMax = Common.calculate1RM(firstDetail.weight!, firstDetail.repeats!.toDouble());
firstDetail.set = 1;
detail.set = detail.set! - 1;
if (detail.set! > 0) {
index++;
}
detail.customerTrainingPlanDetailsId = index;
list.add(firstDetail);
}
if (detail.set! > 0) {
list.add(detail);
}
return list;
}
CustomerTrainingPlanDetails isWeightCalculatedByExerciseType(
int exerciseTypeId, CustomerTrainingPlanDetails detail, CustomerTrainingPlan plan) {
CustomerTrainingPlanDetails calculated = detail;
for (var element in plan.details) {
if (element.exerciseTypeId == exerciseTypeId) {
calculated = element;
break;
}
}
return calculated;
}
TrainingPlan? getTrainingPlanById(int trainingPlanId) {
TrainingPlan? plan;
if (Cache().getTrainingPlans() == null) {
return plan;
}
for (var trainingPlan in Cache().getTrainingPlans()!) {
if (trainingPlan.trainingPlanId == trainingPlanId) {
plan = trainingPlan;
break;
}
}
return plan;
}
int? getTrainingPlanByInternalName(String internalName) {
int? id;
if (Cache().getTrainingPlans() == null) {
return id;
}
for (var trainingPlan in Cache().getTrainingPlans()!) {
//print("internal ${trainingPlan.internalName}");
if (trainingPlan.internalName == internalName) {
id = trainingPlan.trainingPlanId;
break;
}
}
return id;
}
CustomerTrainingPlanDetails getCalculatedWeightRepeats(int exerciseTypeId, CustomerTrainingPlanDetails detail) {
double weight = -1;
if (Cache().getExercises() == null) {
detail.weight = weight;
detail.isTest = true;
return detail;
}
Exercise? lastExercise1RM;
DateTime dt = DateTime.now().subtract(Duration(days: 30));
List<Exercise> exercises = Cache().getExercises()!;
exercises.sort((a, b) {
// reverse
return a.dateAdd!.compareTo(b.dateAdd!);
});
exercises.forEach((exercise) {
if (exercise.exerciseTypeId == exerciseTypeId && exercise.dateAdd!.compareTo(dt) >= 0) {
detail.weight = weight;
lastExercise1RM = exercise;
//print("last exercise: $exercise");
}
});
if (lastExercise1RM == null || lastExercise1RM!.unitQuantity == null) {
detail.weight = weight;
detail.isTest = true;
return detail;
}
double oneRepMax = calculateMax1RMSameDay(lastExercise1RM!);
// Common.calculate1RM(lastExercise1RM!.unitQuantity!, lastExercise1RM!.quantity!);
//print("Exercise $exerciseTypeId - 1RM : $oneRepMax");
weight = oneRepMax * Common.get1RMPercent(detail.repeats!);
//print("Exercise $exerciseTypeId - weight : $weight");
//weight = Common.roundWeight(weight);
//detail.weight = Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), lastExercise1RM!.quantity!);
//weight = lastExercise1RM!.unitQuantity! * detail.repeats! / lastExercise1RM!.quantity!;
weight = Common.roundWeight(weight);
//print("Recaluclated weight ${detail.weight} - repeat: ${detail.repeats}");
//detail.repeats = Common.calculateQuantityByChangedWeight(oneRepMax, weight, detail.repeats!.toDouble());
detail.weight = weight;
return detail;
}
double calculateMax1RMSameDay(Exercise actual) {
List<Exercise> exercises = Cache().getExercises()!;
double max1RM = 0.0;
exercises.forEach((exercise) {
if (actual.exerciseTypeId == exercise.exerciseTypeId &&
actual.dateAdd!.year == exercise.dateAdd!.year &&
actual.dateAdd!.month == exercise.dateAdd!.month &&
actual.dateAdd!.day == exercise.dateAdd!.day) {
double oneRepMax = Common.calculate1RM(exercise.unitQuantity!, exercise.quantity!);
if (max1RM < oneRepMax) {
max1RM = oneRepMax;
}
}
});
return max1RM;
}
int getOriginalRepeats(int trainingPlanId, CustomerTrainingPlanDetails detail) {
TrainingPlan? plan = getTrainingPlanById(trainingPlanId);
if (plan == null) {
return 0;
}
int originalRepeats = 0;
plan.details!.forEach((element) {
if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) {
originalRepeats = element.repeats ?? 0;
}
});
return originalRepeats;
}
double getOriginalWeight(int trainingPlanId, CustomerTrainingPlanDetails detail) {
TrainingPlan? plan = getTrainingPlanById(trainingPlanId);
if (plan == null) {
return 0;
}
double originalWeight = 0;
plan.details!.forEach((element) {
if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) {
originalWeight = element.weight ?? 0;
}
});
return originalWeight;
}
CustomerTrainingPlanDetails recalculateDetailFixRepeats(int trainingPlanId, CustomerTrainingPlanDetails detail) {
TrainingPlan? plan = getTrainingPlanById(trainingPlanId);
if (plan == null) {
return detail;
}
int originalRepeats = getOriginalRepeats(trainingPlanId, detail);
detail.weight = Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), originalRepeats.toDouble());
detail.weight = Common.roundWeight(detail.weight!);
print("Recalculated weight: ${detail.weight}");
detail.repeats = originalRepeats;
return detail;
}
CustomerTrainingPlanDetails recalculateDetailFixRepeatsSet1(
int trainingPlanId, CustomerTrainingPlanDetails detail, CustomerTrainingPlanDetails detailWithData) {
TrainingPlan? plan = getTrainingPlanById(trainingPlanId);
if (plan == null) {
return detail;
}
int originalRepeats = getOriginalRepeats(trainingPlanId, detail);
detail.weight =
Common.calculateWeigthByChangedQuantity(detailWithData.weight!, detailWithData.repeats!.toDouble(), originalRepeats.toDouble());
detail.weight = Common.roundWeight(detail.weight!);
print("Recalculated weight: ${detail.weight}");
detail.repeats = originalRepeats;
return detail;
}
CustomerTrainingPlanDetails recalculateDetail(
int trainingPlanId, CustomerTrainingPlanDetails detail, CustomerTrainingPlanDetails nextDetail) {
CustomerTrainingPlanDetails recalculatedDetail = nextDetail;
// 1. get original repeats
// 1a get original plan
TrainingPlan? plan = getTrainingPlanById(trainingPlanId);
if (plan == null) {
return recalculatedDetail;
}
// 1.b get the original detail's repeat
int originalRepeats = detail.repeats!;
plan.details!.forEach((element) {
if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) {
originalRepeats = element.repeats ?? 0;
}
});
// 2 get recalculated repeats
recalculatedDetail.weight =
Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), originalRepeats.toDouble());
recalculatedDetail.weight = Common.roundWeight(recalculatedDetail.weight!);
print("recalculated repeats for $originalRepeats: ${recalculatedDetail.weight}");
//recalculatedDetail.repeats = originalRepeats;
return recalculatedDetail;
}
void generateTrainingPlan() {
int? trainingPlanId;
if (Cache().userLoggedIn == null) {
return;
}
bool isWoman = Cache().userLoggedIn!.sex == "w";
if (Cache().userLoggedIn!.goal == "shape_forming") {
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("women_shape_L1") : getTrainingPlanByInternalName("man_routine1");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("women_shape_L2") : getTrainingPlanByInternalName("man_routine3");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("women_shape_L3") : getTrainingPlanByInternalName("man_routine4");
} else {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("women_shape_L4") : getTrainingPlanByInternalName("man_routine2");
}
} else if (Cache().userLoggedIn!.goal == "muscle_endurance") {
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_se_l1") : getTrainingPlanByInternalName("man_se_l1");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_se_l2") : getTrainingPlanByInternalName("man_se_l2");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_se_l3") : getTrainingPlanByInternalName("man_se_l3");
} else {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_se_l4") : getTrainingPlanByInternalName("man_se_l4");
}
} else if (Cache().userLoggedIn!.goal == "gain_strength") {
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_power_l1") : getTrainingPlanByInternalName("man_power_l1");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_power_l2") : getTrainingPlanByInternalName("man_power_l2");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_power_l3") : getTrainingPlanByInternalName("man_power_l3");
} else {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_power_l4") : getTrainingPlanByInternalName("man_power_l4");
}
} else if (Cache().userLoggedIn!.goal == "gain_muscle") {
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_beginner") : getTrainingPlanByInternalName("beginner_man");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_beginner_split") : getTrainingPlanByInternalName("man_foundation");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_advanced") : getTrainingPlanByInternalName("basic_mass_building");
} else {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_routine2") : getTrainingPlanByInternalName("mass_building");
}
}
print("Generated plan $trainingPlanId fitness ${Cache().userLoggedIn!.fitnessLevel} - ${FitnessState.beginner}");
if (trainingPlanId != null) {
CustomerTrainingPlan? customerTrainingPlan = activateTrainingPlan(trainingPlanId);
if (customerTrainingPlan != null) {
Cache().myTrainingPlan = customerTrainingPlan;
Cache().saveMyTrainingPlan();
}
}
}
}