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

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sport/bean/forum.dart';
import 'package:sport/bean/post.dart';
import 'package:sport/pages/social/post_page.dart';
import 'package:sport/pages/social/post_widget.dart';
import 'package:sport/pages/social/search_page.dart';
import 'package:sport/provider/lib/provider_widget.dart';
import 'package:sport/provider/lib/view_state.dart';
import 'package:sport/provider/lib/view_state_lifecycle.dart';
import 'package:sport/provider/social_detail_model.dart';
import 'package:sport/provider/social_index_model.dart';
import 'package:sport/router/navigator_util.dart';
import 'package:sport/router/routes.dart';
import 'package:sport/services/api/inject_api.dart';
import 'package:sport/services/api/resp.dart';
import 'package:sport/services/userid.dart';
import 'package:sport/widgets/appbar.dart';
import 'package:sport/widgets/error.dart';
import 'package:sport/widgets/loading.dart';
import 'package:sport/widgets/misc.dart';
import 'package:sport/widgets/persistent_header.dart';
import 'package:sport/widgets/space.dart';

final List<String> _tabs = ['热门', '关注', '最新', '精华', '官方'];

class NewSocialIndexPage extends StatefulWidget {
  NewSocialIndexPage();

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

class _PageState extends ViewStateLifecycle<NewSocialIndexPage, SocialDetailModel> with TickerProviderStateMixin, UserId, InjectApi {
  ScrollController _controller;
  double _expandedHeight = 0;
  int _brightness = 0;

  TabController _tabController;
  Future<RespPage<Post>> _getPostListByOfficial;
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  SocialDetailModel createModel() => SocialDetailModel(0);
  SocialIndexModel indexModel = new SocialIndexModel();

  // 右边draw中的 当前选择的索引...

  ValueNotifier<int> drawOneIndex = ValueNotifier(0);
  ValueNotifier<int> drawTwoIndex = ValueNotifier(0);

  String forumId = "";
  String isOfficial;

  List buttonList = [];
  List<Forum> buttonData = [
    new Forum(
      gameName: "全部",
    ),
    new Forum(
      gameName: "用户发布",
      forumId: "0",
    ),
    new Forum(gameName: "官方发布", forumId: "1"),
  ];
  ValueNotifier<bool> isShowSelect = ValueNotifier(false);

