import 'dart:collection';

import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart';
import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_ability.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bmi_widget.dart';
import 'package:aitrainer_app/widgets/bmr_widget.dart';
import 'package:aitrainer_app/widgets/bottom_bar_multiple_exercises.dart';
import 'package:aitrainer_app/widgets/dialog_common.dart';
import 'package:aitrainer_app/widgets/exercise_save.dart';
import 'package:aitrainer_app/widgets/size_widget.dart';
import 'package:aitrainer_app/widgets/tutorial_widget.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';

class ExerciseNewPage extends StatefulWidget {
  _ExerciseNewPageState createState() => _ExerciseNewPageState();
}

class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
  @override
  Widget build(BuildContext context) {
    final ExerciseType exerciseType = ModalRoute.of(context)!.settings.arguments as ExerciseType;
    // ignore: close_sinks
    final menuBloc = BlocProvider.of<MenuBloc>(context);
    setContext(context);

    return BlocProvider(
        create: (context) => ExerciseNewBloc(
            exerciseRepository: ExerciseRepository(),
            menuBloc: menuBloc,
            customerRepository: CustomerRepository(),
            exerciseType: exerciseType)
          ..add(ExerciseNewLoad()),
        child: BlocConsumer<ExerciseNewBloc, ExerciseNewState>(
          listener: (context, state) {
            if (state is ExerciseNewError) {
              showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return DialogCommon(
                      warning: true,
                      title: t("Warning"),
                      descriptions: t(state.message),
                      text: "OK",
                      onTap: () => Navigator.of(context).pushNamed("login"),
                      onCancel: () => {
                        Navigator.of(context).pop(),
                      },
                    );
                  });
            } else if (state is ExerciseNewSaved) {
              final LinkedHashMap args = LinkedHashMap();
              // ignore: close_sinks
              final TestSetExecuteBloc? executeBloc = BlocProvider.of<TestSetExecuteBloc>(context);
              if (executeBloc != null && executeBloc.existsActivePlan() == true) {
                Navigator.of(context).pushNamed("testSetExecute");
              } else {
                // ignore: close_sinks
                final bloc = BlocProvider.of<ExerciseNewBloc>(context);

                if (bloc.exerciseRepository.exerciseType!.unitQuantityUnit == null) {
                  args['exerciseRepository'] = bloc.exerciseRepository;
                  Navigator.of(context).pushNamed('evaluationPage', arguments: args);
                } else if (menuBloc.ability!.equalsTo(ExerciseAbility.oneRepMax)) {
                  args['exerciseRepository'] = bloc.exerciseRepository;
                  args['percent'] = 0.75;
                  args['readonly'] = false;
                  Navigator.of(context).pushNamed('exerciseControlPage', arguments: args);
                }
              }
            }
          },
          builder: (context, state) {
            final exerciseBloc = BlocProvider.of<ExerciseNewBloc>(context);
            return ModalProgressHUD(
              child: getExerciseSaveWidget(exerciseBloc, exerciseType, menuBloc),
              inAsyncCall: state is ExerciseNewLoading,
              opacity: 0.5,
              color: Colors.black54,
              progressIndicator: CircularProgressIndicator(),
            );
          },
        ));
  }

  Widget getExerciseSaveWidget(ExerciseNewBloc exerciseBloc, ExerciseType exerciseType, MenuBloc menuBloc) {
    if (exerciseBloc.exerciseRepository.exerciseType!.name == "BMR") {
      if (Cache().userLoggedIn == null) {
        exerciseBloc.add(ExerciseNewAddError(message: "Please log in"));
      } else {
        return BMR(exerciseBloc: exerciseBloc);
      }
    }
    if (exerciseBloc.exerciseRepository.exerciseType!.name == "BMI") {
      if (Cache().userLoggedIn == null) {
        exerciseBloc.add(ExerciseNewAddError(message: "Please log in"));
      } else {
        return BMI(exerciseBloc: exerciseBloc);
      }
    }
    if (exerciseBloc.exerciseRepository.exerciseType!.name == "Sizes") {
      if (Cache().userLoggedIn == null) {
        exerciseBloc.add(ExerciseNewAddError(message: "Please log in"));
      } else {
        return SizeWidget(exerciseBloc: exerciseBloc);
      }
    }

    return Scaffold(
      appBar: AppBarNav(depth: 1),
      body: Container(
          padding: EdgeInsets.only(top: 10, left: 20, right: 20),
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage('asset/image/WT_black_background.jpg'),
              fit: BoxFit.cover,
              alignment: Alignment.center,
            ),
          ),
          child: ExerciseSave(
            exerciseName: exerciseBloc.exerciseRepository.exerciseType!.nameTranslation,
            exerciseDescription: exerciseBloc.exerciseRepository.exerciseType!.descriptionTranslation,
            exerciseTask: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null
                ? t("Please take a relative bigger weight and repeat 12-20 times and do your best! MAXIMIZE it!")
                : t("Please repeat as much times as you can! MAXIMIZE it!"),
            unit: exerciseBloc.exerciseRepository.exerciseType!.unit,
            unitQuantityUnit: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit,
            hasUnitQuantity: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null,
            onQuantityChanged: (value) {
              exerciseBloc.add(ExerciseNewQuantityChange(quantity: value));
            },
            onUnitQuantityChanged: (value) => exerciseBloc.add(ExerciseNewQuantityUnitChange(quantity: value)),
            //onSubmit: () => confirmationDialog(exerciseBloc, menuBloc),
            exerciseTypeId: exerciseType.exerciseTypeId,
          )),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () => save(exerciseBloc, menuBloc),
        backgroundColor: Colors.orange[800],
        icon: Icon(
          CustomIcon.save,
          size: 20,
        ),
        label: Text(
          t("Save"),
          style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 12),
        ),
      ),
      bottomNavigationBar: BottomBarMultipleExercises(
        isSet: false,
        exerciseTypeId: exerciseType.exerciseTypeId,
      ),
    );
  }

  void save(ExerciseNewBloc bloc, MenuBloc menuBloc) {
    // ignore: close_sinks
    final TestSetExecuteBloc? executeBloc = BlocProvider.of<TestSetExecuteBloc>(context);

    final TutorialBloc tutorialBloc = BlocProvider.of<TutorialBloc>(context);
    if (tutorialBloc.isActive) {
      final String checkText = "Save";
      if (!tutorialBloc.checkAction(checkText)) {
        return;
      }
      if (Cache().userLoggedIn != null) {
        saveAll(bloc);
        return;
      } else {
        if (tutorialBloc.isActive) {
          tutorialBloc.step = 0;
          TutorialWidget().close();
        }
        Navigator.of(context).pushNamed("registration");
        return;
      }
    }

    if (executeBloc != null && executeBloc.existsActivePlan() == true) {
      confirmationOverride(bloc);
    } else {
      confirmationSave(bloc, menuBloc);
    }
  }

  void confirmationSave(ExerciseNewBloc bloc, MenuBloc menuBloc) {
    if (bloc.exerciseRepository.exercise!.quantity == null) {
      return;
    }

    String quantity = bloc.exerciseRepository.exercise!.quantity! % 1 == 0
        ? bloc.exerciseRepository.exercise!.quantity!.round().toString()
        : bloc.exerciseRepository.exercise!.quantity!.toString();

    String unitQuantity = "";
    if (bloc.exerciseRepository.exercise!.unitQuantity != null) {
      unitQuantity = bloc.exerciseRepository.exercise!.unitQuantity! % 1 == 0
          ? bloc.exerciseRepository.exercise!.unitQuantity!.round().toString()
          : bloc.exerciseRepository.exercise!.unitQuantity.toString();
    }

    // ignore: close_sinks
    final TestSetExecuteBloc executeBloc = BlocProvider.of<TestSetExecuteBloc>(context);

    final question = bloc.exerciseRepository.exercise!.quantity! == 12.0
        ? "Did you try the MAXIMUM what you can do? Are you sure we save the exercise with ONLY 12 repeats?"
        : "Do you save this exercise with these parameters?";

    showCupertinoDialog(
        useRootNavigator: true,
        context: context,
        builder: (_) => CupertinoAlertDialog(
              title: Text(t(question)),
              content: Column(children: [
                Divider(),
                Text(
                  t("Exercise") + ": " + bloc.exerciseRepository.exerciseType!.name,
                  style: (TextStyle(color: Colors.blue)),
                ),
                Text(
                  quantity + " " + t(bloc.exerciseRepository.exerciseType!.unit),
                  style: (TextStyle(color: Colors.deepOrange)),
                ),
                Text(
                  bloc.exerciseRepository.exerciseType!.unitQuantity == "1"
                      ? t("with") + " " + unitQuantity + " " + t(bloc.exerciseRepository.exerciseType!.unitQuantityUnit!)
                      : "",
                  style: (TextStyle(color: Colors.deepOrange)),
                ),
              ]),
              actions: [
                TextButton(
                  child: Text(t("No")),
                  onPressed: () => Navigator.pop(context),
                ),
                TextButton(
                  child: Text(t("Yes")),
                  onPressed: () {
                    if (Cache().userLoggedIn == null) {
                      Navigator.pop(context);
                      bloc.add(ExerciseNewAddError(message: "Please log in, because we can calculate the best suggestions for you"));
                    } else {
                      saveAll(bloc);
                      if (executeBloc.existsActivePlan() == true) {
                        executeBloc.add(TestSetExecuteExerciseFinished(
                            exerciseTypeId: bloc.exerciseRepository.exerciseType!.exerciseTypeId,
                            quantity: bloc.exerciseRepository.exercise!.quantity!,
                            unitQuantity: bloc.exerciseRepository.exercise!.unitQuantity!));
                      }
                      Navigator.pop(context);
                    }
                  },
                )
              ],
            ));
  }

  void saveAll(ExerciseNewBloc bloc) {
    bloc.exerciseRepository.setCustomer(Cache().userLoggedIn!);
    bloc.add(ExerciseNewSubmit());
  }

  void confirmationOverride(ExerciseNewBloc bloc) {
    // ignore: close_sinks
    final TestSetExecuteBloc executeBloc = BlocProvider.of<TestSetExecuteBloc>(context);
    showCupertinoDialog(
        useRootNavigator: true,
        context: context,
        builder: (_) => CupertinoAlertDialog(
              title: Text(t("You have an active Test Set!"), style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.red[800])),
              content: Column(children: [
                Divider(),
                Text(t("Do you want to override it?"), style: GoogleFonts.archivoBlack(fontSize: 16, color: Colors.blue[800])),
              ]),
              actions: [
                TextButton(
                  child: Text(t("No"), style: GoogleFonts.archivoBlack(fontSize: 16, color: Colors.blue[800])),
                  onPressed: () => Navigator.pop(context),
                ),
                TextButton(
                  child: Text(t("Yes"), style: GoogleFonts.archivoBlack(fontSize: 16, color: Colors.red[800])),
                  onPressed: () {
                    Navigator.pop(context);
                    executeBloc.add(TestSetExecuteDeleteAllActive());
                    saveAll(bloc);
                  },
                )
              ],
            ));
  }
}
