import 'dart:math';
import 'dart:ui';
import 'dart:ui' as ui;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:sport/bean/sport_detail.dart';
import 'package:sport/bean/sport_index.dart';
import 'package:sport/services/api/inject_api.dart';
import 'package:sport/services/api/resp.dart';
import 'package:sport/widgets/appbar.dart';
import 'package:sport/widgets/decoration.dart';
import 'package:sport/widgets/misc.dart';
import 'package:sport/widgets/progress_bar.dart';
import 'package:sport/widgets/space.dart';

class StrengthPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _PageState();
}

class _PageState extends State<StrengthPage> with InjectApi {
  ValueNotifier<int> _valueNotifierIndex = ValueNotifier(26);
  SwiperController _swiperController;
  ScrollController _scrollController;

  @override
  void initState() {
    _swiperController = SwiperController();
    _scrollController = ScrollController();
    super.initState();
  }

  @override
  void dispose() {
    _swiperController?.dispose();
    _valueNotifierIndex?.dispose();
    _scrollController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          buildSliverAppBar(context, "运动强度", backgroundColor: Theme.of(context).scaffoldBackgroundColor),
          SliverToBoxAdapter(
            child: Container(
              margin: const EdgeInsets.symmetric(horizontal: 12.0),
              padding: const EdgeInsets.only(top:20.0,bottom: 10.0,left: 16.0,right: 16.0),
              decoration: circular(),
              child: FutureBuilder(
                future: createFutureType(0),
                builder: (BuildContext context, AsyncSnapshot<RespData<SportDetailSimple>> snapshot) => Column(
                  children: <Widget>[
                    Center(
                      child: CustomPaint(
                        painter: _Bg(),
                        child: Container(
                          width: 200,
                          height: 200,
                          child: Center(
                            child: CircularProgressBar(
                              percent: strengthToValue(snapshot?.data?.data?.sum?.consume ?? 0) / 12.0,
                              radius: 69.0,
                              center: Column(
                                children: <Widget>[
                                  SizedBox(
                                    height: 16.0,
                                  ),
                                  Text(
                                    "${strengthToValue(snapshot?.data?.data?.sum?.consume ?? 0).toStringAsFixed(1)}",
                                    style: Theme.of(context).textTheme.headline2.copyWith(fontSize: 40.0, fontFamily: "DIN"),
                                    strutStyle: fixedLine,
                                  ),SizedBox(
                                    height: 5.0,
                                  ),
                                  Text(
                                    "卡/分",
                                    style: Theme.of(context).textTheme.subtitle2,
                                    strutStyle: fixedLine,
                                  )
                                ],
                                mainAxisSize: MainAxisSize.min,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                    SizedBox(
                      width: 15.0,
                    ),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 6.0),
                      child: Row(
                        children: <Widget>[
                          Row(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: <Widget>[
                              Container(
                                width: 8,
                                height: 8,
                                decoration: BoxDecoration(shape: BoxShape.circle, color: const Color(0xffFFE600)),
                              ),
                              const SizedBox(
                                width: 5.0,
                              ),
                              Text(
                                "低强度",
                                style: Theme.of(context).textTheme.bodyText1,
                                strutStyle: fixedLine,
                              ),
                              const SizedBox(
                                width: 12.0,
                              ),
                              Container(
                                width: 8,
                                height: 8,
                                decoration: BoxDecoration(shape: BoxShape.circle, color: const Color(0xffFFAA00)),
                              ),
                              const SizedBox(
                                width: 5.0,
                              ),
                              Text(
                                "强度适中",
                                style: Theme.of(context).textTheme.bodyText1,
                                strutStyle: fixedLine,
                              ),
                              const SizedBox(
                                width: 12.0,
                              ),
                              Container(
                                width: 8,
                                height: 8,
                                decoration: BoxDecoration(shape: BoxShape.circle, color: const Color(0xffFF7323)),
                              ),
                              const SizedBox(
                                width: 5.0,
                              ),
                              Text(
                                "高强度",
                                style: Theme.of(context).textTheme.bodyText1,
                                strutStyle: fixedLine,
                              )
                            ],
                          ),
                          Text(
                            "单位：卡/分钟",
                            style: Theme.of(context).textTheme.bodyText1,
                            strutStyle: fixedLine,
                          )
                        ],
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      ),
                    ),
                    Divider(),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 16.0),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: <Widget>[
                          Column(
                            children: <Widget>[
                              Text(
                                "${snapshot?.data?.data?.sum?.consume ?? 0}",
                                style: Theme.of(context).textTheme.headline2.copyWith(fontSize: 26.0, fontFamily: "DIN"),
                              ),
                              Space(height: 4.0,),
                              Text(
                                "运动消耗 (卡)",
                                style: Theme.of(context).textTheme.bodyText1,
                              ),
                            ],
                            mainAxisSize: MainAxisSize.min,
                            crossAxisAlignment: CrossAxisAlignment.center,
                          ),
                          Column(
                            children: <Widget>[
                              Text(
                                "${snapshot?.data?.data?.sum?.durationMinute ?? 0}",
                                style: Theme.of(context).textTheme.headline2.copyWith(fontSize: 26.0, fontFamily: "DIN"),
                              ),
                              Space(height: 4.0,),
                              Text(
                                "运动时长 (分钟)",
                                style: Theme.of(context).textTheme.bodyText1,
                              ),
                            ],
                            mainAxisSize: MainAxisSize.min,
                            crossAxisAlignment: CrossAxisAlignment.center,
                          )
                        ],
                      ),
                    )
                  ],
                ),
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Container(
                height: 140.0,
                margin: const EdgeInsets.only(top: 12.0),
                child: CustomPaint(
                  painter: _ListBg(),
                  child: FutureBuilder(
                    future: createFutureType(1).asStream().map((event) => convert(event)).last,
                    builder: (BuildContext context, AsyncSnapshot<List<_DataItem>> snapshot) {
                      var list = snapshot?.data;
                      if (list == null || list?.isEmpty == true) return Container();
                      return ValueListenableBuilder(
                        valueListenable: _valueNotifierIndex,
                        builder: (BuildContext context, int value, Widget child) {
                          return SingleChildScrollView(
                            reverse: true,
                            child: Padding(
                                padding: EdgeInsets.only(top: 10.0),
                                child: Row(
                                  children: list?.map((e) {
                                    var index = list.indexOf(e);
                                    return GestureDetector(
                                        behavior: HitTestBehavior.opaque,
                                        onTap: () {
                                          // _valueNotifierIndex.value = index;
                                          // var page = max(0, strengthArr.indexOf(strengthToLabel(list[index].data)));
                                          // _swiperController?.move(page);
                                        },
                                        child: Column(
                                          mainAxisAlignment: MainAxisAlignment.end,
                                          children: <Widget>[
                                            CustomPaint(
                                              child: SizedBox(
                                                width: MediaQuery.of(context).size.width / 7.0,
                                                height: 100.0,
                                              ),
                                              painter: _Dot(list, index),
                                            ),
                                            Container(
                                                height: 30.0,
                                                decoration: index == value
                                                    ? BoxDecoration(
                                                        border: Border(bottom: BorderSide(color: Theme.of(context).accentColor, width: 3.0)),
                                                      )
                                                    : null,
                                                child: Center(
                                                    child: Text(
                                                  "${e.date}",
                                                  style: e.date == "今日"
                                                      ? Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor)
                                                      : Theme.of(context).textTheme.subtitle1,
                                                ))),
                                          ],
                                        ));
                                  })?.toList(),
                                )),
                            scrollDirection: Axis.horizontal,
                          );
                        },
                      );
                    },
                  ),
                )),
          ),
          SliverToBoxAdapter(
            child: Padding(
              padding: const EdgeInsets.only(top: 12.0),
              child: Container(
                width: double.infinity,
                height: 145.0,
                child: Swiper(
                    controller: _swiperController,
                    loop: false,
                    itemBuilder: (BuildContext context, int index) {
                      return Container(
                        margin: const EdgeInsets.only(left:12.0,right: 12.0),
                        // decoration: circular(),
                        // padding: const EdgeInsets.all(12.0),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Text(
                              index == 0 ? "低强度" : index == 1 ? "强度适中" : "高强度",
                              style: Theme.of(context).textTheme.headline1,
                            ),
                            SizedBox(
                              height: 5.0,
                            ),
                            Text(
                              index == 0
                                  ? "感觉舒适，呼吸有节奏，能自由进行交谈。该级别适用于恢复和基础心血功能训练，可以提高心脏的泵血能力和肌肉使用氧气的能力"
                                  : index == 1 ? "该级别训练强度适中，较难以进行交谈，呼吸加重。可以适当增强心肺功能，获得更强耐力" : "感觉难受，且呼吸急促，难以长时间维持该强度训练。可以增强力量和肌肉耐力，提高厌氧能力和乳酸阈值",
                              style: Theme.of(context).textTheme.bodyText2,
                              strutStyle: StrutStyle(height: 1.5,forceStrutHeight: true),
                            ),
                          ],
                        ),
                      );
                    },
                    itemCount: 3),
              ),
            ),
          )
        ],
      ),
    );
  }

  Future<RespData<SportDetailSimple>> createFutureType(int type) async {
    Future<RespData<SportDetailSimple>> data;
    var time = DateTime.now();
    switch (type) {
      case 0:
        data = api.getSportRecordListOneDay('${time.year}-${'${time.month}'.padLeft(2, '0')}-${'${time.day}'.padLeft(2, '0')}');
        break;
      case 1:
        DateTime end = DateTime(time.year, time.month, time.day + 3);
        DateTime start = DateTime(time.year, time.month, end.day - 30);
        data = api.getSportRecordListByDay('${start.year}-${'${start.month}'.padLeft(2, '0')}-${'${start.day}'.padLeft(2, '0')}',
            '${end.year}-${'${end.month}'.padLeft(2, '0')}-${'${end.day}'.padLeft(2, '0')}');
        break;
    }
    return data;
  }

  List<_DataItem> convert(RespData<SportDetailSimple> data) {
    List<_DataItem> items = [];
    List<RecordsToday> records = data?.data?.records ?? [];
    var time = DateTime.now();
    DateTime end = DateTime(time.year, time.month, time.day + 3);
    for (var i = 0; i < 30; i++) {
      var day = DateTime(end.year, end.month, end.day - i);
      String tag = '${day.year}-${'${day.month}'.padLeft(2, '0')}-${'${day.day}'.padLeft(2, '0')}';
      String date = (time.month == day.month && time.day == day.day) ? '今日' : (day.day == 1) ? '${day.month}.${day.day}' : '${day.day}';
      int total = 0;
      for (var record in records) {
        if (tag == record.createdAt.split(" ")[0]) {
          total += record.consume;
        }
      }
      items.add(_DataItem(tag, date, total));
      if (i == 3) {
        _swiperController?.move(max(0, strengthArr.indexOf(strengthToLabel(total))));
      }
    }
    return items.reversed.toList();
  }
}

