import 'dart:collection';
import 'dart:ui';

import 'package:aitrainer_app/bloc/body_type/bodytype_bloc.dart';
import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.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/dialog_html.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:aitrainer_app/library/liquid_progress_indicator/liquid_custom_progress_indicator.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:rainbow_color/rainbow_color.dart';

class CustomerBodyTypeAnimationPage extends StatefulWidget {
  @override
  _CustomerBodyTypeAnimationPageState createState() => _CustomerBodyTypeAnimationPageState();
}

class _CustomerBodyTypeAnimationPageState extends State<CustomerBodyTypeAnimationPage> with Trans {
  late bool fulldata;

  @override
  Widget build(BuildContext context) {
    CustomerRepository customerRepository;
    dynamic args = ModalRoute.of(context)!.settings.arguments;
    if (args is HashMap && args['personal_data'] != null) {
      fulldata = args['personal_data'];
      customerRepository = args['bloc'];
    } else {
      customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
    }

    setContext(context);
    return Scaffold(
      appBar: AppBarNav(depth: 0),
      body: Container(
          height: double.infinity,
          width: double.infinity,
          alignment: Alignment.center,
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage('asset/image/WT_plainblack_background.jpg'),
              fit: BoxFit.cover,
              alignment: Alignment.topCenter,
            ),
          ),
          child: BlocProvider(
              create: (context) => BodytypeBloc(repository: customerRepository),
              child: BlocConsumer<BodytypeBloc, BodytypeState>(listener: (context, state) {
                if (state is BodytypeError) {
                  ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(backgroundColor: Colors.orange, content: Text(state.error, style: TextStyle(color: Colors.white))));
                }
              }, builder: (context, state) {
                final bloc = BlocProvider.of<BodytypeBloc>(context);
                return ModalProgressHUD(
                  child: getBodyTypeAnimation(bloc),
                  inAsyncCall: state is BodytypeLoading,
                  opacity: 0.5,
                  color: Colors.black54,
                  progressIndicator: CircularProgressIndicator(),
                );
              }))),
    );
  }

  Widget getBodyTypeAnimation(BodytypeBloc bloc) {
    return Column(
      children: [
        Text(t("Body Type Analyser"),
            textAlign: TextAlign.center,
            style: GoogleFonts.archivoBlack(
              fontSize: 24,
              color: Colors.yellow[300],
              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,
                ),
              ],
            )),
        SizedBox(
          height: 30,
        ),
        _AnimatedLiquidCustomProgressIndicator(
          percentFrom: ((bloc.step - 1) / 22 * 100).toInt(),
          percentTo: (bloc.step / 22 * 100).toInt(),
        ),
        Divider(
          color: Colors.transparent,
        ),
        Text(t("How likely is it true about you?"),
            textAlign: TextAlign.center,
            style: GoogleFonts.archivoBlack(
              fontSize: 16,
              color: Colors.yellow[300],
              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,
                ),
              ],
            )),
        SizedBox(
          height: 30,
        ),
        Divider(
          color: Colors.white54,
        ),
        Question(
          bloc: bloc,
          text: bloc.getQuestion(),
        ),
        Divider(color: Colors.transparent),
        drawCircles(bloc),
        Divider(
          color: Colors.transparent,
        ),
        getLegend("Very unlikely", "Maybe", "Very likely"),
        Divider(color: Colors.transparent),
        InkWell(
            onTap: () => bloc.add(BodytypeBack()),
            child: Text(t("« Back"),
                textAlign: TextAlign.center,
                style: GoogleFonts.inter(
                  fontSize: 16,
                  color: Colors.blue[300],
                  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,
                    ),
                  ],
                ))),
        Divider(
          color: Colors.white54,
        ),
        SizedBox(
          height: 20,
        ),
        bloc.showResults()
            ? Text(t("Your Bodytype result"),
                textAlign: TextAlign.center,
                style: GoogleFonts.archivoBlack(
                  fontSize: 20,
                  color: Colors.yellow[300],
                  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,
                    ),
                  ],
                ))
            : Offstage(),
        SizedBox(
          height: 30,
        ),
        bloc.showResults() ? BodyTypeResult(bloc: bloc) : Offstage(),
        Divider(
          color: Colors.transparent,
        ),
        bloc.showResults()
            ? getLegend(PropertyEnum.Ectomorph.toStr(), PropertyEnum.Mesomorph.toStr(), PropertyEnum.Endomorph.toStr(), info: true)
            : Offstage(),
      ],
    );
  }

  Widget getLegend(String text1, String text2, String text3, {bool info = false}) {
    return Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
      Text(t(text1),
          textAlign: TextAlign.center,
          style: GoogleFonts.archivoBlack(
            fontSize: 14,
            color: Colors.green[300],
            shadows: <Shadow>[
              Shadow(
                offset: Offset(2.0, 2.0),
                blurRadius: 14.0,
                color: Colors.black54,
              ),
              Shadow(
                offset: Offset(-3.0, 3.0),
                blurRadius: 12.0,
                color: Colors.black54,
              ),
            ],
          )),
      info
          ? GestureDetector(
              onTap: () => showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return DialogHTML(
                      title: t(text1),
                      htmlData: t(text1 + "_desc"),
                    );
                  }),
              child: Icon(
                Icons.info_outline_rounded,
                color: Colors.yellow[100],
              ))
          : Offstage(),
      SizedBox(
        width: 5,
      ),
      Text(t(text2),
          textAlign: TextAlign.center,
          style: GoogleFonts.archivoBlack(
            fontSize: 14,
            color: Colors.green[300],
            shadows: <Shadow>[
              Shadow(
                offset: Offset(2.0, 2.0),
                blurRadius: 12.0,
                color: Colors.black54,
              ),
              Shadow(
                offset: Offset(-3.0, 3.0),
                blurRadius: 12.0,
                color: Colors.black54,
              ),
            ],
          )),
      info
          ? GestureDetector(
              onTap: () => showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return DialogHTML(
                      title: t(text2),
                      htmlData: t(text2 + "_desc"),
                    );
                  }),
              child: Icon(
                Icons.info_outline_rounded,
                color: Colors.yellow[100],
              ))
          : Offstage(),
      SizedBox(
        width: 5,
      ),
      Text(t(text3),
          textAlign: TextAlign.center,
          style: GoogleFonts.archivoBlack(
            fontSize: 14,
            color: Colors.green[300],
            shadows: <Shadow>[
              Shadow(
                offset: Offset(2.0, 2.0),
                blurRadius: 12.0,
                color: Colors.black54,
              ),
              Shadow(
                offset: Offset(-3.0, 3.0),
                blurRadius: 12.0,
                color: Colors.black54,
              ),
            ],
          )),
      info
          ? GestureDetector(
              onTap: () => showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return DialogHTML(
                      title: t(text3),
                      htmlData: t(text3 + "_desc"),
                    );
                  }),
              child: Icon(
                Icons.info_outline_rounded,
                color: Colors.yellow[100],
              ))
          : Offstage(),
    ]);
  }

  Widget drawCircles(BodytypeBloc bloc) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        CircleButton(value: 1, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 1))),
        CircleButton(value: 2, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 2))),
        CircleButton(value: 3, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 3))),
        CircleButton(value: 4, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 4))),
        CircleButton(value: 5, bloc: bloc, onTap: () => bloc.add(BodytypeClick(value: 5))),
      ],
    );
  }
}

