import 'dart:math';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sport/bean/game.dart' as game;
import 'package:sport/bean/sport_index.dart';
import 'package:sport/bean/user.dart';
import 'package:sport/constant/ui.dart' show ui_padding, ui_margin_list;
import 'package:sport/pages/game/game_info.dart';
import 'package:sport/pages/home/guide_page.dart';
import 'package:sport/provider/bluetooth.dart';
import 'package:sport/provider/lib/provider_widget.dart';
import 'package:sport/provider/lib/view_state_lifecycle.dart';
import 'package:sport/provider/sport_index_model.dart';
import 'package:sport/provider/user_model.dart';
import 'package:sport/router/navigator_util.dart';
import 'package:sport/router/routes.dart';
import 'package:sport/widgets/area.dart';
import 'package:sport/widgets/button_primary.dart';
import 'package:sport/widgets/decoration.dart';
import 'package:sport/widgets/dialog/request_dialog.dart';
import 'package:sport/widgets/dialog/search_device.dart';
import 'package:sport/widgets/image.dart';
import 'package:sport/widgets/loading.dart';
import 'package:sport/widgets/misc.dart';
import 'package:sport/widgets/space.dart';
import 'package:sport/widgets/wave_painter.dart';

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

class _PageState extends ViewStateLifecycle<HomeInfoPage, SportIndexModel> with AutomaticKeepAliveClientMixin {
  String _rank;
  ValueNotifier<bool> _valueNotifierGuide = ValueNotifier(false);
  static const String GUIDE = "guide";

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

