import 'dart:collection';

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/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/dialog_common.dart';
import 'package:aitrainer_app/widgets/menu_image.dart';
import 'package:aitrainer_app/widgets/victory_widget.dart';
import 'package:ezanimation/ezanimation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:timeline_tile/timeline_tile.dart';

// ignore: must_be_immutable
class TestSetExecute extends StatelessWidget with Trans {
  @override
  Widget build(BuildContext context) {
    // ignore: close_sinks
    final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
    // ignore: close_sinks
    TestSetExecuteBloc executeBloc = BlocProvider.of<TestSetExecuteBloc>(context);
    executeBloc.menuBloc = menuBloc;

    executeBloc.add(TestSetExecuteLoad());
    setContext(context);
    return Scaffold(
      appBar: AppBarNav(depth: 0),
      body: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('asset/image/WT_black_background.jpg'),
            fit: BoxFit.cover,
            alignment: Alignment.center,
          ),
        ),
        child: BlocConsumer<TestSetExecuteBloc, TestSetExecuteState>(listener: (context, state) {
          if (state is TestSetExecuteError) {
            ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
          } else if (state is TestSetExecuteFinished) {
            showDialog(
                context: context,
                barrierDismissible: true,
                builder: (BuildContext context) {
                  return Victory(
                    victory: true,
                  );
                });
          }
        }, builder: (context, state) {
          executeBloc = BlocProvider.of<TestSetExecuteBloc>(context);
          return ModalProgressHUD(
            child: getExercises(executeBloc, context),
            inAsyncCall: state is TestSetExecuteLoading,
            opacity: 0.5,
            color: Colors.black54,
            progressIndicator: CircularProgressIndicator(),
          );
        }),
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () => executeBloc.getNext() != null
            ? executeExercise(executeBloc, executeBloc.getNext()!, context)
            : Navigator.of(context).pushNamed('home'),
        backgroundColor: Colors.orange[800],
        icon: Icon(CustomIcon.weight_hanging),
        label: Text(
          t("Next"),
          style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
        ),
      ),
    );
  }

  Widget getExercises(TestSetExecuteBloc bloc, BuildContext context) {
    return CustomScrollView(slivers: [
      SliverList(delegate: SliverChildListDelegate(getTiles(bloc, context))),
    ]);
  }

  List<Widget> getTiles(TestSetExecuteBloc bloc, BuildContext context) {
    List<Widget> tiles = [];
    tiles.add(getStartTile(bloc));
    tiles.addAll(getExerciseTiles(bloc, context));
    tiles.add(getEndTile());
    return tiles;
  }

  Widget getStartTile(TestSetExecuteBloc bloc) {
    return TimelineTile(
      alignment: TimelineAlign.manual,
      lineXY: 0.1,
      isFirst: true,
      afterLineStyle: const LineStyle(
        color: Colors.orange,
        thickness: 6,
      ),
      indicatorStyle: IndicatorStyle(
        width: 40,
        color: Colors.orange,
        padding: const EdgeInsets.all(8),
        iconStyle: IconStyle(
          color: Colors.white,
          iconData: Icons.insert_emoticon,
        ),
      ),
      endChild: Container(
        padding: EdgeInsets.only(top: 30),
        constraints: const BoxConstraints(
          minHeight: 120,
        ),
        color: Colors.transparent,
        child: RichText(
            text: TextSpan(
                style: GoogleFonts.inter(
                  fontSize: 14,
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
                children: [
              TextSpan(
                  text: bloc.isFirst() ? t("Start") : t("Continue"),
                  style: GoogleFonts.inter(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.yellow[400],
                    shadows: <Shadow>[
                      Shadow(
                        offset: Offset(5.0, 5.0),
                        blurRadius: 12.0,
                        color: Colors.black54,
                      ),
                      Shadow(
                        offset: Offset(-3.0, 3.0),
                        blurRadius: 12.0,
                        color: Colors.black54,
                      ),
                    ],
                  )),
              TextSpan(
                  text: t(" your ") + t(bloc.testType),
                  style: GoogleFonts.inter(
                    fontSize: 20,
                    fontWeight: FontWeight.bold,
                    color: Colors.yellow[400],
                    shadows: <Shadow>[
                      Shadow(
                        offset: Offset(5.0, 5.0),
                        blurRadius: 12.0,
                        color: Colors.black54,
                      ),
                      Shadow(
                        offset: Offset(-3.0, 3.0),
                        blurRadius: 12.0,
                        color: Colors.black54,
                      ),
                    ],
                  )),
              TextSpan(
                  text: "\n",
                  style: GoogleFonts.inter(
                    fontSize: 16,
                    color: Colors.white,
                  )),
              TextSpan(
                  text: bloc.testName == null ? "" : bloc.testName,
                  style: GoogleFonts.inter(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                  )),
              TextSpan(
                  text: t("\nyour plan is available for 24 hours"),
                  style: GoogleFonts.inter(
                    fontSize: 16,
                    color: Colors.white,
                  ))
            ])),
      ),
    );
  }

  Widget getEndTile() {
    return Container(
      color: Colors.transparent,
      child: TimelineTile(
        alignment: TimelineAlign.manual,
        lineXY: 0.1,
        isLast: true,
        beforeLineStyle: const LineStyle(
          color: Colors.orange,
          thickness: 6,
        ),
        indicatorStyle: IndicatorStyle(
          width: 40,
          color: Colors.orange,
          padding: const EdgeInsets.all(8),
          iconStyle: IconStyle(
            color: Colors.white,
            iconData: Icons.thumb_up,
          ),
        ),
        endChild: Container(
          padding: EdgeInsets.only(top: 50),
          constraints: const BoxConstraints(
            minHeight: 120,
          ),
          color: Colors.transparent,
          child: RichText(
              text: TextSpan(
                  style: GoogleFonts.inter(
                    fontSize: 14,
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                  ),
                  children: [
                TextSpan(
                    text: "Finish!",
                    style: GoogleFonts.inter(
                      fontSize: 20,
                      fontWeight: FontWeight.bold,
                      color: Colors.yellow[400],
                      shadows: <Shadow>[
                        Shadow(
                          offset: Offset(5.0, 5.0),
                          blurRadius: 12.0,
                          color: Colors.black54,
                        ),
                        Shadow(
                          offset: Offset(-3.0, 3.0),
                          blurRadius: 12.0,
                          color: Colors.black54,
                        ),
                      ],
                    )),
              ])),
        ),
      ),
    );
  }

  List<Widget> getExerciseTiles(TestSetExecuteBloc bloc, BuildContext context) {
    List<Widget> tiles = [];
    if (bloc.exercisePlanDetails != null) {
      bloc.exercisePlanDetails!.forEach((element) {
        //if (element != null && element.exerciseTypeId != null) {
        tiles.add(GestureDetector(
            onDoubleTap: () => print("Execute ${element.exerciseType!.nameTranslation}"),
            onTap: () => element.state.equalsTo(ExercisePlanDetailState.finished)
                ? evaluation(bloc, element)
                : executeExercise(bloc, element, context),
            child: ExerciseTile(
              bloc: bloc,
              exercisePlanDetail: element,
            )));
        //}
      });
    }

    return tiles;
  }

  void evaluation(TestSetExecuteBloc bloc, ExercisePlanDetail planDetail) {
    if (planDetail.exercises != null && planDetail.exercises!.isNotEmpty) {
      ExerciseRepository exerciseRepository = ExerciseRepository();
      exerciseRepository.start = planDetail.exercises![0].dateAdd;
      exerciseRepository.exerciseList = Cache().getExercises();
      exerciseRepository.actualExerciseList = planDetail.exercises!;
      print("actualEx ${exerciseRepository.actualExerciseList}");
      LinkedHashMap args = LinkedHashMap();
      args['exerciseRepository'] = exerciseRepository;
      args['exercise'] = planDetail.exercises![0];
      args['past'] = true;
      Navigator.of(context).pushNamed('evaluationPage', arguments: args);
    }
  }

  void executeExercise(TestSetExecuteBloc bloc, ExercisePlanDetail exercisePlanDetail, BuildContext context) {
    ExercisePlanDetail? next = bloc.getNext();

    if (next != null) {
      final HashMap args = HashMap();
      args['exerciseType'] = next.exerciseType;
      args['exercisePlanDetailId'] = exercisePlanDetail.exercisePlanDetailId;
      args['testSetExecuteBloc'] = bloc;
      String title = "";
      String description = "";
      String description2 = "";
      if (next.exerciseTypeId != exercisePlanDetail.exerciseTypeId) {
        title = t("Stop!");
        description = t("Please continue with the next exercise in the queue:") + next.exerciseType!.nameTranslation;
        description2 = t("Or, you can redifine this exercise queue in the Compact Test menu");
      } else {
        if (exercisePlanDetail.state.equalsTo(ExercisePlanDetailState.inProgress)) {
          final HashMap args = HashMap();
          args['exerciseType'] = exercisePlanDetail.exerciseType;
          args['exercisePlanDetail'] = exercisePlanDetail;
          args['testSetExecuteBloc'] = bloc;
          Navigator.of(context).pushNamed('testSetControl', arguments: args);
        } else {
          Navigator.of(context).pushNamed('testSetNew', arguments: args);
        }
        return;
      }

      showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) {
            return DialogCommon(
              title: title,
              descriptions: description,
              description2: description2,
              text: "OK",
              onTap: () => {Navigator.of(context).pop()},
              onCancel: () => {Navigator.of(context).pop()},
            );
          });
    } else {
      Navigator.of(context).pushNamed('home');
    }
  }
}