class BodyTypeResult extends StatefulWidget {
  final BodytypeBloc bloc;
  const BodyTypeResult({required this.bloc});
  @override
  _BodyTypeResultState createState() => _BodyTypeResultState();
}

class _BodyTypeResultState extends State<BodyTypeResult> with TickerProviderStateMixin {
  late Animation<Color> colorAnim;
  late AnimationController colorController;

  @override
  void initState() {
    buildAnimation();
    super.initState();
  }

  void buildAnimation() {
    colorController = AnimationController(duration: Duration(seconds: 2), vsync: this);
    colorAnim = RainbowColorTween([
      Colors.green[800]!,
      Colors.green[700]!,
      Colors.green[600]!,
      Colors.green[500]!,
      Colors.green[400]!,
      Colors.green[300]!,
      Colors.green[200]!,
      Colors.green[100]!,
      Color(0xffb4f500),
    ]).animate(colorController)
      ..addListener(() {
        setState(() {});
      });
    colorController.forward();
  }

  @override
  void didUpdateWidget(BodyTypeResult oldWidget) {
    buildAnimation();

    super.didUpdateWidget(oldWidget);
  }

  @override
  void dispose() {
    colorController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        padding: EdgeInsets.only(left: 15, right: 15),
        width: MediaQuery.of(context).size.width - 20,
        height: 5,
        child: CustomPaint(
          painter: CurvePainter(value: widget.bloc.getBodyTypeValue(), color: colorAnim.value),
        ));
  }
}

class CurvePainter extends CustomPainter {
  final linePainter = Paint();
  final circlePainter = Paint();
  final Color color;
  final int value;

  CurvePainter({required this.value, required this.color});

  @override
  void paint(Canvas canvas, Size size) {
    var paint = linePainter;
    paint.color = Colors.green[800]!;
    paint.strokeWidth = 5;
    paint.style = PaintingStyle.fill;

    canvas.drawLine(
      Offset(0, size.height / 2),
      Offset(size.width, size.height / 2),
      paint,
    );

    paint.strokeWidth = 12;
    canvas.drawCircle(Offset(size.width / 2, size.height / 2), 6, paint);
    canvas.drawCircle(Offset(0, size.height / 2), 6, paint);
    canvas.drawCircle(Offset(size.width, size.height / 2), 6, paint);

    var paint2 = circlePainter;
    paint2.color = this.color; //Color(0xffb4f500);
    paint2.strokeWidth = 30;
    canvas.drawCircle(Offset(size.width * (value / 100), size.height / 2), 15, paint2);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

class Question extends StatefulWidget {
  final String text;
  final BodytypeBloc bloc;
  const Question({required this.text, required this.bloc});

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

class _QuestionState extends State<Question> with TickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    buildAnimation();
  }

  @override
  void didUpdateWidget(Question oldWidget) {
    if (oldWidget.text != widget.text) {
      buildAnimation();
    }
    super.didUpdateWidget(oldWidget);
  }

  void buildAnimation() {
    _controller = AnimationController(duration: const Duration(milliseconds: 2000), vsync: this);
    _animation = CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn);

    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        padding: EdgeInsets.only(left: 10, right: 10),
        child: FadeTransition(
            key: ValueKey(widget.text),
            opacity: _animation,
            child: Text(AppLocalizations.of(context)!.translate(widget.bloc.getQuestion()),
                textAlign: TextAlign.center,
                maxLines: 3,
                style: GoogleFonts.archivoBlack(
                  fontSize: 18,
                  color: Color(0xffb4f500),
                  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,
                    ),
                  ],
                ))));
  }
}

