import 'dart:async';
import 'package:aitrainer_app/bloc/exercise_execute_plan/exercise_execute_plan_bloc.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/track.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

part 'exercise_execute_plan_add_event.dart';

part 'exercise_execute_plan_add_state.dart';

class ExerciseExecutePlanAddBloc extends Bloc<ExerciseExecutePlanAddEvent, ExerciseExecutePlanAddState> {
  final ExerciseRepository exerciseRepository;
  final ExercisePlanRepository exercisePlanRepository;
  final WorkoutMenuTree workoutTree;
  final ExerciseExecutePlanBloc planBloc;
  final int customerId;

  late Customer customer;
  int step = 1;
  int countSteps = 1;

  double? quantity;
  double? unitQuantity;

  double scrollOffset = 0;

  @override
  ExerciseExecutePlanAddBloc(
      {required this.exerciseRepository,
      required this.exercisePlanRepository,
      required this.customerId,
      required this.workoutTree,
      required this.planBloc})
      : super(ExerciseExecutePlanAddInitial());

  void init() {
    exerciseRepository.exerciseType = workoutTree.exerciseType;
    if (Cache().userLoggedIn!.customerId == customerId) {
      customer = Cache().userLoggedIn!;
    } else if (Cache().getTrainee()!.customerId == customerId) {
      customer = Cache().getTrainee()!;
    }
    exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType!);
    exerciseRepository.customer = customer;
    countSteps = exercisePlanRepository.getActualPlanDetail()!.serie!;
    if (exercisePlanRepository.getActualPlanDetail()!.weightEquation == null) {
      unitQuantity = 0.0;
    } else {
      unitQuantity = double.parse(exercisePlanRepository.getActualPlanDetail()!.weightEquation!);
    }
    quantity = exercisePlanRepository.getActualPlanDetail()!.repeats!.toDouble();

    exerciseRepository.setQuantity(quantity!);
    exerciseRepository.setUnitQuantity(unitQuantity!);
  }

  @override
  Stream<ExerciseExecutePlanAddState> mapEventToState(ExerciseExecutePlanAddEvent event) async* {
    try {
      if (event is ExerciseExecutePlanAddLoad) {
        yield ExerciseExecutePlanAddLoading();
        init();
        Track().track(TrackingEvent.my_exercise_plan_execute_open);
        yield ExerciseExecutePlanAddReady();
      } else if (event is ExerciseExecutePlanAddChangeQuantity) {
        yield ExerciseExecutePlanAddLoading();
        quantity = event.quantity;
        exerciseRepository.setQuantity(quantity!);
        yield ExerciseExecutePlanAddReady();
      } else if (event is ExerciseExecutePlanAddChangeUnitQuantity) {
        yield ExerciseExecutePlanAddLoading();
        unitQuantity = event.quantity;
        exerciseRepository.setUnitQuantity(unitQuantity!);
        yield ExerciseExecutePlanAddReady();
      } else if (event is ExerciseExecutePlanAddSubmit) {
        yield ExerciseExecutePlanAddLoading();
        exerciseRepository.exercise!.exercisePlanDetailId = exercisePlanRepository.getActualPlanDetail()!.exercisePlanDetailId;
        exerciseRepository.exercise!.unit = workoutTree.exerciseType!.unit;
        workoutTree.executed = true;
        await exerciseRepository.addExercise();
        exerciseRepository.initExercise();
        Track().track(TrackingEvent.my_exercise_plan_execute_save);
        step++;
        scrollOffset = step * 200.0;
        planBloc.add(ExerciseByPlanLoad());
        yield ExerciseExecutePlanAddReady();
      }
    } on Exception catch (e) {
      yield ExerciseExecutePlanAddError(message: e.toString());
    }
  }
}
