import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
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/repository/workout_tree_repository.dart';
import 'package:test/test.dart';

import 'mocks.dart';

main() {
  SimExercisePlanRepository _exercisePlanRepository;
  ExercisePlanBloc bloc;

  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();
    WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
    bloc = ExercisePlanBloc(menuTreeRepository: menuTreeRepository);
    bloc.setExercisePlanRepository(_exercisePlanRepository);
    _customerId = 62;
    await setUpPlan();
  });

/*
  group('New Plan', () {
    test('Get Data', () async {
    });

    test('Add bloc', () async {

    });
    test('Update bloc', () async {

    });
    test('Delete bloc', () async {

    });

  });*/

  group('Existing Plan', () {
    test('Get Data', () async {
      bloc.customerId = 101;
      bloc.add(ExercisePlanLoad());

      final expectedResponse = [
        ExercisePlanLoading(),
        ExercisePlanReady()
      ];

      expectLater(
        bloc,
        emitsInOrder(expectedResponse),
      ).then((_) {
        expect(bloc.exercisePlanRepository.newPlan, false);
        expect(bloc.exercisePlanRepository.exercisePlan.name, "Test Plan2" );
        expect(bloc.exercisePlanRepository.exercisePlanDetails[4].weightEquation, "95");
        expect(Cache().getMyExercisePlan().name, "Test Plan2");
        expect(Cache().getMyExercisePlanDetails()[4].weightEquation, "95");
      });
    });

    test('Add bloc', () async {
      bloc.customerId = 101;

      bloc.exercisePlanRepository.getLastExercisePlan();
      bloc.exercisePlanRepository.getExercisePlanDetails();

      ExercisePlanDetail detail4 = ExercisePlanDetail(5);
      detail4.repeats = 20;
      detail4.weightEquation = "55";
      detail4.serie = 3;



      bloc.add(ExercisePlanAddExercise(exercisePlanDetail: detail4));

      final expectedResponse2 = [
        ExercisePlanLoading(),
        ExercisePlanReady()
      ];

      expectLater(
        bloc,
        emitsInOrder(expectedResponse2),
      ).then((_) {
        expect(bloc.exercisePlanRepository.newPlan, false);
        expect(bloc.exercisePlanRepository.exercisePlan.customerId, 101);
        expect(bloc.exercisePlanRepository.exercisePlanDetails.length, 3);
        expect(bloc.exercisePlanRepository.exercisePlanDetails[5].repeats, 20);
        expect(bloc.exercisePlanRepository.exercisePlanDetails[5].change, ExercisePlanDetailChange.add);
        expect(Cache()
          .getMyExercisePlan()
          .name, "Test Plan2");
        expect(Cache().getMyExercisePlanDetails()[5].weightEquation, "55");
        expect(Cache().getMyExercisePlanDetails()[5].repeats, 20);
      });
    });
    test('Update bloc', () async {
      bloc.customerId = 101;

      bloc.exercisePlanRepository.getLastExercisePlan();
      bloc.exercisePlanRepository.getExercisePlanDetails();
      bloc.exercisePlanRepository.exercisePlanDetails[3].repeats = 25;

      bloc.add(ExercisePlanAddExercise(exercisePlanDetail: bloc.exercisePlanRepository.exercisePlanDetails[3]));

      final expectedResponse2 = [
        ExercisePlanLoading(),
        ExercisePlanReady()
      ];

      expectLater(
        bloc,
        emitsInOrder(expectedResponse2),
      ).then((_) {
        expect(bloc.exercisePlanRepository.newPlan, false);
        expect(bloc.exercisePlanRepository.exercisePlanDetails[3].repeats, 25);
        expect(Cache().getMyExercisePlanDetails()[3].repeats, 25);
      });

    });
    test('Delete bloc', () async {
      bloc.customerId = 101;
      bloc.exercisePlanRepository.getLastExercisePlan();
      bloc.exercisePlanRepository.getExercisePlanDetails();
      bloc.add(ExercisePlanRemoveExercise(exercisePlanDetail: bloc.exercisePlanRepository.exercisePlanDetails[3]));

      final expectedResponse2 = [
        ExercisePlanLoading(),
        ExercisePlanReady()
      ];

      expectLater(
        bloc,
        emitsInOrder(expectedResponse2),
      ).then((_) {
        expect(bloc.exercisePlanRepository.newPlan, false);
        expect(bloc.exercisePlanRepository.exercisePlanDetails.length, 2);
        expect(bloc.exercisePlanRepository.exercisePlanDetails[3], isNull);
        expect(Cache().getMyExercisePlanDetails()[3], isNull);
      });
    });

  test('Test Trainee', () async {
    /*bloc.customerId = 102;
    bloc.exercisePlanRepository.customerId = 102;

    bloc.add(ExercisePlanLoad());

    final expectedResponse = [
      ExercisePlanLoading(),
      ExercisePlanReady()
    ];


    expectLater(
      bloc,
      emitsInOrder(expectedResponse),
    ).then((_) {
      expect(bloc.exercisePlanRepository.newPlan, true);
      expect(bloc.exercisePlanRepository.exercisePlanDetails.length, 0);
    });*/
  });

});

}