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

import 'mocks.dart';

main() {
  late SimExercisePlanRepository _exercisePlanRepository;
  late ExercisePlanBloc bloc;

  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);
    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, ModelChange.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);
    });*/
    });
  });
}
