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;
  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 {
    print("on Submitting Custom form");
    try {
      emitLoading(progress: 30);
      // Emit either Loaded or Error

      emitSuccess(canSubmitAgain: 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;
    }
    print("Calculating 1RM");
    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();
  }
}