import 'dart:collection';

import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/customer_training_plan.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/library/tree_view.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/menu_image.dart';
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
import 'package:ezanimation/ezanimation.dart';
import 'package:flutter/cupertino.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 TrainingPlanCustomPage extends StatefulWidget {
  @override
  _ExercisePlanCustomPage createState() => _ExercisePlanCustomPage();
}

class _ExercisePlanCustomPage extends State<TrainingPlanCustomPage> with Trans {
  TrainingPlanBloc? bloc;
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    setContext(context);
    bloc = BlocProvider.of<TrainingPlanBloc>(context);
    bloc!.menuBloc.menuTreeRepository.sortByMuscleType();
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBarNav(depth: 1),
      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<TrainingPlanBloc, TrainingPlanState>(listener: (context, state) {
            if (state is TrainingPlanError) {
              ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                content: Text(
                  state.message,
                ),
                backgroundColor: Colors.orange,
              ));
            }
          }, builder: (context, state) {
            return ModalProgressHUD(
              child: exerciseWidget(bloc!),
              inAsyncCall: state is TrainingPlanLoading,
              opacity: 0.5,
              color: Colors.black54,
              progressIndicator: CircularProgressIndicator(),
            );
          })),
      bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () => Navigator.of(context).popAndPushNamed('myTrainingPlanExecute'),
        backgroundColor: Colors.orange[800],
        icon: Icon(CustomIcon.weight_hanging),
        label: Text(
          t("Start") + "!",
          style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
        ),
      ),
    );
  }

  Widget exerciseWidget(TrainingPlanBloc bloc) {
    return TreeView(
      startExpanded: false,
      children: _getTreeChildren(bloc),
    );
  }

  List<Widget> _getTreeChildren(TrainingPlanBloc bloc) {
    List<Widget> exerciseTypes = [];

    Card explanation = Card(
        color: Colors.white60,
        child: Container(
            padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                Row(
                  children: [
                    Icon(
                      Icons.info,
                      color: Colors.orangeAccent,
                    ),
                    Text("  "),
                    Text(
                      t("Custom Exercise Plan"),
                      style: GoogleFonts.archivoBlack(fontSize: 20),
                    ),
                  ],
                ),
                Divider(
                  color: Colors.transparent,
                ),
                Text(
                  t("Select manually the exercises what you would like to have in your plan. At the end don't forget to save."),
                  style: GoogleFonts.inter(fontSize: 12, fontWeight: FontWeight.normal),
                ),
              ],
            )));
    exerciseTypes.add(explanation);

    bloc.menuBloc.menuTreeRepository.sortedTree.forEach((name, list) {
      exerciseTypes.add(Container(
          margin: const EdgeInsets.only(left: 4.0),
          child: TreeViewChild(
            startExpanded: bloc.existsAddedExerciseTypeInTree(name),
            parent: TreeviewParentWidget(text: name),
            children: getTiles(list, bloc),
          )));
    });

    return exerciseTypes;
  }

  List<Widget> getTiles(List<WorkoutMenuTree> list, TrainingPlanBloc bloc) {
    List<Widget> tiles = [];
    tiles.addAll(getExerciseTiles(bloc, list));
    return tiles;
  }

  List<Widget> getExerciseTiles(TrainingPlanBloc bloc, List<WorkoutMenuTree> listWorkoutTree) {
    List<Widget> tiles = [];

    listWorkoutTree.forEach((element) {
      tiles.add(GestureDetector(
          onTap: () => {},
          child: ExerciseTile(
            bloc: bloc,
            exerciseType: element.exerciseType!,
          )));
    });

    return tiles;
  }
}

class ExerciseTile extends StatefulWidget {
  final TrainingPlanBloc bloc;
  final ExerciseType exerciseType;

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

