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/training_plan.dart';
import 'package:aitrainer_app/service/training_plan_service.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

  Future<CustomerTrainingPlan?> activateTrainingPlan(int trainingPlanId) async {
    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();
    plan.name = getTrainingPlanById(trainingPlanId)!.nameTranslations["hu"];

    TrainingPlan? trainingPlan = this.getTrainingPlanById(trainingPlanId);
    if (trainingPlan == null || trainingPlan.details == null) {
      return null;
    }

    // 3 calculate weights
    trainingPlan.details!.forEach((elem) {
      CustomerTrainingPlanDetails detail = CustomerTrainingPlanDetails();
      detail.exerciseTypeId = elem.exerciseTypeId;
      detail.repeats = elem.repeats;
      detail.set = elem.set;
      detail.day = elem.day;
      detail.parallel = elem.parallel;
      detail.restingTime = elem.restingTime;
      detail.exerciseType = Cache().getExerciseTypeById(detail.exerciseTypeId!);
      if (detail.exerciseType!.unitQuantityUnit != null) {
        detail = getCalculatedWeightRepeats(elem.exerciseTypeId, detail);
      } else {
        detail.weight = 0;
      }
      //print("Detail $detail exerciseType: ${detail.exerciseType}");

      detail.state = ExercisePlanDetailState.start;
      plan.details.add(detail);
    });

    Cache().myTrainingPlan = plan;

    //TrainingPlanApi().saveCustomerTrainingPlan(plan);
    return plan;
  }

  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;
  }

  CustomerTrainingPlanDetails getCalculatedWeightRepeats(int exerciseTypeId, CustomerTrainingPlanDetails detail) {
    double weight = -1;
    if (Cache().getExercises() == null) {
      detail.weight = weight;
      return detail;
    }

    Exercise? lastExercise1RM;
    Cache().getExercises()!.forEach((exercise) {
      if (exercise.exercisePlanDetailId == 0 && exercise.exerciseTypeId == exerciseTypeId) {
        detail.weight = weight;
        lastExercise1RM = exercise;
      }
    });

    if (lastExercise1RM == null || lastExercise1RM!.unitQuantity == null) {
      detail.weight = weight;
      return detail;
    }

    double oneRepMax = 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.repeats = Common.calculateQuantityByChangedWeight(oneRepMax, weight, detail.repeats!.toDouble());

    detail.weight = weight;
    return detail;
  }
}