  void _refresh() {
    model?.setForumIdAndOrigin(_tabController.index, forumId, isOfficial);
    _controller.animateTo(0, duration: Duration(milliseconds: 100), curve: Curves.ease);
  }

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: _tabs.length, initialIndex: 0, vsync: this)
      ..addListener(() {
        if (_tabController.index.toDouble() == _tabController.animation.value) {
          _refresh();
        }
      });
    _controller = ScrollController()
      ..addListener(() {
        if (_controller.position.pixels >= _expandedHeight - 70) {
          if (_brightness == 0) {
            setState(() {
              _brightness = 1;
            });
          }
        } else {
          if (_brightness == 1) {
            setState(() {
              _brightness = 0;
            });
          }
        }
      });
    initButtonList();
  }

  @override
  void dispose() {
    super.dispose();
    _controller?.dispose();
    _tabController?.dispose();
    PaintingBinding.instance.imageCache.clear();
  }

  Future<int> _getCount() async {
    int count = 0;
    try {
      count += (await model.api.getNoticeCount("comment", "0")).data;
    } catch (e) {
      print(e);
    }
    if (count == 0) {
      try {
        count += (await model.api.getNoticeCount("like", "0")).data;
      } catch (e) {
        print(e);
      }
    }
    return count;
  }

  Widget _buildSearchWidget() {
    return GestureDetector(
      onTap: () {
        Navigator.push(context, new MaterialPageRoute(builder: (context) => SearchPage()));
      },
      child: Container(
//        margin: EdgeInsets.fromLTRB(12.0, 0, 12.0, 12.0),
        width: MediaQuery.of(context).size.width * 0.8,
        height: 35,
        padding: EdgeInsets.fromLTRB(12.0, 0, 12.0, 0),
        decoration: BoxDecoration(
          color: Color(0xffF1F1F1),
          shape: BoxShape.rectangle,
          borderRadius: BorderRadius.all(Radius.circular(50)),
        ),
        child: Row(
          children: <Widget>[
            Image.asset("lib/assets/img/searchbar_icon_search.png"),
            Space(
              width: 4,
            ),
            Text(
              "输入关键词",
              strutStyle: StrutStyle(forceStrutHeight: true),
              style: TextStyle(fontSize: 14, color: Color(0xff999999)),
            ),
          ],
        ),
      ),
    );
  }

  //  @title       button 的title
  //  @index       当前显示的下标
  //  @targetIndex 目标下标
  //  @type        origin / project
  Widget _buildDrawerButtonItem(Forum data, int index, ValueNotifier<int> targetIndex, String type) {
    return InkWell(
      child: Container(
//        height: 35.0,
        decoration: BoxDecoration(
            color: index == targetIndex.value ? Theme.of(context).accentColor : Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(20.0)),
            border: Border.all(color: index == targetIndex.value ? Colors.white : Theme.of(context).dividerTheme.color)),
        padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 25.0),
        child: Text(
          data.gameName,
          strutStyle: StrutStyle(forceStrutHeight: true),
          style: TextStyle(fontSize: 14.0, color: index == targetIndex.value ? Colors.white : Color(0xff999999)),
        ),
      ),
      onTap: () {
        targetIndex.value = index;
        if (type == "project") {
          forumId = data.forumId;
        } else if (type == "origin") {
          isOfficial = data.forumId;
        }
        if (drawOneIndex.value == 0 && drawTwoIndex.value == 0) {
          isShowSelect.value = false;
        } else {
          isShowSelect.value = true;
        }

        model.setForumIdAndOrigin(_tabController.index, forumId, isOfficial);
      },
    );
  }

  Widget _buildDrawButtonContainer(Widget buttons, {String type = 'top'}) {
    return Padding(
      padding: EdgeInsets.only(left: 16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          type == 'top'
              ? Space(
                  height: 21.0,
                )
              : Container(),
          type == 'bottom'
              ? Space(
                  height: 43.0,
                )
              : Container(),
          Text("运动项目", style: TextStyle(color: Color(0xff333333), fontSize: 16.0, fontWeight: FontWeight.bold)),
          Space(
            height: 16.0,
          ),
          buttons,
          type == 'bottom'
              ? Space(
                  height: 21.0,
                )
              : Container(),
        ],
      ),
    );
  }

  Widget _buildButtons(ValueNotifier<int> targetIndex, {List<dynamic> list}) {
    return ValueListenableBuilder(
      valueListenable: targetIndex,
      builder: (BuildContext context, int value, Widget child) => Wrap(
        alignment: WrapAlignment.start,
        crossAxisAlignment: WrapCrossAlignment.start,
        spacing: 8.0,
        runSpacing: 16.0,
        children: list != null
            ? list.asMap().entries.map((e) => _buildDrawerButtonItem(e.value, e.key, targetIndex, "project")).toList()
            : buttonData.asMap().entries.map((e) => _buildDrawerButtonItem(e.value, e.key, targetIndex, "origin")).toList(),
      ),
    );
  }

  Widget _buildEndrawer() {
    return Container(
        height: double.infinity,
        width: MediaQuery.of(context).size.width * 0.65,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10.0),
            bottomLeft: Radius.circular(10.0),
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            _buildDrawButtonContainer(
              _buildButtons(drawOneIndex, list: buttonList),
              type: "bottom",
            ),
            Divider(),
            _buildDrawButtonContainer(
              _buildButtons(drawTwoIndex),
              type: "top",
            ),
          ],
        ));
  }

  Widget _buildFilterButton(String name, ValueNotifier<int> index, String type) {
    return InkWell(
      child: Container(
        padding: EdgeInsets.symmetric(vertical: 6.0, horizontal: 16.0),
        decoration: BoxDecoration(border: Border.all(color: Theme.of(context).accentColor), borderRadius: BorderRadius.all(Radius.circular(44.0))),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Text(
              "$name",
              strutStyle: StrutStyle(forceStrutHeight: true),
              style: TextStyle(color: Theme.of(context).accentColor, fontSize: 12.0),
            ),
            Space(
              width: 5.0,
            ),
            Image.asset(
              "lib/assets/img/btn_close_yellow.png",
              width: 7.0,
              height: 7.0,
            )
          ],
        ),
      ),
      onTap: () {
        type == "one" ? model.setForumIdAndOrigin(_tabController.index, "", isOfficial) : model.setForumIdAndOrigin(_tabController.index, forumId, "");
        index.value = 0;
        if (drawOneIndex.value == 0 && drawTwoIndex.value == 0) {
          isShowSelect.value = false;
        } else {
          isShowSelect.value = true;
        }
      },
    );
  }

  initButtonList() async {
    RespList<Forum> data = await api.getForumIndex();
    setState(() {
      buttonList = data.results;
      if (data.results.length > 0) {
        buttonList.insert(0, new Forum(gameName: "全部"));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      backgroundColor: Colors.white,
      endDrawer: _buildEndrawer(),
      body: ProviderWidget2<SocialDetailModel, SocialIndexModel>(
        model1: model,
        model2: indexModel,
        onModelReady: (model1, model2) => model.initData(),
        builder: (_, model, model2, __) {
          return EasyRefresh.builder(
              controller: model.refreshController,
              enableControlFinishRefresh: true,
              enableControlFinishLoad: true,
              onRefresh: () => model.refresh(),
              onLoad: model.isIdle ? () => model.loadMore() : null,
              header: buildClassicalHeader(),
              footer: buildClassicalFooter(),
              builder: (context, physics, header, footer) {
                return AnnotatedRegion<SystemUiOverlayStyle>(
                  value: SystemUiOverlayStyle.dark,
                  child: Material(
                    color: Colors.white,
                    child: SafeArea(
                      child: CustomScrollView(
                        controller: _controller,
                        physics: physics,
                        slivers: <Widget>[
                          buildSliverAppBar(context, "社区",
                              canBack: false,
                              pinned: false,
                              height: 100.0,
                              padding: const EdgeInsets.fromLTRB(12.0, 0, 0, 6.0),
                              actions: <Widget>[
                                Selector<SocialIndexModel, ViewState>(
                                    selector: (_, SocialIndexModel model) => model.viewState,
                                    shouldRebuild: (_, v) => v == ViewState.idle,
                                    builder: (BuildContext context, ViewState value, Widget child) {
                                      return IconButton(
                                        icon: Stack(
                                          alignment: Alignment.center,
                                          children: <Widget>[
                                            Image.asset("lib/assets/img/bbs_icon_news.png"),
                                            FutureBuilder(
                                                future: SharedPreferences.getInstance(),
                                                builder: (BuildContext context, AsyncSnapshot<SharedPreferences> snapshot) {
                                                  if (snapshot.connectionState == ConnectionState.done) {
                                                    if (snapshot.data.getBool("message_setting") ?? true == true) {
                                                      return FutureBuilder(
                                                          future: _getCount(),
                                                          builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
                                                            if (snapshot.data != null && snapshot.data > 0) {
                                                              return Align(
                                                                alignment: Alignment.topRight,
                                                                child: Container(
                                                                  margin: const EdgeInsets.only(top: 6.0),
                                                                  width: 10,
                                                                  height: 10,
                                                                  decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.red),
                                                                  child: Center(
                                                                    child: Text(""),
                                                                  ),
                                                                ),
                                                              );
                                                            }
                                                            return Container();
                                                          });
                                                    }
                                                  }
                                                  return Container();
                                                }),
                                          ],
                                        ),
                                        onPressed: () async {
                                          await NavigatorUtil.go(context, Routes.socialMessage);
                                          setState(() {});
                                        },
                                      );
                                    }),
                              ],
                              paddingLeading: false),
                          header,
                          SliverPersistentHeader(
                            delegate: PersistentHeader(
                                min: 50,
                                max: 50,
                                child: Container(
                                  color: Colors.white,
                                  padding: EdgeInsets.only(bottom: 10),
                                  child: TabBar(
                                    isScrollable: true,
                                    indicatorPadding: EdgeInsets.symmetric(horizontal: 8),
                                    indicatorWeight: 3,
                                    controller: _tabController,
                                    tabs: _tabs.map((e) => Tab(text: e)).toList(),
                                  ),
                                )),
                            pinned: true,
                          ),
                          SliverToBoxAdapter(
                            child: Padding(
                              padding: EdgeInsets.symmetric(vertical: 6.0, horizontal: 12.0),
                              child: Row(
                                children: <Widget>[
                                  _buildSearchWidget(),
                                  Space(
                                    width: 15.0,
                                  ),
                                  ValueListenableBuilder(
                                    valueListenable: isShowSelect,
                                    builder: (context, flag, child) => InkWell(
                                      child: flag
                                          ? Image.asset(
                                              "lib/assets/img/bbs_icon_choose_press.png",
                                              width: 22,
                                              height: 22,
                                            )
                                          : Image.asset(
                                              "lib/assets/img/bbs_icon_choose_normal.png",
                                              width: 22,
                                              height: 22,
                                            ),
                                      onTap: () => _scaffoldKey.currentState.openEndDrawer(),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                          SliverToBoxAdapter(
                            child: Padding(
                              padding: EdgeInsets.only(left: 12.0),
                              child: Row(
                                children: <Widget>[
                                  if (drawOneIndex.value != 0) _buildFilterButton('${buttonList[drawOneIndex.value].gameName}', drawOneIndex, "one"),
                                  Space(
                                    width: 10.0,
                                  ),
                                  if (drawTwoIndex.value != 0) _buildFilterButton('${buttonData[drawTwoIndex.value].gameName}', drawTwoIndex, "two"),
                                ],
                              ),
                            ),
                          ),
                          if (model.isBusy)
                            SliverToBoxAdapter(
                              child: RequestLoadingWidget(),
                            ),
                          if (model.isEmpty)
                            SliverFillRemaining(
                              child: Center(
                                child: RequestErrorWidget(
                                  null,
                                  msg: "暂无帖子~",
                                  assets: RequestErrorWidget.ASSETS_NO_INVITATION,
                                ),
                              ),
                            ),
                          if (model.isIdle)
                            SliverList(
                              delegate: SliverChildBuilderDelegate(
                                (context, index) {
                                  Post post = model.list[index];
                                  return PostWidget(post, model, selfId == post.userId);
                                },
                                childCount: model.list.length,
                              ),
                            ),
                        ],
                      ),
                    ),
                  ),
                );
              });
        },
      ),
      floatingActionButtonLocation: const _EndFloatFloatingActionButtonLocation(),
      floatingActionButtonAnimator:const _ScalingFabMotionAnimator(),
      floatingActionButton: InkWell(
        child: Image.asset("lib/assets/img/bbs_icon_edit.png"),
        onTap: () async {
//            print('FloatingActionButton');
          var result = await NavigatorUtil.goPage(
              context,
              (context) => PostPage(
                    "",
                    forums: buttonList,
                  ));
          if (result == true) {
            if (_tabController.index.toDouble() == _tabController.animation.value) {
              _refresh();
            } else {
              _tabController?.index = 2;
            }
          }
        },
      ),
    );
  }
}

class _EndFloatFloatingActionButtonLocation extends FloatingActionButtonLocation {
  const _EndFloatFloatingActionButtonLocation();

  double _rightOffset(ScaffoldPrelayoutGeometry scaffoldGeometry, {double offset = 0.0}) {
    return scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.minInsets.right - scaffoldGeometry.floatingActionButtonSize.width + offset;
  }

  double getDockedY(ScaffoldPrelayoutGeometry scaffoldGeometry) {
    final double contentBottom = scaffoldGeometry.contentBottom;
    final double bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height;
    final double fabHeight = scaffoldGeometry.floatingActionButtonSize.height;
    final double snackBarHeight = scaffoldGeometry.snackBarSize.height;

    double fabY = contentBottom - fabHeight / 2.0;
    // The FAB should sit with a margin between it and the snack bar.
    if (snackBarHeight > 0.0) fabY = min(fabY, contentBottom - snackBarHeight - fabHeight - kFloatingActionButtonMargin);
    // The FAB should sit with its center in front of the top of the bottom sheet.
    if (bottomSheetHeight > 0.0) fabY = min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0);

    final double maxFabY = scaffoldGeometry.scaffoldSize.height - fabHeight;
    return min(maxFabY, fabY);
  }

  @override
  Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
    final double fabX = _rightOffset(scaffoldGeometry, offset: -8.0);
    final double fabY = getDockedY(scaffoldGeometry);
    return Offset(fabX, fabY - 8);
  }

  @override
  String toString() => 'FloatingActionButtonLocation.endFloat';
}

class _ScalingFabMotionAnimator extends FloatingActionButtonAnimator {
  const _ScalingFabMotionAnimator();

  @override
  Offset getOffset({ Offset begin, Offset end, double progress }) {

    return end;
  }

  @override
  Animation<double> getScaleAnimation({ Animation<double> parent }) {
    return AlwaysStoppedAnimation(1.0);
  }

  @override
  Animation<double> getRotationAnimation({ Animation<double> parent }) {
    return AlwaysStoppedAnimation(1.0);
  }

  // If the animation was just starting, we'll continue from where we left off.
  // If the animation was finishing, we'll treat it as if we were starting at that point in reverse.
  // This avoids a size jump during the animation.
  @override
  double getAnimationRestart(double previousValue) => 1.0;
}