import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:tab_indicator_styler/tab_indicator_styler.dart';
import 'package:zhiying_base_widget/pages/custom_page/custom_item_page.dart';
import 'package:zhiying_base_widget/pages/main_page/model/background_model.dart';
import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart';
import 'package:zhiying_base_widget/widgets/empty/empty_widget.dart';
import 'package:zhiying_comm/zhiying_comm.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'bloc/background_bloc.dart';
import 'bloc/custom_page_bloc.dart';
import 'bloc/custom_page_state.dart';
import 'bloc/custom_page_event.dart';
import 'bloc/custom_page_repository.dart';
import 'package:zhiying_base_widget/widgets/search/widget/my_tab.dart';
import 'dart:ui';

///
/// 通用模块页面
///
class CustomPage extends StatefulWidget {
  final Map<String, dynamic> data;

  CustomPage(this.data, {Key key}) : super(key: key);

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

class _CustomPageState extends State<CustomPage> {
  @override
  Widget build(BuildContext context) {
    Logger.log("数据: " + widget?.data.toString());
    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: MainPageBgNotifier()),
      ],
      child: BlocProvider<CustomPageBloc>(
        create: (_) => CustomPageBloc(CustomPageRepository(data: widget?.data))..add(CustomPageInitEvent()),
        child: _CommonPageContainer(widget?.data),
        // ),
      ),
    );
  }
}

class _CommonPageContainer extends StatefulWidget {
  final Map<String, dynamic> data;

  _CommonPageContainer(this.data);

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

class __CommonPageContainerState extends State<_CommonPageContainer> with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
  TabController _tabController;

  // 是否有AppBar
  bool _isHasAppbar = false;

  // 是否有TabBar
  bool _isHasTabBar = false;

  double backgroundTopMargin = 0;

  BackgroundBloc backgroundBloc;

  /// 刷新
  void _onRefreshEvent() async {
    BlocProvider.of<CustomPageBloc>(context).add(CustomPageRefreshEvent());
  }

  @override
  void initState() {
    backgroundBloc = BackgroundBloc();
    super.initState();
  }

  @override
  void dispose() {
    _tabController?.dispose();
    backgroundBloc.streamController.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
    return BlocConsumer<CustomPageBloc, CustomPageState>(
      listener: (context, state) {},
      buildWhen: (prev, current) {
        if (current is CustomPageErrorState) {
          return false;
        }
        if (current is CustomPageRefreshSuccessState) {
          // _refreshController.refreshCompleted(resetFooterState: true);
          return false;
        }
        if (current is CustomPageRefreshErrorState) {
          // _refreshController.refreshFailed();
          return false;
        }
        return true;
      },
      builder: (context, state) {
        /// 有数据
        if (state is CustomPageLoadedState) {
          if (EmptyUtil.isEmpty(state.model)) return _buildEmptyWidget();
          Logger.log("通用模板数据", state.model);
          return _buildMainWidget(state.model, state.backgroundModel);
        }

        /// 初始化失败
        if (state is CustomPageInitErrorState) {
          return _buildEmptyWidget();
        }

        /// 骨架图
        return _buildSkeletonWidget();
      },
    );
  }

  /// 有数据
  Widget _buildMainWidget(List<Map<String, dynamic>> model, BackgroundModel backgroundModel) {
    return Scaffold(
      appBar: _buildAppbar(model?.first),
      backgroundColor: HexColor.fromHex(backgroundModel?.bgColor == null || backgroundModel?.bgColor == '' ? "#FFF9F9F9" : backgroundModel?.bgColor ?? "#FFF9F9F9"),
      // floatingActionButton: _buildFloatWidget(),
      floatingActionButtonLocation: _CustomFloatingActionButtonLocation(FloatingActionButtonLocation.endFloat, 0, -100),
      body: Stack(
        children: <Widget>[
          _buildBackground(backgroundModel),
          Column(children: _buildFirstWidget(model, backgroundModel)),
        ],
      ),
    );
  }

  /// 骨架图
  Widget _buildSkeletonWidget() {
    return Scaffold();
  }

