import 'dart:math';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';

class CustomExerciseFormBloc extends FormBloc<String, String> {
  final ExerciseRepository exerciseRepository;
  bool loading = false;
  final quantityField = TextFieldBloc(
    validators: [
      FieldBlocValidators.required,
    ],
  );

  final unitQuantityField = TextFieldBloc(
    validators: [
      FieldBlocValidators.required,
    ],
  );

  //1RM calculated Fields
  final rmWendlerField = TextFieldBloc(
    initialValue: "0",
  );
  final rmMayhewField = TextFieldBloc(initialValue: "0");
  final rmOconnerField = TextFieldBloc(initialValue: "0");
  final rmWathenField = TextFieldBloc(initialValue: "0");
  final rmAverageField = TextFieldBloc(initialValue: "0");
  final rm90Field = TextFieldBloc(initialValue: "0");
  final rm80Field = TextFieldBloc(initialValue: "0");
  final rm75Field = TextFieldBloc(initialValue: "0");
  final rm75WendlerField = TextFieldBloc(initialValue: "0");
  final rm75OconnorField = TextFieldBloc(initialValue: "0");
  final rm70Field = TextFieldBloc(initialValue: "0");
  final rm60Field = TextFieldBloc(initialValue: "0");
  final rm50Field = TextFieldBloc(initialValue: "0");

  CustomExerciseFormBloc({this.exerciseRepository}) {
    addFieldBlocs(fieldBlocs: [
      quantityField,
      unitQuantityField,
      rmWendlerField,
      rmMayhewField,
      rmOconnerField,
      rmWathenField,
      rmAverageField,
      rm90Field,
      rm80Field,
      rm70Field,
      rm75Field,
      rm75WendlerField,
      rm75OconnorField,
      rm60Field,
      rm50Field
    ]);

    quantityField.onValueChanges(onData: (previous, current) async* {
      exerciseRepository.setQuantity(current.valueToDouble);
      calculate1RM();
    });

    unitQuantityField.onValueChanges(onData: (previous, current) async* {
      exerciseRepository.setUnitQuantity(current.valueToDouble);
      calculate1RM();
    });
  }

  @override
  void onSubmitting() async {
    try {
      loading = true;
      emitLoading(progress: 30);
      // Emit either Loaded or Error

      emitSuccess(canSubmitAgain: false);
      loading = false;
    } on Exception catch (ex) {
      emitFailure(failureResponse: ex.toString());
    }
  }

  void calculate1RM() {
    double weight = exerciseRepository.exercise.unitQuantity;
    double repeat = exerciseRepository.exercise.quantity;
    if (weight == 0 || repeat == 0) {
      return;
    }
    exerciseRepository.rmWendler = weight * repeat * 0.0333 + weight;
    rmWendlerField.updateValue(exerciseRepository.rmWendler.toStringAsFixed(1));
    exerciseRepository.rmOconner = weight * (1 + repeat / 40);
    rmOconnerField.updateValue(exerciseRepository.rmOconner.toStringAsFixed(1));
    exerciseRepository.rmMayhew = 100 * weight / (52.2 + 41.9 * pow(e, -0.055 * repeat));
    rmMayhewField.updateValue(exerciseRepository.rmMayhew.toStringAsFixed(1));
    exerciseRepository.rmWathen = 100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat));
    rmWathenField.updateValue(exerciseRepository.rmWathen.toStringAsFixed(1));
    double average = (exerciseRepository.rmWendler + exerciseRepository.rmOconner) / 2;
    rmAverageField.updateValue(average.toStringAsFixed(1));
    rm90Field.updateValue((average * 0.9).toStringAsFixed(1));
    rm80Field.updateValue((average * 0.8).toStringAsFixed(1));
    rm75Field.updateValue((average * 0.75).toStringAsFixed(1));
    rm75OconnorField.updateValue((exerciseRepository.rmOconner * 0.75).toStringAsFixed(1));
    rm75WendlerField.updateValue((exerciseRepository.rmWendler * 0.75).toStringAsFixed(1));
    rm70Field.updateValue((average * 0.7).toStringAsFixed(1));
    rm60Field.updateValue((average * 0.6).toStringAsFixed(1));
    rm50Field.updateValue((average * 0.5).toStringAsFixed(1));
  }

  //@override
  Future<void> close() {
    quantityField.close();
    unitQuantityField.close();

    rmWendlerField.close();
    rmMayhewField.close();
    rmOconnerField.close();
    rmWathenField.close();
    rmAverageField.close();
    rm90Field.close();
    rm80Field.close();
    rm75WendlerField.close();
    rm75OconnorField.close();
    rm75Field.close();
    rm70Field.close();
    rm60Field.close();
    rm50Field.close();
    return super.close();
  }
}