import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_plan.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:test/test.dart';
import 'mocks.dart';

main() {
  late SimExercisePlanRepository _exercisePlanRepository;
  late int _customerId;

  Future<void> setUpPlan() async {
    final String planName2 = "Test Plan2";
    ExercisePlan plan2 = ExercisePlan(planName2, 101);
    _exercisePlanRepository.setCustomerId(101);
    _exercisePlanRepository.setExercisePlan(plan2);

    ExercisePlanDetail detail3 = ExercisePlanDetail(3);
    detail3.repeats = 23;
    detail3.weightEquation = "60";
    detail3.serie = 4;

    _exercisePlanRepository.setActualPlanDetail(detail3);
    _exercisePlanRepository.addDetailToPlan();

    ExercisePlanDetail detail4 = ExercisePlanDetail(4);
    detail4.repeats = 12;
    detail4.weightEquation = "95";
    detail4.serie = 3;

    _exercisePlanRepository.setActualPlanDetail(detail4);
    _exercisePlanRepository.addDetailToPlan();
    await _exercisePlanRepository.saveExercisePlan();
  }

  setUp(() async {
    _exercisePlanRepository = SimExercisePlanRepository();
    _customerId = 62;
    await setUpPlan();
  });

  group('New Plan', () {
    test('add new plan and plan details and save', () async {
      final String planName = "Boss Test Plan";
      ExercisePlan plan = ExercisePlan(planName, _customerId);
      _exercisePlanRepository.setExercisePlan(plan);

      ExercisePlanDetail detail1 = ExercisePlanDetail(37);
      detail1.repeats = 12;
      detail1.weightEquation = "80";
      detail1.serie = 4;

      _exercisePlanRepository.setActualPlanDetail(detail1);
      _exercisePlanRepository.addDetailToPlan();

      ExercisePlanDetail detail2 = ExercisePlanDetail(55);
      detail2.repeats = 13;
      detail2.weightEquation = "55";
      detail2.serie = 3;

      _exercisePlanRepository.setActualPlanDetail(detail2);
      _exercisePlanRepository.addDetailToPlan();

      await _exercisePlanRepository.saveExercisePlan();

      expect(_exercisePlanRepository.getExercisePlan()!.name, planName);
      expect(_exercisePlanRepository.getExercisePlan()!.exercisePlanId! > 0, true);

      ExercisePlanDetail detail = _exercisePlanRepository.getExercisePlanDetailByExerciseId(55)!;
      expect(detail.exercisePlanId, _exercisePlanRepository.getExercisePlan()!.exercisePlanId);
    });
    test('save new plan and plan details second', () async {
      int customerId = 100;
      final String planName = "Boss2 Test Plan";
      ExercisePlan plan = ExercisePlan(planName, customerId);
      _exercisePlanRepository.setExercisePlan(plan);

      ExercisePlanDetail detail1 = ExercisePlanDetail(12);
      detail1.repeats = 10;
      detail1.weightEquation = "40";
      detail1.serie = 5;

      _exercisePlanRepository.setActualPlanDetail(detail1);
      _exercisePlanRepository.addDetailToPlan();

      ExercisePlanDetail detail2 = ExercisePlanDetail(13);
      detail2.repeats = 33;
      detail2.weightEquation = "15";
      detail2.serie = 3;
      _exercisePlanRepository.setActualPlanDetail(detail2);
      _exercisePlanRepository.addDetailToPlan();

      await _exercisePlanRepository.saveExercisePlan();

      expect(_exercisePlanRepository.getExercisePlan()!.name, planName);
      expectLater(_exercisePlanRepository.getExercisePlan()!.exercisePlanId! > 0, true);

      ExercisePlanDetail detail = _exercisePlanRepository.getExercisePlanDetailByExerciseId(13)!;
      expect(detail.exercisePlanId, _exercisePlanRepository.getExercisePlan()!.exercisePlanId);
      expect(detail.repeats, 33);
    });
  });

  group('Existing Plan', () {
    test('Get Last Plan and Details from DB', () async {
      ExercisePlan? exercisePlan = await _exercisePlanRepository.getLastExercisePlan();
      expect(exercisePlan!.customerId, 101);

      await _exercisePlanRepository.getExercisePlanDetails();
      expect(_exercisePlanRepository.exercisePlanDetails[3]!.repeats, 23);
      expect(_exercisePlanRepository.exercisePlanDetails[4]!.weightEquation, "95");

      //Test Cache
      expect(Cache().getMyExercisePlan()!.name, "Test Plan2");
      expect(Cache().getMyExercisePlanDetails()[3]!.weightEquation, "60");
    });

    test('Add new PlanDetail', () async {
      _exercisePlanRepository.newPlan = false;
      ExercisePlanDetail detail4 = ExercisePlanDetail(5);
      detail4.repeats = 6;
      detail4.weightEquation = "105";
      detail4.serie = 3;

      _exercisePlanRepository.setActualPlanDetail(detail4);
      _exercisePlanRepository.addDetailToPlan();

      await _exercisePlanRepository.saveExercisePlan();

      expect(_exercisePlanRepository.getExercisePlan()!.name, "Test Plan2");
      expect(Cache().getMyExercisePlanDetails()[5]!.weightEquation, "105");
      expect(Cache().getMyExercisePlanDetails()[5]!.repeats, 6);
    });

    test('Delete from PlanDetails', () async {
      _exercisePlanRepository.removeExerciseTypeFromPlanByExerciseTypeId(4);
      _exercisePlanRepository.saveExercisePlan();

      expect(_exercisePlanRepository.exercisePlanDetails[4]!.change, ModelChange.delete);
      expect(Cache().getMyExercisePlanDetails()[4], isNull);
    });
  });
}