  /// 空数据视图
  Widget _buildEmptyWidget() {
    return Scaffold(
        backgroundColor: HexColor.fromHex('#F9F9F9'),
        appBar: AppBar(
          brightness: Brightness.light,
          backgroundColor: Colors.white,
          leading: IconButton(
            icon: Icon(
              Icons.arrow_back_ios,
              size: 22,
              color: HexColor.fromHex('#333333'),
            ),
            onPressed: () => Navigator.maybePop(context),
          ),
          title: Text(
            '',
            style: TextStyle(color: HexColor.fromHex('#333333'), fontSize: 18, fontWeight: FontWeight.bold),
          ),
          centerTitle: true,
          elevation: 0,
        ),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Align(
              alignment: Alignment.topCenter,
              child: EmptyWidget(
                tips: '网络似乎开小差了~',
              ),
            ),
            GestureDetector(
              onTap: () => _onRefreshEvent(),
              behavior: HitTestBehavior.opaque,
              child: Container(
                alignment: Alignment.center,
                decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), border: Border.all(color: HexColor.fromHex('#999999'), width: 0.5), color: Colors.white),
                width: 80,
                height: 20,
                child: Text(
                  '刷新一下',
                  style: TextStyle(fontSize: 12, color: HexColor.fromHex('#333333'), fontWeight: FontWeight.bold),
                ),
              ),
            )
          ],
        ));
  }

  /// 数据,生成第一层widget
  List<Widget> _buildFirstWidget(List<Map<String, dynamic>> model, BackgroundModel backgroundModel) {
    List<Widget> result = [];

    // 分类导航的key ⚠️ 这里先写成Test 后续要改
    const String CATEGORY_KEY = 'category';
    // 判断是否有分类导航
    // 判断最后一个是否属于分类导航,如果属于,则有分类导航,如果不是,则无分类导航
    bool haveCategory = !EmptyUtil.isEmpty(model?.last) && model.last.containsKey('mod_name') && model.last['mod_name'] == CATEGORY_KEY;
    int endIndexLength = model.length;
    // 如果没有分类导航,则取分类导航之上的所有mod
    if (!haveCategory) {
      for (int i = 0; i < model.length; i++) {
        Map<String, dynamic> item = model[i];
        if (item['mod_name'] == CATEGORY_KEY) {
          endIndexLength = (i + 1);
          break;
        }
      }
    }

    for (int i = 0; i < endIndexLength; i++) {
      WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(model[i]));
      // last model
      if (i == endIndexLength - 1) {
        result.addAll(_buildTabBar(model[i], i));
        break;
      }

      // appBar 无需在这里添加
      if (item.modName.contains('appbar')) {
        continue;
      }
      result.addAll(WidgetFactory.create(item.modName, isSliver: false, model: model[i]));
    }

    // 没有appbar并且没有tabbar,则给第一个元素加边距
    if (!_isHasAppbar) {
      result.insert(0, SizedBox(height: MediaQueryData.fromWindow(window).padding.top, child: Container(color: HexColor.fromHex(backgroundModel?.headerBg?.mainColor))));
    }

    return result;
  }

  /// appbar
  Widget _buildAppbar(final Map<String, dynamic> model) {
    if (EmptyUtil.isEmpty(model)) return null;
    String mobName = model['mod_name'];
    if (!mobName.contains('_appbar')) return null;
    Map<String, dynamic> data = Map<String, dynamic>();
    try {
      data = jsonDecode(model['data']);
    } catch (e, s) {
      Logger.warn(e, s);
    }
    String parentTitle = !EmptyUtil.isEmpty(widget?.data) ? widget?.data['title'] ?? '' : '';
    _isHasAppbar = true;
    return AppBar(
      backgroundColor: HexColor.fromHex(!EmptyUtil.isEmpty(data) ? data['app_bar_bg_color'] ?? '#FFFFFF' : '#FFFFFF'),
      brightness: Brightness.light,
      leading: Navigator.canPop(context) ? IconButton(
        icon: Icon(
          Icons.arrow_back_ios,
          size: 22,
          color: HexColor.fromHex(!EmptyUtil.isEmpty(data) ? data['app_bar_name_color'] ?? '#333333' : '#333333'),
        ),
        onPressed: () => Navigator.maybePop(context),
      ) : null,
      title: Text(
        !EmptyUtil.isEmpty(data) && data.containsKey('app_bar_name')
            // ? data['app_bar_name'] != '自定义页面'
                ? data['app_bar_name']
                // : parentTitle
            : parentTitle,
        style: TextStyle(
          color: HexColor.fromHex(!EmptyUtil.isEmpty(data) ? data['app_bar_name_color'] ?? '#333333' : '#333333'),
          fontSize: 16,
          fontWeight: FontWeight.bold,
        ),
      ),
      centerTitle: true,
      elevation: 0,
    );
  }

  /// tabBar
  List<Widget> _buildTabBar(final Map<String, dynamic> model, final int index) {
    Map<String, dynamic> data = Map<String, dynamic>();
    List<Map<String, dynamic>> listStyle = [];
    List<Widget> result = [];
    try {
      data = jsonDecode(model['data']);
      listStyle = List.from(data['list_style']);
    } catch (e, s) {
      Logger.warn(e, s);
    }

    // 1、导航栏没开启的情况 传null进去进行获取没开启导航栏的widget集合
    if (EmptyUtil.isEmpty(listStyle)) {
      result.add(Expanded(
        child: CustomItemPage(
          null,
          0,
          model['mod_id']?.toString() ?? null,
          model['mod_pid']?.toString() ?? null,
          (!_isHasAppbar && index == 0),
          scroller: _listenScroller,
        ),
      ));
      return result;
    }

    // 2、导航栏开启的情况
    if (listStyle.length > 0) {

      // 获取分类类型,如果第一位type等于imageAndText说明是带有小图标的
      bool haveIcon = false;
      try {
        haveIcon = listStyle[0]['type']?.toString() == 'imageAndText';
      } catch (e, s){
        Logger.error(e, s);
      }

      // tabContorller 初始化
      if (null == _tabController || _tabController.length != listStyle.length) {
        _tabController = new TabController(length: listStyle.length, vsync: this);
      }

      result.add(Container(
        height: 40,
        padding: const EdgeInsets.only(bottom: 5),
        width: double.infinity,
        color: HexColor.fromHex(data['bg_color']),
        child: TabBar(
          controller: _tabController,
          isScrollable: /*listStyle.length <= 5 ? false : */ true,
          labelColor: HexColor.fromHex(data['choose_text_color'] ?? '#FF4242'),
          labelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
          unselectedLabelColor: HexColor.fromHex(data['text_color'] ?? '#999999'),
          unselectedLabelStyle: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
          indicatorSize: TabBarIndicatorSize.label,
          indicator: MaterialIndicator(
            color: HexColor.fromHex(data['choose_color'] ?? '#FF4242'),
            bottomLeftRadius: 1.25,
            topLeftRadius: 1.25,
            topRightRadius: 1.25,
            bottomRightRadius: 1.25,
            height: 2.5,
            horizontalPadding: 5,
          ),
          // 不带图标
          tabs: !haveIcon ? listStyle.map((e) => Text(e['name'])).toList() :
          // 带图标
          listStyle.map((item) {
            return MyTab(
              icon: CachedNetworkImage(
                imageUrl: item['choose_image_url'] ?? '',
                width: 16,
              ),
              text: item['name'],
            );
          }).toList()
        ),
      ));

      _isHasTabBar = true;
      // 最后添加TabBarView
      result.add(Expanded(
        child: TabBarView(
          controller: _tabController,
          children: _buildTabBarViewChildren(listStyle, model['mod_id']?.toString(), model['mod_pid']?.toString(), index),
        ),
      ));
    }
    return result;
  }

  /// 返回TabBarView的视图
  List<Widget> _buildTabBarViewChildren(final List<Map<String, dynamic>> listStyle, final String modId, final String modPid, final int index) {
    List<Widget> result = [];
    for (int i = 0; i < listStyle.length; i++) {
      result.add(CustomItemPage(
        listStyle[i],
        i,
        modId,
        modPid,
        (!_isHasAppbar && !_isHasTabBar && index == 0),
        scroller: _listenScroller,
      ));
    }
    return result;
  }

  /// 背景颜色
  _buildBackground(BackgroundModel backgroundModel) {
    if (backgroundModel != null) {
      var headerBg = backgroundModel.headerBg;
      return StreamBuilder(
        stream: backgroundBloc.outData,
        builder: (context, asncy) {
          return Container(
            constraints: BoxConstraints(minHeight: 0),
            height: (double.tryParse(headerBg?.height) ?? 0) + backgroundTopMargin ?? 0,
            width: double.infinity,
            decoration: BoxDecoration(
                gradient: LinearGradient(
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                    colors: [HexColor.fromHex(headerBg?.mainColor ?? ""), HexColor.fromHex(headerBg?.assistColor ?? ""), HexColor.fromHex(headerBg?.minorColor ?? "")])),
          );
        },
      );
    } else {
      return Container();
    }
  }

// /// 悬浮按钮
// Widget _buildFloatWidget() {
//   return Visibility(
//     visible: true,
//     child: GestureDetector(
//       onTap: () => _scrollTop(),
//       behavior: HitTestBehavior.opaque,
//       child: Container(
//         height: 30,
//         width: 30,
//         child: Icon(Icons.arrow_upward),
//       ),
//     ),
//   );
// }

  ///监听页面滚动
  _listenScroller(double offset) {
    if (offset >= 0) {
      backgroundTopMargin = -offset;
      if (backgroundTopMargin > -500) {
        backgroundBloc.streamController.add("");
      }
    }
  }

  @override
  bool get wantKeepAlive => true;
}

/// 回到顶部的icon
class _CustomFloatingActionButtonLocation extends FloatingActionButtonLocation {
  FloatingActionButtonLocation location;
  double offsetX; // X方向的偏移量
  double offsetY; // Y方向的偏移量
  _CustomFloatingActionButtonLocation(this.location, this.offsetX, this.offsetY);

  @override
  Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
    Offset offset = location.getOffset(scaffoldGeometry);
    return Offset(offset.dx + offsetX, offset.dy + offsetY);
  }
}