class CircleButton extends StatefulWidget {
  final GestureTapCallback onTap;
  final BodytypeBloc bloc;
  final int value;

  CircleButton({Key? key, required this.onTap, required this.bloc, required this.value}) : super(key: key);

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

class _CircleButtonState extends State<CircleButton> with TickerProviderStateMixin {
  late Animation<Color> colorAnim;
  late AnimationController colorController;

  @override
  void initState() {
    buildAnimation();
    super.initState();
  }

  @override
  void dispose() {
    colorController.dispose();
    super.dispose();
  }

  @override
  void didUpdateWidget(CircleButton oldWidget) {
    if (widget.bloc.getPrevValue() == widget.value) {
      buildAnimation();
    }
    super.didUpdateWidget(oldWidget);
  }

  void buildAnimation() {
    colorController = AnimationController(duration: Duration(seconds: 2), vsync: this);
    colorAnim = RainbowColorTween([
      Color(0xffb4f500),
      Color(0xffb4f500),
      Color(0xffb4f500),
      Color(0xffb4f500),
      Color(0xffb4f500),
      Color(0xffb4f500),
      Colors.green[100]!,
      Colors.green[200]!,
      Colors.green[300]!,
      Colors.green[400]!,
      Colors.green[500]!,
      Colors.green[600]!,
      Colors.green[700]!,
      Colors.green[800]!,
    ]).animate(colorController)
      ..addListener(() {
        setState(() {});
      });
    colorController.forward();
  }

  @override
  Widget build(BuildContext context) {
    final double size = 50.0;
    return InkResponse(
        onTap: () => {
              widget.bloc.add(BodytypeClick(value: widget.value)),
            },
        child: Container(
            key: UniqueKey(),
            width: size,
            height: size,
            decoration: BoxDecoration(
              color: widget.value == widget.bloc.getPrevValue() ? colorAnim.value : Colors.green[800],
              shape: BoxShape.circle,
            )));
  }
}

class _AnimatedLiquidCustomProgressIndicator extends StatefulWidget {
  final int percentTo;
  final int percentFrom;

  const _AnimatedLiquidCustomProgressIndicator({required this.percentTo, required this.percentFrom});

  @override
  State<StatefulWidget> createState() => _AnimatedLiquidCustomProgressIndicatorState();
}

class _AnimatedLiquidCustomProgressIndicatorState extends State<_AnimatedLiquidCustomProgressIndicator> with TickerProviderStateMixin {
  late AnimationController _animationController;
  bool switching = false;

  @override
  void didChangeDependencies() {
    buildAnimation();
    super.didChangeDependencies();
  }

  @override
  void didUpdateWidget(_AnimatedLiquidCustomProgressIndicator oldWidget) {
    if (oldWidget.percentFrom != widget.percentFrom) {
      buildAnimation();
    }
    super.didUpdateWidget(oldWidget);
  }

  void buildAnimation() {
    _animationController = AnimationController(
      lowerBound: (widget.percentFrom / 100).toDouble(),
      upperBound: (widget.percentTo / 100).toDouble(),
      vsync: this,
      duration: Duration(seconds: 3),
    )..addListener(() {
        /* setState(() {
          print("build animation state change");
        }); */
      });

    _animationController.forward();
  }

  @override
  void initState() {
    //buildAnimation();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final percentage = _animationController.value * 100;
    return Center(
      key: ValueKey(widget.percentFrom),
      child: LiquidCustomProgressIndicator(
        value: _animationController.value,
        direction: Axis.vertical,
        backgroundColor: Colors.white,
        valueColor: AlwaysStoppedAnimation(Colors.blue[200]!),
        shapePath: _buildHeartPath(),
        center: Text(
          "${percentage.toStringAsFixed(0)}%",
          style: TextStyle(
            color: Colors.blue[800],
            fontSize: 20.0,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
    );
  }

  Path _buildHeartPath() {
    return Path()
      ..moveTo(55, 15)
      ..cubicTo(55, 12, 50, 0, 30, 0)
      ..cubicTo(0, 0, 0, 37.5, 0, 37.5)
      ..cubicTo(0, 55, 20, 77, 55, 95)
      ..cubicTo(90, 77, 110, 55, 110, 37.5)
      ..cubicTo(110, 37.5, 110, 0, 80, 0)
      ..cubicTo(65, 0, 55, 12, 55, 15)
      ..close();
  }
}