  void loadSetting() async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    _valueNotifierGuide.value = preferences.getBool(GUIDE) ?? true;
  }

  @override
  SportIndexModel createModel() => SportIndexModel(context);

  refresh() {
    _rank = null;

    model.refresh();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: PreferredSize(
        preferredSize: Size.fromHeight(40.0),
        child: AppBar(
          titleSpacing: ui_padding,
          brightness: Brightness.dark,
          backgroundColor: Color(0xff241D19),
          title: _buildDeviceInfoWidget(),
        ),
      ),
      body: ProviderWidget<SportIndexModel>(
        model: this.model,
        onModelReady: (v) => v.initData(),
        builder: (BuildContext context, SportIndexModel value, Widget child) => EasyRefresh.custom(
          enableControlFinishRefresh: true,
          onRefresh: () => refresh(),
          header: buildClassicalHeader(bgColor: Color(0xff241D19)),
          slivers: <Widget>[
//            // 暂时测试
//            if (model.isIdle && value.data != null)
//              SliverToBoxAdapter(
//                child: Stack(
//                  fit: StackFit.passthrough,
//                  children: <Widget>[
//                    CustomPaint(
//                      painter: _HeaderBackground(),
//                      child: Container(
//                        height: 116,
//                      ),
//                    ),
//                    Container(
//                      margin: EdgeInsets.fromLTRB(ui_padding, 4.0, ui_padding, 10.0),
//                      decoration: card(),
//                      height: 156,
//                      child: _buildSportWidget(value.data),
//                    )
//                  ],
//                ),
//              ),
            if (model.isIdle && value.data != null)
              SliverToBoxAdapter(
                child: _buildTopWidget(value.data),
              ),
            if (model.isBusy)
              SliverToBoxAdapter(
                child: RequestLoadingWidget(),
              ),
            if (value.data?.lastGame != null)
              SliverToBoxAdapter(
                child: _buildSportHistoryWidget(value.data.lastGame),
              ),
            SliverToBoxAdapter(
              child: ValueListenableBuilder<bool>(
                  builder: (BuildContext context, value, Widget child) => value ? _buildGuideWidget() : Container(), valueListenable: _valueNotifierGuide),
            ),
            if (value.data?.games != null)
              SliverToBoxAdapter(
                child: _buildLabelWidget("SPORTS"),
              ),
            if (value.data?.games != null)
              SliverPadding(
                padding: const EdgeInsets.symmetric(horizontal: ui_padding),
                sliver: SliverGrid(
                  gridDelegate:
                      SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, crossAxisSpacing: 10, mainAxisSpacing: 10, childAspectRatio: 170.0 / 226),
                  delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
                    return InkWell(
                        onTap: () => NavigatorUtil.goGameDetails(context, details: value.data.games[index]),
                        child: _buildSportItemWidget(value.data.games[index]));
                  }, childCount: value.data.games.length),
                ),
              ),
            if (value.data?.rank != null)
              SliverToBoxAdapter(
                child: Padding(
                  padding: const EdgeInsets.only(top: 12.0),
                  child: Row(
                    children: <Widget>[
                      Expanded(child: _buildLabelWidget("CHARTS")),
                      PopupMenuButton(
                        onSelected: (v) {
                          value.game(v);
                        },
                        itemBuilder: (BuildContext context) {
                          return divideMenus(value.data.games
                              .map((e) => menuItemSelected(e.id, e.name, e.id ==  value.gameId))
                              .toList());
                        },
                        child: Row(
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget>[
                            Text(value.data.games.where((element) => element.id == value.gameId).map((e) => e.name).first, style: Theme.of(context).textTheme.bodyText1,),
                            Padding(
                              padding: const EdgeInsets.all(6.0),
                              child: arrowBottom(),
                            )
                          ],
                        ),
                      ),
                      SizedBox(
                        width: 12,
                      ),
                      NotificationListener<AreaNotification>(
                        onNotification: (n) {
                          _rank = n.rank;
                          request(context, () async {
                            await value.area(
                                n.all ? null : n.provinceId, n.all ? null : n.province ? null : n.cityId, n.all ? null : n.province ? null : n.districtId);
                          });
                          return true;
                        },
                        child: AreaPage(
                          area: _rank,
                        ),
                      )
                    ],
                  ),
                ),
              ),
            if (value.data?.rank != null)
              SliverToBoxAdapter(
                child: _buildRankWidget(value.data.rank),
              ),
            if (value.data?.rank != null)
              SliverPadding(
                  padding: const EdgeInsets.symmetric(horizontal: ui_padding),
                  sliver: SliverList(
                    delegate: SliverChildBuilderDelegate((content, index) {
                      return (value.data.rank.records.length - 3) > index
                          ? _buildRankItemWidget(value.data.rank.records[index + 3], index)
                          : _buildRankItemWidget(null, index);
                    }, childCount: 7),
                  )),
            if (value.data?.rank != null)
              SliverToBoxAdapter(
                child: Center(
                    child: InkWell(
                  onTap: () {
                    NavigatorUtil.goRankDetails(context, value.data.rank.rank.gameId, 1);
                  },
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Text(
                      "查看完整榜单",
                      style: Theme.of(context).textTheme.bodyText1.copyWith(color: Color(0xffcecece)),
                    ),
                  ),
                )),
              ),
            SliverToBoxAdapter(
              child: SizedBox(
                height: 50,
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  bool get wantKeepAlive => true;

  Widget _buildDeviceInfoWidget() {
    return Selector<Bluetooth, BluetoothDevice>(
        selector: (_, bluetooth) => bluetooth.device,
        builder: (_, device, ___) {
          return device == null ? _buildDeviceInfoConnectFailWidget() : _buildDeviceInfoStateWidget(device);
        });
  }

  Widget _buildDeviceInfoStateWidget(BluetoothDevice device) {
    return StreamBuilder<BluetoothDeviceState>(
        stream: device.state,
        initialData: BluetoothDeviceState.connecting,
        builder: (c, snapshot) => _buildDeviceInfoConnectedWidget(snapshot.data == BluetoothDeviceState.connected));
  }

  Widget _buildDeviceInfoConnectedWidget(bool connect) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
        Row(
          children: <Widget>[
            Container(
              width: 10,
              height: 10,
              decoration: BoxDecoration(shape: BoxShape.circle, color: connect ? Color(0xff00DC42) : Colors.red),
            ),
            SizedBox(
              width: 6.0,
            ),
            Text(connect ? "设备已连接" : "未连接设备",
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 14,
                ),
                strutStyle: StrutStyle(forceStrutHeight: true)),
            SizedBox(
              width: 4.0,
            ),
            if (connect)
              Stack(
                alignment: Alignment.bottomCenter,
                children: <Widget>[
                  Image.asset("lib/assets/img/battery.png"),
                  ValueListenableBuilder(
                      valueListenable: Provider.of<Bluetooth>(context, listen: false).electricityNotifier,
                      builder: (_, data, ___) => Container(
                            width: 5.5,
                            height: 8 * (data / 100),
                            margin: EdgeInsets.only(bottom: 2, right: 0.5),
                            decoration: BoxDecoration(color: Color(0xff00DC42)),
                          )),
                ],
              )
          ],
        ),
        GestureDetector(
          onTap: () => NavigatorUtil.go(context, Routes.deviceInfo),
          child: Row(
            children: <Widget>[
              Text(
                "查看设备详情",
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 14,
                ),
                strutStyle:  StrutStyle(forceStrutHeight: true),
              ),
              SizedBox(
                width: 6,
              ),
              arrowRight1()
            ],
          ),
        ),
      ],
    );
  }

  Widget _buildDeviceInfoConnectFailWidget() {
    return Row(
      children: <Widget>[
        Container(
          width: 10,
          height: 10,
          decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.red),
        ),
        SizedBox(
          width: 6.0,
        ),
        Text("未连接设备",
            style: TextStyle(
              color: Colors.white,
              fontSize: 14,
            ),
            strutStyle:  StrutStyle(forceStrutHeight: true)),
      ],
    );
  }

  Widget _buildDeviceWidget() {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        Image.asset("lib/assets/img/home_image_connect.png"),
        Space(
          height: 8,
        ),
        Text(
          "请先连接设备鞋子",
          style: Theme.of(context).textTheme.bodyText1,
        ),
        Space(
          height: 12,
        ),
        PrimaryButton(
          content: "搜索设备",
          width: 132,
          height: 35,
          callback: () {
            showDialog(context: context, child: SearchDeviceDialog());
          },
        )
      ],
    );
  }

  Widget _buildTopWidget(SportIndex item) {
    return Stack(
      fit: StackFit.passthrough,
      children: <Widget>[
        CustomPaint(
          painter: _HeaderBackground(),
          child: Container(
            height: 116,
          ),
        ),
        Container(
          margin: EdgeInsets.fromLTRB(ui_padding, 4.0, ui_padding, 10.0),
          decoration: card(),
          height: 156,
          child: Selector<Bluetooth, BluetoothDevice>(
              selector: (_, bluetooth) => bluetooth.device,
              builder: (_, device, ___) {
                return device != null ? _buildSportWidget(item) : _buildDeviceWidget();
              }),
        )
      ],
    );
  }

  Widget _buildSportWidget(SportIndex item) {
    return InkWell(
      onTap: () => NavigatorUtil.go(context, Routes.sportDetail),
      child: Stack(
        alignment: Alignment.center,
        children: <Widget>[
          Row(
            children: <Widget>[
              Expanded(
                  flex: 5,
                  child: Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: ValueListenableBuilder(
                        valueListenable: Provider.of<UserModel>(context, listen: false).durationTarget,
                        builder: (_, v, __) => ProgressManager(min(.9,  v <= 0 ? 0 : item.duration / v))),
                  )),
              Expanded(
                flex: 6,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Text(
                      "今日已运动",
                      style: Theme.of(context).textTheme.subtitle1,
                    ),
                    SizedBox(
                      height: 5,
                    ),
                    RichText(
                      text: TextSpan(style: Theme.of(context).textTheme.subtitle2, children: <InlineSpan>[
                        TextSpan(text: '${item.duration}', style: Theme.of(context).textTheme.subtitle2.copyWith(fontWeight: FontWeight.bold, fontSize: 40)),
                        TextSpan(text: '分钟'),
                      ]),
                    ),
                    SizedBox(
                      height: 5,
                    ),
                    Text("共消耗 ${item.consume} kal", style: Theme.of(context).textTheme.bodyText1),
                    SizedBox(
                      height: 5,
                    ),
                    Text(item.beyond > 0 ? "已超越了${item.beyond}人，请再接再厉" : "${item.inspire}", style: Theme.of(context).textTheme.bodyText1),
                  ],
                ),
              )
            ],
          ),
          Positioned(
            right: 0,
            child: Image.asset("lib/assets/img/home_icon_details.png"),
          )
        ],
      ),
    );
  }

  Widget _buildRankWidget(RankInfo rankInfo) {
    return Column(
      children: <Widget>[
        if (rankInfo?.user != null)
          GestureDetector(
            onTap: () => NavigatorUtil.goRankPeopleDetails(context, details: rankInfo.user),
            child: Container(
              margin: EdgeInsets.all(ui_padding),
              padding: EdgeInsets.all(ui_padding),
              decoration: card(),
              child: Row(
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.only(right: 8),
                    child: Text(
                      "${rankInfo.user.position}",
                    ),
                  ),
                  if (rankInfo.user.up != 0 && rankInfo.user.upNew != 0)
                    Padding(
                      padding: const EdgeInsets.only(right: 8),
                      child: Image.asset("lib/assets/img/rand_icon_${rankInfo.user.up >= 0 ? 'top' : 'down'}.png"),
                    ),
                  Padding(
                    padding: const EdgeInsets.only(right: 10.0),
                    child: CircleAvatar(backgroundImage: userAvatarProvider(rankInfo?.user?.userAvatar), radius: 22),
                  ),
                  Expanded(
                    child: Text(
                      rankInfo.user.userName,
                      style: Theme.of(context).textTheme.subtitle1,
                    ),
                  ),
                  Text(
                    "${rankInfo.user.score.toStringAsFixed(1)}分",
                    style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor),
                  ),
                ],
              ),
            ),
          ),
        Center(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            crossAxisAlignment: CrossAxisAlignment.end,
            children: <Widget>[
              Container(width: 94, child: rankInfo.records.length >= 2 ? _buildRankHeaderWidget(rankInfo.records[1], 2) : _buildRankHeaderWidget(null, 2)),
              Container(width: 120, child: rankInfo.records.length >= 1 ? _buildRankHeaderWidget(rankInfo.records[0], 1) : _buildRankHeaderWidget(null, 1)),
              Container(width: 94, child: rankInfo.records.length >= 3 ? _buildRankHeaderWidget(rankInfo.records[2], 3) : _buildRankHeaderWidget(null, 3)),
            ],
          ),
        ),
        Space(
          height: 10,
        ),
        Divider(
          indent: 12.0,
          endIndent: 12.0,
        )
      ],
    );
  }

  Widget _buildRankHeaderWidget(User item, int rank) {
    return InkWell(
      onTap: item == null ? null : () => NavigatorUtil.goRankPeopleDetails(context, details: item),
      child: Column(
        children: <Widget>[
          rank == 1
              ? Stack(
                  alignment: Alignment.center,
                  children: <Widget>[
                    CircleAvatar(backgroundImage: userAvatarProvider(item == null ? "" : item.userAvatar), radius: 46.0),
                    Image.asset(
                      "lib/assets/img/rank_image_no$rank.png",
                    )
                  ],
                )
              : Stack(
                  alignment: Alignment.topCenter,
                  children: <Widget>[
                    Positioned(top: 3, child: CircleAvatar(backgroundImage: userAvatarProvider(item == null ? "" : item.userAvatar), radius: 35.0)),
                    Image.asset(
                      "lib/assets/img/rank_image_no$rank.png",
                    )
                  ],
                ),
          Space(
            height: 6,
          ),
          Text(
            item == null ? "虚位以待" : item.userName,
            style: Theme.of(context).textTheme.subtitle1,
            maxLines: 1,
          ),
          Space(
            height: 4,
          ),
          Row(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Text(
                item == null ? "" : "${item.score.toStringAsFixed(1)}分",
                style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor),
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildLabelWidget(String title) {
    return Container(
        padding: EdgeInsets.fromLTRB(ui_padding, 10.0, ui_padding, 10.0),
        child: Text(
          title,
          style: Theme.of(context).textTheme.headline1,
        ));
  }

  Widget _buildSportItemWidget(game.GameInfoData item) {
    return Container(
        decoration: BoxDecoration(
            image: DecorationImage(
              image: CachedNetworkImageProvider(item.coverVertical),
              fit: BoxFit.cover,
            ),
            borderRadius: BorderRadius.all(Radius.circular(10.0))),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            Container(
              width: double.infinity,
              padding: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0),
              decoration: BoxDecoration(
                gradient:
                    LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0x00000000), Color(0x912c2c2c), Color(0xCF000000)]),
                borderRadius: BorderRadius.vertical(bottom: Radius.circular(10.0)),
              ),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    item.name,
                    style: Theme.of(context).textTheme.headline3.copyWith(color: Colors.white),
                  ),
                  Space(
                    height: 5,
                  ),
                  if (item.tags != null)
                    Wrap(
                      spacing: 4,
                      runSpacing: 4,
                      children: item.tags.map((e) => gameTag(context, e)).toList(),
                    ),
                  Space(
                    height: 5,
                  ),
                  Text(
                    "${item.userCount}人在玩",
                    style: Theme.of(context).textTheme.bodyText1.copyWith(color: Colors.white),
                  ),
                ],
              ),
            ),
          ],
        ));
  }

  Widget _buildRankItemWidget(User item, int index) {
    return Column(
      children: <Widget>[
        InkWell(
            onTap: item == null ? null : () => NavigatorUtil.goRankPeopleDetails(context, details: item),
            child: Container(
              child: Row(
                children: <Widget>[
                  Container(
                    width: 24,
                    child: Text(
                      "${index + 4}",
                      style: Theme.of(context).textTheme.bodyText2,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.fromLTRB(0, 6, 10.0, 6),
                    child: CircleAvatar(
                        backgroundColor: Colors.transparent, backgroundImage: userAvatarProvider(item == null ? "" : item.userAvatar ?? ""), radius: 22),
                  ),
                  Expanded(
                    child: Text(
                      item == null ? "虚位以待" : item.userName,
                      style: Theme.of(context).textTheme.subtitle1,
                      maxLines: 1,
                    ),
                  ),
                  Text(
                    item == null ? "" : "${item.score.toStringAsFixed(1)}分",
                    style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor),
                  ),
                ],
              ),
            )),
        Divider(),
      ],
    );
  }

  Widget _buildGuideWidget() {
    return Container(
      decoration: card(),
      margin: ui_margin_list,
      child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: () => NavigatorUtil.goPage(context, (context) => GuidePage()),
          child: Stack(children: <Widget>[
            Padding(
              padding: EdgeInsets.all(ui_padding),
              child: Row(
                children: <Widget>[
                  Image.asset("lib/assets/img/home_image_guidance.png"),
                  Space(
                    width: 12,
                  ),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        Text(
                          "新手指引",
                          style: Theme.of(context).textTheme.headline3.copyWith(fontSize: 14.0),
                        ),
                        Space(
                          height: 4,
                        ),
                        Text("帮助您快速了解并使用相关功能", style: Theme.of(context).textTheme.bodyText1),
                      ],
                    ),
                  ),
                ],
              ),
            ),
            Positioned(
              right: 0,
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () async {
                  SharedPreferences preferences = await SharedPreferences.getInstance();
                  preferences.setBool(GUIDE, false);
                  _valueNotifierGuide.value = false;
                },
                child: Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: Image.asset("lib/assets/img/btn_close_small.png"),
                ),
              ),
            )
          ])),
    );
  }

  Widget _buildSportHistoryWidget(game.GameInfoData item) {
    return GameItem(
      type: 1,
      imgUrl: item.cover,
      name: item.name,
      time: item.playTime,
      id: item.id,
      duration: item.durationTotal,
      data: item,
      bold: true,
    );
  }
}

class _HeaderBackground extends CustomPainter {
  final Paint _paint = Paint()
    ..color = Color(0xff241D19)
    ..isAntiAlias = true;

  @override
  void paint(Canvas canvas, Size size) {
    Path path = Path();
    path.lineTo(size.width, 0);
    path.lineTo(size.width, size.height);
    path.lineTo(0, size.height / 3 * 2);
    path.close();
    canvas.drawPath(path, _paint);
  }

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

class RankFlowDelegate extends FlowDelegate {
  @override
  void paintChildren(FlowPaintingContext context) {
    var screenW = context.size.width;
    var childW = screenW / context.childCount;

    double padding = 5; //间距
    double offsetX = padding; //x坐标
    double offsetY = padding; //y坐标

    for (int i = 0; i < context.childCount; i++) {
//      if(i == 0){
      context.paintChild(i, transform: Matrix4.translationValues(offsetX, offsetY, 0));
//      }
    }
  }

  @override
  bool shouldRepaint(FlowDelegate context) => true;
}
