import 'package:intl/intl.dart'; import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/customer_training_plan_details.dart'; import 'package:aitrainer_app/model/exercise_plan_detail.dart'; import 'package:aitrainer_app/model/training_evaluation_exercise.dart'; import 'package:aitrainer_app/util/common.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; part 'training_evaluation_event.dart'; part 'training_evaluation_state.dart'; class TrainingEvaluationBloc extends Bloc with Common { final TrainingPlanBloc trainingPlanBloc; final String day; TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial()) { _load(); on(_onLoad); } String duration = "-"; String totalLift = "0"; String maxTotalLift = "0"; String maxRepeats = "0"; String totalRepeats = "0"; DateTime? end; List evaluationList = []; void _onLoad(TrainingEvaluationLoad event, Emitter emit) async { getDuration(); getTotalLift(); getMaxRepeats(); getTotalRepeats(); createEvaluationData(); getMaxLift(); if (end == null || DateTime.now().difference(end!).inMinutes > 5) { emit(TrainingEvaluationReady()); } else { emit(TrainingEvaluationVictoryReady()); } } void _load() { getDuration(); getTotalLift(); getMaxRepeats(); getTotalRepeats(); createEvaluationData(); getMaxLift(); /* if (end == null || DateTime.now().difference(end!).inMinutes > 5) { emit(TrainingEvaluationReady()); } else { emit(TrainingEvaluationVictoryReady()); } */ } void createEvaluationData() { if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { return; } trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { if (element.exerciseTypeId != null) { if (!findExerciseInEvaluationList(element.exerciseTypeId!)) { addEvaluationExercise(element); } } }); } bool findExerciseInEvaluationList(int exerciseTypeId) { bool found = false; for (var exercise in evaluationList) { if (exercise.exerciseTypeId == exerciseTypeId) { found = true; break; } } return found; } void addEvaluationExercise(CustomerTrainingPlanDetails detail) { TrainingEvaluationExercise exercise = TrainingEvaluationExercise(); exercise.exerciseTypeId = detail.exerciseTypeId!; exercise.name = detail.exerciseType!.nameTranslation; exercise.state = detail.state; if (detail.state.equalsTo(ExercisePlanDetailState.skipped)) { TrainingEvaluationExercise exercise = TrainingEvaluationExercise(); exercise.exerciseTypeId = detail.exerciseTypeId!; exercise.name = detail.exerciseType!.nameTranslation; exercise.state = ExercisePlanDetailState.skipped; exercise.type = TrainingEvaluationExerciseType.weightBased; this.evaluationList.add(exercise); } else { if (detail.exerciseType!.unitQuantityUnit == null || detail.weight == null) { exercise.type = TrainingEvaluationExerciseType.repeatBased; exercise.repeats = detail.repeats; exercise.maxRepeats = getMaxRepeatsByExerciseType(detail.exerciseTypeId!); exercise.trend = getTrendEvaluationRepeats(exercise); } else { exercise.type = TrainingEvaluationExerciseType.weightBased; exercise.oneRepMax = calculate1RM(detail.weight!, detail.repeats!.toDouble()); exercise.max1RM = getMax1RMByExerciseType(detail.exerciseTypeId!); exercise.totalLift = getTotalLiftBySameExercise(detail.exerciseTypeId!); exercise.maxTotalLift = getMaxTotalLiftByExerciseType(detail.exerciseTypeId!); exercise.trend = this.getTrendWeight(exercise.oneRepMax!, exercise.max1RM, exercise.totalLift, exercise.maxTotalLift); } exercise.trendText = getTrendText(exercise.trend!); exercise.trendColor = getTrendColor(exercise.trend!); this.evaluationList.add(exercise); } } double getTrendEvaluationRepeats(TrainingEvaluationExercise exercise) { double rate = exercise.repeats! / exercise.maxRepeats!; return rate; } String getTrendText(double rate) { if (rate > 1.20) { return "Strongly Growing"; } else if (rate > 1.05) { return "Growing"; } else if (rate < 0.80) { return "Strongly Sinking"; } else if (rate < 0.95) { return "Sinking"; } else { return "Stagnant"; } } Color getTrendColor(double rate) { if (rate > 1.20) { return Colors.green[900]!; } else if (rate > 1.05) { return Colors.green[300]!; } else if (rate < 0.80) { return Colors.red[900]!; } else if (rate < 0.95) { return Colors.red[400]!; } else { return Colors.white; } } void getDuration() { if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { return; } int index = 0; DateTime? start; trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { if (element.state.equalsTo(ExercisePlanDetailState.finished)) { if (index++ == 0) { start = element.exercises[0].dateAdd!; } else { if (element.exercises.length > 0) { this.end = element.exercises[element.exercises.length - 1].dateAdd!; } } //print("Exercise Date ${element.exercises[0].dateAdd!}"); } }); if (start == null) { this.duration = "00:00:00"; } else if (this.end == null) { this.duration = "00:01:00"; this.end = start; } else { this.duration = end!.difference(start!).inMinutes.toString(); } } void getTotalLift() { if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { return; } double total = 0; trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unitQuantityUnit != null) { total += element.weight! * element.repeats!; } }); totalLift = total.toStringAsFixed(0); } double getTotalLiftBySameExercise(int exerciseTypeId) { if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { return 0; } double total = 0; trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { if (element.exerciseTypeId == exerciseTypeId) { if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unitQuantityUnit != null) { total += element.weight! * element.repeats!; } } }); return total; } void getMaxLift() { if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { return; } double max = 0; trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unitQuantityUnit != null) { if (max < element.weight!) { max = element.weight!; } } }); maxTotalLift = max.toStringAsFixed(0); } void getMaxRepeats() { if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { return; } int max = 0; trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unit != "second") { print("Repeats ${element.repeats}"); if (max < element.repeats!) { max = element.repeats!; } } }); maxRepeats = max.toStringAsFixed(0); } void getTotalRepeats() { if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { return; } int total = 0; trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unit != "second") { print("Repeats ${element.repeats}"); total += element.repeats!; } }); totalRepeats = total.toStringAsFixed(0); } double getMaxTotalLiftByExerciseType(int exerciseTypeId) { if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) { return 0; } var now = new DateTime.now(); var formatter = new DateFormat('yyyy-MM-dd'); final String formattedToday = formatter.format(now); double maxTotal = 0; Cache().getExercises()!.forEach((element) { if (element.dateAdd != null) { final String formattedExerciseDate = formatter.format(element.dateAdd!); if (element.exerciseTypeId == exerciseTypeId && formattedToday != formattedExerciseDate) { final double total = element.quantity! * element.unitQuantity!; if (maxTotal < total) { maxTotal = total; } } } }); return maxTotal; } double getMax1RMByExerciseType(int exerciseTypeId) { if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) { return 0; } var now = new DateTime.now(); var formatter = new DateFormat('yyyy-MM-dd'); final String formattedToday = formatter.format(now); double max1RM = 0; Cache().getExercises()!.forEach((element) { if (element.dateAdd != null) { final String formattedExerciseDate = formatter.format(element.dateAdd!); if (element.exerciseTypeId == exerciseTypeId && formattedToday != formattedExerciseDate) { final double oneRepMax = calculate1RM(element.unitQuantity!, element.quantity!); if (max1RM < oneRepMax) { max1RM = oneRepMax; } } } }); return max1RM; } int getMaxRepeatsByExerciseType(int exerciseTypeId) { if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) { return 0; } int maxRepeats = 0; Cache().getExercises()!.forEach((element) { if (element.exerciseTypeId == exerciseTypeId) { final int repeats = element.quantity!.toInt(); if (maxRepeats < repeats) { maxRepeats = repeats; } } }); return maxRepeats; } double getOneRepMax(CustomerTrainingPlanDetails detail) { if (detail.weight == null) { return 0; } return calculate1RM(detail.weight!, detail.repeats!.toDouble()); } double getTotalLiftExercise(CustomerTrainingPlanDetails detail) { if (detail.weight == null) { return 0; } return detail.weight! * detail.repeats!; } double getTrendWeight(double oneRepMax, max1RM, totalLift, maxTotalLift) { final double oneRepMaxRate = oneRepMax / max1RM; //double totalLiftRate = totalLift / maxTotalLift; return oneRepMaxRate; } }