  @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);
    Future.delayed(Duration(milliseconds: 400)).then((value) => animation.start());
    return true;
  }

  void activateCustomPlan() {
    widget.bloc.add(TrainingPlanCustomAddLoad(exerciseType: widget.exerciseType));
    Navigator.of(context).popAndPushNamed("myTrainingPlanCustomAdd");
  }

  Widget getIndicator() {
    if (widget.exerciseType.trainingPlanState.equalsTo(ExerciseTypeTrainingPlanState.none)) {
      return GestureDetector(
          onTap: () {
            if (widget.bloc.getMyPlan() != null && !widget.bloc.getMyPlan()!.type.equalsTo(CustomerTrainingPlanType.custom)) {
              showCupertinoDialog(
                  useRootNavigator: true,
                  context: context,
                  builder: (_) => CupertinoAlertDialog(
                        title: Text(t("You have an active Training Plan")),
                        content: Column(children: [
                          Divider(),
                          Text(
                            t("Do you want to override it?"),
                            style: (TextStyle(color: Colors.blue)),
                          ),
                        ]),
                        actions: [
                          TextButton(
                            child: Text(t("No")),
                            onPressed: () => Navigator.pop(context),
                          ),
                          TextButton(
                            child: Text(t("Yes")),
                            onPressed: () => activateCustomPlan(),
                          )
                        ],
                      ));
            } else {
              activateCustomPlan();
            }
          },
          child: ClipRRect(
              borderRadius: BorderRadius.circular(24.0),
              child: Container(
                  color: Colors.blue,
                  child: Icon(
                    CustomIcon.plus_1,
                    size: 28,
                    color: Colors.white,
                  ))));
    } else if (widget.exerciseType.trainingPlanState.equalsTo(ExerciseTypeTrainingPlanState.added)) {
      return GestureDetector(
          onTap: () => widget.bloc.add(TrainingPlanDeleteExerciseType(exerciseType: widget.exerciseType)),
          child: ClipRRect(
              borderRadius: BorderRadius.circular(24.0),
              child: Container(
                  padding: EdgeInsets.only(left: 8, bottom: 3),
                  color: Colors.red[400],
                  child: Text("X",
                      style: GoogleFonts.archivoBlack(
                        fontSize: 30,
                        color: Colors.white,
                      )))));
    } else {
      return ClipRRect(
          borderRadius: BorderRadius.circular(24.0),
          child: Container(
              color: Colors.blue,
              child: Icon(
                CustomIcon.down,
                size: 28,
                color: Colors.white,
              )));
    }
  }

  @override
  Widget build(BuildContext context) {
    bool added = widget.exerciseType.trainingPlanState.equalsTo(ExerciseTypeTrainingPlanState.added);
    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(),
        ),
        endChild: Container(
          padding: EdgeInsets.only(left: 10),
          child: Row(children: [
            Container(
              width: 120,
              height: 80,
              child: MenuImage(
                imageName: widget.bloc.getActualImageName(widget.exerciseType.exerciseTypeId),
                workoutTreeId: widget.bloc.getActualWorkoutTreeId(widget.exerciseType.exerciseTypeId)!,
              ),
            ),
            SizedBox(
              width: 10,
            ),
            Expanded(
                child: RichText(
              text: TextSpan(
                  style: GoogleFonts.inter(
                    fontSize: 14,
                    fontWeight: FontWeight.bold,
                    color: added ? Colors.white : Colors.grey,
                  ),
                  children: [
                    TextSpan(
                        text: widget.exerciseType.nameTranslation,
                        style: GoogleFonts.inter(
                          fontSize: 14,
                          fontWeight: FontWeight.bold,
                          color: added ? Colors.orange[500] : Colors.white,
                          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.exerciseType.unitQuantityUnit != null
                        ? TextSpan(
                            text: "\n",
                          )
                        : TextSpan(),
                    widget.exerciseType.unitQuantityUnit != null
                        ? TextSpan(
                            text: t(widget.exerciseType.unitQuantityUnit!) + ": ",
                            style: GoogleFonts.inter(
                                fontSize: 12, color: added ? Colors.yellow[400] : Colors.grey, fontWeight: FontWeight.bold))
                        : TextSpan(),
                    widget.exerciseType.unitQuantityUnit != null
                        ? TextSpan(
                            text: added ? widget.bloc.getWeightByExerciseType(widget.exerciseType) : "?",
                            style: GoogleFonts.inter(
                              fontSize: 12,
                            ))
                        : TextSpan(),
                    TextSpan(
                      text: "\n",
                    ),
                    TextSpan(
                        text: t(widget.exerciseType.unit) + ": ",
                        style:
                            GoogleFonts.inter(fontSize: 12, color: added ? Colors.yellow[400] : Colors.grey, fontWeight: FontWeight.bold)),
                    TextSpan(
                        text: added ? widget.bloc.getRepeatsByExerciseType(widget.exerciseType) : "?",
                        style: GoogleFonts.inter(
                          fontSize: 12,
                        )),
                    TextSpan(
                      text: "\n",
                    ),
                    TextSpan(
                        text: t("Set") + ": ",
                        style:
                            GoogleFonts.inter(fontSize: 12, color: added ? Colors.yellow[400] : Colors.grey, fontWeight: FontWeight.bold)),
                    TextSpan(
                        text: added ? widget.bloc.getSetByExerciseType(widget.exerciseType) : "?",
                        style: GoogleFonts.inter(
                          fontSize: 12,
                        )),
                  ]),
            )),
          ]),
        ),
      ),
    );
  }
}