class _DataItem {
  final String tag;
  final String date;
  final int data;

  _DataItem(this.tag, this.date, this.data);
}

class _Bg extends CustomPainter {
  final Paint _paint = Paint()
    ..color = const Color(0xffDCDCDC)
    ..strokeWidth = 0.5
    ..style = PaintingStyle.stroke
    ..isAntiAlias = true;
  final ParagraphStyle _valueStyle = ParagraphStyle(
    textAlign: TextAlign.center,
    fontSize: 12,
  );

  @override
  void paint(Canvas canvas, Size size) {
    final double cx = size.width / 2;
    final double cy = size.height / 2;
    final double radius = (size.width - 40) / 2;
    canvas.drawCircle(Offset(cx, cy), radius, _paint);

    canvas.save();
    for (int i = 0; i < 4; i++) {
      canvas.translate(cx, cy);
      canvas.rotate(pi * 2 / 3);
      canvas.translate(-cx, -cy);
      canvas.drawLine(Offset(cx, cy - radius), Offset(cx, cy - radius + 4), _paint);
    }
    canvas.restore();

    ParagraphBuilder pb = ParagraphBuilder(_valueStyle)
      ..pushStyle(ui.TextStyle(color: Color(0xff999999)))
      ..addText("0");
    ParagraphConstraints constraints = ParagraphConstraints(width: 20.0);
    Paragraph paragraph = pb.build()..layout(constraints);
    paragraph.computeLineMetrics().forEach((element) {
      canvas.drawParagraph(paragraph, Offset(cx - element.width - 4, 2));
    });

    pb = ParagraphBuilder(_valueStyle)
      ..pushStyle(ui.TextStyle(color: Color(0xff999999)))
      ..addText("4.0");
    constraints = ParagraphConstraints(width: 20.0);
    paragraph = pb.build()..layout(constraints);
    paragraph.computeLineMetrics().forEach((element) {
      canvas.drawParagraph(paragraph, Offset(size.width - 25, 140));
    });

    pb = ParagraphBuilder(_valueStyle)
      ..pushStyle(ui.TextStyle(color: Color(0xff999999)))
      ..addText("8.0");
    constraints = ParagraphConstraints(width: 20.0);
    paragraph = pb.build()..layout(constraints);
    paragraph.computeLineMetrics().forEach((element) {
      canvas.drawParagraph(paragraph, Offset(6, 140.0));
    });
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

class _ListBg extends CustomPainter {
  final Paint _paint = Paint()
    ..color = const Color(0xffDCDCDC)
    ..strokeWidth = 0.5
    ..isAntiAlias = true;
  final ParagraphStyle _valueStyle = ParagraphStyle(
    textAlign: TextAlign.right,
    fontSize: 12,
  );

  @override
  void paint(Canvas canvas, Size size) {
    final double height = size.height - 40;
    final int split = 3;
    final double splitHeight = height / split;
    double _startY = 10;
    for (var i = 0; i < split; i++) {
      canvas.drawLine(Offset(0, _startY), Offset(size.width, _startY), _paint);
      _startY += splitHeight;
      ParagraphBuilder pb = ParagraphBuilder(_valueStyle)
        ..pushStyle(ui.TextStyle(color: Color(0xff999999)))
        ..addText("${(8.0 - (4.0 * i)).toStringAsFixed(1)}");
      ParagraphConstraints constraints = ParagraphConstraints(width: size.width - 10);
      Paragraph paragraph = pb.build()..layout(constraints);
      paragraph.computeLineMetrics().forEach((element) {
        canvas.drawParagraph(paragraph, Offset(0, splitHeight * i + element.baseline / 2 + 14));
      });
    }
    canvas.drawLine(Offset(0, size.height - 30), Offset(size.width, size.height - 30), _paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

class _Dot extends CustomPainter {
  final List<_DataItem> items;
  final int index;

  static const Color _color = const Color(0xffFFC400);
  final Paint _paint = Paint()
    ..maskFilter = MaskFilter.blur(BlurStyle.solid, 3)
    ..isAntiAlias = true;
  final Paint _line = Paint()
    ..color = _color
    ..strokeWidth = 0.5
    ..isAntiAlias = true;
  final Paint _polygonal = Paint()
    ..color = _color
    ..strokeWidth = 1
    ..isAntiAlias = true;

  _Dot(this.items, this.index);

  @override
  void paint(Canvas canvas, Size size) {
    if (index > items.length - 4) return;

    double _height = size.height;

    final double cx = size.width / 2;
    final double progress = min(1.0, items[index].data / 60.0 / 12.0);
    final double cy = _height * (1.0 - progress);
    // print("$progress $cy ${items[index].data}");
    final double radius = size.width * 0.15 / 2;
    _paint.color = _color;
    canvas.drawCircle(Offset(cx, cy), radius, _paint);

    if (index == items.length - 4) {
      double _h = cy;
      while (_h < _height) {
        canvas.drawLine(Offset(cx, _h), Offset(cx, min(_height, _h + 3)), _line);
        _h += 5;
      }
    }

    for (var i = index - 1; i < index + 1; i += 2) {
      if (i < 0) continue;
      if (i >= items.length) continue;
      double _cx = (cx - size.width) * (index - i);
      double _cy = size.height * (1.0 - min(1.0, items[i].data / 60.0 / 12.0));
      canvas.drawLine(Offset(_cx, _cy), Offset(cx, cy), _polygonal);
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}