// ignore: must_be_immutable
class ExerciseTile extends StatefulWidget {
  final TestSetExecuteBloc bloc;
  final ExercisePlanDetail exercisePlanDetail;

  ExerciseTile({required this.bloc, required this.exercisePlanDetail});

  @override
  _ExerciseTileState createState() => _ExerciseTileState();
}

class _ExerciseTileState extends State<ExerciseTile> with Trans {
  final EzAnimation animation = EzAnimation(1.0, 30.0, Duration(seconds: 3), reverseCurve: Curves.easeIn);

  @override
  void initState() {
    animation.start();
    animation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {}
    });

    super.initState();
  }

  @override
  bool didUpdateWidget(ExerciseTile oldWidget) {
    super.didUpdateWidget(oldWidget);
    animation.start();
    return true;
  }

  Widget getIndicator(ExercisePlanDetailState state) {
    ExercisePlanDetail? next = widget.bloc.getNext();
    bool actual = false;
    if (next != null) {
      if (next.exerciseTypeId == widget.exercisePlanDetail.exerciseTypeId) {
        actual = true;
      }
    }
    if (state.equalsTo(ExercisePlanDetailState.inProgress)) {
      return ClipRRect(
          borderRadius: BorderRadius.circular(24.0),
          child: Container(
              color: actual ? Colors.green : Colors.orange,
              child: Icon(
                CustomIcon.calendar_2,
                size: 28,
                color: Colors.white,
              )));
    } else if (state.equalsTo(ExercisePlanDetailState.finished)) {
      return ClipRRect(
          borderRadius: BorderRadius.circular(24.0),
          child: Container(
              color: Colors.white,
              child: Icon(
                CustomIcon.ok_circled,
                size: 40,
                color: Colors.green,
              )));
    } else {
      return Image.asset(
        "asset/image/pict_reps_volumen_db.png",
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    final ExercisePlanDetailState state = widget.exercisePlanDetail.state;
    final bool done = state.equalsTo(ExercisePlanDetailState.finished);
    final String countSerie = widget.exercisePlanDetail.exercises == null ? "1" : (widget.exercisePlanDetail.exercises!.length).toString();
    final String serie = widget.exercisePlanDetail.exerciseType!.unitQuantityUnit == null ? "/1" : "/4";
    setContext(context);
    return Container(
      color: Colors.transparent,
      child: TimelineTile(
        alignment: TimelineAlign.manual,
        lineXY: 0.1,
        beforeLineStyle: const LineStyle(
          color: Color(0xffb4f500),
          thickness: 6,
        ),
        afterLineStyle: const LineStyle(
          color: Color(0xffb4f500),
          thickness: 6,
        ),
        indicatorStyle: IndicatorStyle(
          width: 40,
          height: 40,
          indicator: getIndicator(state),
        ),
        endChild: Container(
          padding: EdgeInsets.only(left: 10),
          child: Row(children: [
            Container(
                width: 120,
                height: 80,
                child: MenuImage(
                  imageName: widget.bloc.getActualImageName(widget.exercisePlanDetail.exerciseType!.exerciseTypeId),
                  workoutTreeId: widget.bloc.getActualWorkoutTreeId(widget.exercisePlanDetail.exerciseType!.exerciseTypeId)!,
                )),
            SizedBox(
              width: 10,
            ),
            Expanded(
                child: RichText(
              text: TextSpan(
                  style: GoogleFonts.inter(
                    fontSize: 14,
                    fontWeight: FontWeight.bold,
                    color: done ? Colors.grey[400] : Colors.white,
                  ),
                  children: [
                    TextSpan(
                        text: widget.exercisePlanDetail.exerciseType!.nameTranslation,
                        style: GoogleFonts.inter(
                          fontSize: 14,
                          fontWeight: FontWeight.bold,
                          color: done ? Colors.grey[400] : Colors.orange[500],
                          shadows: <Shadow>[
                            Shadow(
                              offset: Offset(5.0, 5.0),
                              blurRadius: 12.0,
                              color: Colors.black54,
                            ),
                            Shadow(
                              offset: Offset(-3.0, 3.0),
                              blurRadius: 12.0,
                              color: Colors.black54,
                            ),
                          ],
                        )),
                    widget.exercisePlanDetail.exerciseType!.unitQuantityUnit != null
                        ? TextSpan(
                            text: "\n",
                          )
                        : TextSpan(),
                    widget.exercisePlanDetail.exerciseType!.unitQuantityUnit != null
                        ? TextSpan(
                            text: t(widget.exercisePlanDetail.exerciseType!.unitQuantityUnit!) + ": ",
                            style: GoogleFonts.inter(
                                fontSize: 12, color: done ? Colors.grey[100] : Colors.yellow[400], fontWeight: FontWeight.bold))
                        : TextSpan(),
                    widget.exercisePlanDetail.exerciseType!.unitQuantityUnit != null
                        ? TextSpan(
                            text: t(widget.bloc.getExerciseWeight(widget.exercisePlanDetail)),
                            style: GoogleFonts.inter(
                              fontSize: 12,
                            ))
                        : TextSpan(),
                    TextSpan(
                      text: "\n",
                    ),
                    TextSpan(
                        text: t(widget.exercisePlanDetail.exerciseType!.unit) + ": ",
                        style: GoogleFonts.inter(
                            fontSize: 12, color: done ? Colors.grey[100] : Colors.yellow[400], fontWeight: FontWeight.bold)),
                    TextSpan(
                        text: widget.bloc.repeatTimesText(widget.exercisePlanDetail),
                        style: GoogleFonts.inter(
                          fontSize: 12,
                        )),
                    TextSpan(
                      text: "\n",
                    ),
                    TextSpan(
                        text: t("Set") + ": ",
                        style: GoogleFonts.inter(
                            fontSize: 12, color: done ? Colors.grey[100] : Colors.yellow[400], fontWeight: FontWeight.bold)),
                    TextSpan(
                        text: countSerie + serie,
                        style: GoogleFonts.inter(
                          fontSize: 12,
                        )),
                  ]),
            )),
            done
                ? AnimatedBuilder(
                    animation: animation,
                    builder: (context, snapshot) {
                      return Column(mainAxisAlignment: MainAxisAlignment.center, children: [
                        Image.asset(
                          "asset/image/kupa.png",
                          width: animation.value,
                        ),
                        Text("Result", style: GoogleFonts.inter(fontSize: 10, color: Colors.white)),
                      ]);
                    })
                : Offstage()
          ]),
        ),
      ),
    );
  }
}