import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
import 'package:sk_base_mobile/widgets/core/sk_ink.dart';
import 'package:sk_base_mobile/widgets/gradient_button.dart';
import 'package:sk_base_mobile/widgets/loading_indicator.dart';

class CascadeItem<T, Z> {
  late String label;
  T? value;
  List<Z>? children;
  CascadeItem({required this.label, this.value, this.children});
}

class SkCascadePicker<T, Z> extends StatelessWidget {
  final SkCascadePickerController cascadeController;
  final int maxPageNum;
  final Color tabColor;
  final double tabHeight;
  final TextStyle? tabTitleStyle;
  final double itemHeight;
  final TextStyle? itemTitleStyle;
  final Color itemColor;
  final Color activeColor;
  final Widget? selectedIcon;
  final Function(List<CascadeItem<T, Z>>)? onConfirm;

  SkCascadePicker(
      {required Future<List<CascadeItem<T, Z>>> Function() getData,
      required List<CascadeItem<T, Z>> Function(SkCascadePickerController<T, Z>)
          initialPageData,
      required NextPageCallback<T, Z> nextPageData,
      this.onConfirm,
      this.maxPageNum = 3,
      this.tabHeight = 40,
      this.activeColor = AppTheme.primaryColor,
      this.tabColor = Colors.white,
      this.tabTitleStyle,
      this.itemHeight = 40,
      this.itemColor = Colors.white,
      this.itemTitleStyle,
      this.selectedIcon})
      : cascadeController = Get.put(SkCascadePickerController<T, Z>(
            initialPageData: initialPageData,
            nextPageData: nextPageData,
            getData: getData));

  @override
  Widget build(BuildContext context) {
    return Container(
        decoration: const BoxDecoration(color: AppTheme.nearlyWhite),
        height: ScreenAdaper.height(400),
        width: Get.width,
        child: Obx(() => cascadeController.loading.value
            ? const LoadingIndicator(
                common: true,
              )
            : Column(children: [
                Container(
                  padding: EdgeInsets.symmetric(
                      horizontal: ScreenAdaper.width(20),
                      vertical: ScreenAdaper.height(10)),
                  child: Row(
                    children: [
                      SkInk(
                          onTap: () {
                            Get.back();
                          },
                          child: Text(
                            '取消',
                            style: TextStyle(fontSize: ScreenAdaper.height(30)),
                          )),
                      const Spacer(),
                      SkInk(
                          onTap: () {
                            Get.back();
                            if (onConfirm != null) {
                              onConfirm!(cascadeController.selectedTabs
                                  .where((e) =>
                                      e.label !=
                                      SkCascadePickerController.newTabName)
                                  .toList() as List<CascadeItem<T, Z>>);
                            }
                          },
                          child: Text(
                            '确定',
                            style: TextStyle(
                                fontSize: ScreenAdaper.height(30),
                                color: AppTheme.primaryColor),
                          ))
                    ],
                  ),
                ),
                const Divider(
                  height: 1,
                ),
                // GradientButton(
                //   buttonText: '确定',
                //   onPressed: () {
                //     Get.back();
                //     if (onConfirm != null) {
                //       onConfirm!(cascadeController.selectedTabs
                //           .where((e) =>
                //               e.label != SkCascadePickerController.newTabName)
                //           .toList() as List<CascadeItem<T, Z>>);
                //     }

                //     // 已选中的titles
                //     // List<CascadeItem<T,Z>> selectedTitles =
                //     //     cascadeController.selectedTabs;
                //     // print("已选中的titles: $selectedTitles");
                //     // 已选中的序号
                //     // List<int> selectedIndexes =
                //     //     cascadeController.selectedIndexes;
                //     // print("已选中的序号：$selectedIndexes");
                //   },
                // ),
                Expanded(
                    child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    AnimatedBuilder(
                      animation: cascadeController.sliderAnimation!,
                      builder: (context, child) => Stack(
                        clipBehavior: Clip.hardEdge,
                        alignment: Alignment.bottomLeft,
                        children: [
                          Container(
                            padding: EdgeInsets.symmetric(
                                horizontal: ScreenAdaper.width(20)),
                            width: MediaQuery.of(context).size.width,
                            child: Obx(
                              () => SingleChildScrollView(
                                controller: cascadeController.scrollController,
                                scrollDirection: Axis.horizontal,
                                child: Row(children: _tabWidgets()),
                              ),
                            ),
                          ),
                          ValueListenableBuilder<double>(
                            valueListenable: cascadeController.sliderFixMargin,
                            builder: (_, margin, __) => Positioned(
                              left: margin +
                                  cascadeController.sliderAnimation!.value,
                              child: Container(
                                key: cascadeController.sliderKey,
                                width: cascadeController.sliderWidth,
                                height: 2,
                                decoration: BoxDecoration(
                                    color: activeColor,
                                    borderRadius: BorderRadius.circular(2)),
                              ),
                            ),
                          )
                        ],
                      ),
                    ),
                    Expanded(
                      child: PageView.builder(
                        itemCount: cascadeController.pagesData.length,
                        controller: cascadeController.pageController,
                        itemBuilder: (context, index) => _pageWidget(index),
                        onPageChanged: (position) {
                          if (!cascadeController.isClickAndMoveTab) {
                            cascadeController.moveSlider(position,
                                movePage: false);
                          }
                          if (cascadeController.urrentSelectPage == position) {
                            cascadeController.isClickAndMoveTab = false;
                          }
                        },
                      ),
                    )
                  ],
                ))
              ])));
  }

  /// 注意：tab渲染完成才开始动画，即调用moveSlider，这个方法会在动画执行期间多次调用
  Widget _animateTab({required Widget tab}) {
    return Transform.translate(
      offset: Offset(
          Tween<double>(
                  begin: cascadeController.isAddTabEvent
                      ? -cascadeController.animTabWidth
                      : 0,
                  end: 0)
              .evaluate(cascadeController.curvedAnimation),
          0),
      child: Opacity(

          /// 动画未开始前隐藏文本
          opacity: cascadeController.isAnimateTextHide ? 0 : 1,
          child: tab),
    );
  }

  List<Widget> _tabWidgets() {
    List<Widget> widgets = [];
    cascadeController.tabKeys.clear();
    for (int i = 0; i < cascadeController.pagesData.length; i++) {
      GlobalKey key = GlobalKey();
      cascadeController.tabKeys.add(key);
      final tab = GestureDetector(
        child: Container(
          key: key,
          height: tabHeight,
          color: tabColor,
          alignment: Alignment.center,
          child: Container(
            // constraints: BoxConstraints(
            //     maxWidth: MediaQuery.of(Get.context!).size.width /
            //             cascadeController.pagesData.length -
            //         10),
            child: Text(
              cascadeController.selectedTabs[i].label,
              style: cascadeController.urrentSelectPage == i
                  ? (tabTitleStyle ??
                          TextStyle(
                              color: Colors.black,
                              fontSize: ScreenAdaper.height(30)))
                      .copyWith(color: activeColor)
                  : (tabTitleStyle ??
                      TextStyle(
                          color: Colors.black,
                          fontSize: ScreenAdaper.height(30))),
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ),
        onTap: () {
          cascadeController.moveSlider(i);
        },
      );
      if (i == cascadeController.pagesData.length - 1 &&
          cascadeController.selectedTabs[i].label ==
              SkCascadePickerController.newTabName) {
        widgets.add(_animateTab(tab: tab));
      } else {
        widgets.add(tab);
      }
      cascadeController.isAnimateTextHide = false;
      if (i < cascadeController.pagesData.length - 1) {
        widgets.add(Container(
          // color: Colors.red,
          child: Icon(
            Icons.arrow_right,
            size: ScreenAdaper.height(50),
          ),
        ));
      }
    }
    return widgets;
  }

  /// 选择项
  Widget _pageItemWidget(int index, int page, CascadeItem item) {
    return GestureDetector(
      child: Container(
        alignment: Alignment.centerLeft,
        padding: EdgeInsets.symmetric(horizontal: ScreenAdaper.width(20)),
        height: itemHeight,
        color: itemColor,
        child: Obx(() => Row(
              children: [
                item == cascadeController.selectedTabs[page]
                    ? Padding(
                        padding: const EdgeInsets.all(5.0),
                        child: selectedIcon == null
                            ? Icon(Icons.chevron_right,
                                size: ScreenAdaper.height(40),
                                color: activeColor)
                            : selectedIcon,
                      )
                    : SizedBox(),
                Text(item.label,
                    style: item == cascadeController.selectedTabs[page]
                        ? (itemTitleStyle ??
                                TextStyle(
                                    color: Colors.black,
                                    fontSize: ScreenAdaper.height(30)))
                            .copyWith(color: activeColor)
                        : (itemTitleStyle ??
                            TextStyle(
                                color: Colors.black,
                                fontSize: ScreenAdaper.height(30)))),
              ],
            )),
      ),
      onTap: () {
        if (page == maxPageNum - 1) {
          /// 当前页是最后一页
          cascadeController.selectedTabs[page] = item;
          cascadeController.selectedIndexes[page] = index;

          /// 调整滑块位置
          WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
            cascadeController.moveSlider(page);
          });
        } else if (cascadeController.tabKeys.length >= maxPageNum ||
            page < cascadeController.tabKeys.length - 1) {
          if (index == cascadeController.selectedIndexes[page]) {
            /// 选择相同的item
            cascadeController.moveSlider(page + 1);
          } else {
            /// 选择不同的item，更新tab renderBox
            cascadeController.selectedTabs[page] = item;
            cascadeController.selectedIndexes[page] = index;
//              selectedIndexes.removeRange(page + 1, selectedIndexes.length);
            cascadeController.loadNextPageData(page + 1, index, item,
                isUpdatePage: true);
          }
        } else {
          /// 添加新tab页面
          /// page == tabKeys.length - 1 && tabKeys.length == widget.maxPageNum
          cascadeController.selectedTabs[page] = item;
          cascadeController.selectedIndexes[page] = index;
          cascadeController.addTab(page + 1, index, item);
        }
      },
    );
  }

  Widget _pageWidget(int page) {
    return Obx(() => ListView.builder(
          padding: EdgeInsets.zero,
          itemCount: cascadeController.pagesData[page].length,
          itemBuilder: (context, index) => _pageItemWidget(
              index, page, cascadeController.pagesData[page][index]),
//      separatorBuilder: (context, index) => Divider(height: 0.3, thickness: 0.3, color: Color(0xffdddddd), indent: 15, endIndent: 15,),
        ));
  }
}

class SkCascadePickerController<T, Z> extends GetxController
    with GetSingleTickerProviderStateMixin {
  RxList<CascadeItem<T, Z>> treeData = RxList([]);
  final Future<List<CascadeItem<T, Z>>> Function() getData;
  final List<CascadeItem<T, Z>> Function(SkCascadePickerController<T, Z>)
      initialPageData;
  final NextPageCallback<T, Z> nextPageData;
  final RxBool loading = false.obs;
  final scrollController = ScrollController();
  SkCascadePickerController(
      {required this.initialPageData,
      required this.nextPageData,
      required this.getData});
  @override
  void onInit() {
    init();
    animateController = AnimationController(
        duration: const Duration(milliseconds: 500), vsync: this);
    curvedAnimation =
        CurvedAnimation(parent: animateController, curve: Curves.ease)
          ..addStatusListener((state) {});
    sliderAnimation = Tween<double>(begin: 0, end: 10).animate(curvedAnimation);

    super.onInit();
  }

  Future<void> init() async {
    loading.value = true;
    treeData.assignAll(await getData());
    // 树形结构展评
    selectedTabs.add(CascadeItem<T, Z>(label: newTabName));
    pagesData.add(initialPageData(this));
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      RenderBox tabBox =
          tabKeys.first.currentContext?.findRenderObject() as RenderBox;
      sliderFixMargin.value = (tabBox.size.width - sliderWidth) / 2;
    });
    loading.value = false;
  }

  bool isCompleted() =>
      !selectedTabs.map((item) => item.label).contains(newTabName);

  static String newTabName = "请选择";

  late final AnimationController animateController;
  late final CurvedAnimation curvedAnimation;
  Animation? sliderAnimation;
  final sliderFixMargin = ValueNotifier(0.0);
  double sliderWidth = 20;

  PageController pageController = PageController(initialPage: 0);

  GlobalKey sliderKey = GlobalKey();
  List<GlobalKey> tabKeys = [];

  /// 选择器数据集合
  RxList<List<CascadeItem<T, Z>>> pagesData = RxList([]);

  /// 已选择的title集合
  RxList<CascadeItem<T, Z>> selectedTabs = RxList([]);

  /// 已选择的item index集合
  RxList<int> selectedIndexes = RxList([-1]);

  /// "请选择"tab宽度，添加新的tab时用到
  double animTabWidth = 0;

  /// tab添加事件记录，用于隐藏"请选择"tab初始化状态
  bool isAddTabEvent = false;

  /// tab移动未开始，渲染'请选择'tab时隐藏文本，这时的tab在终点位置
  bool isAnimateTextHide = false;

  /// 防止moveSlider重复调用
  bool isClickAndMoveTab = false;

  /// 当前选择的页面，移动滑块前赋值
  int urrentSelectPage = 0;

  addTab(int page, int atIndex, CascadeItem<T, Z> currentPageItem) {
    loadNextPageData(page, atIndex, currentPageItem);
  }

  loadNextPageData(int page, int atIndex, CascadeItem<T, Z> currentPageItem,
      {bool isUpdatePage = false}) {
    nextPageData((data) {
      final nextPageDataIsEmpty = data.isEmpty;
      if (!nextPageDataIsEmpty) {
        /// 下一页有数据，更新本页数据或添加新的页面
        if (isUpdatePage) {
          /// 更新下一页
          pagesData[page] = data;
          selectedTabs[page] = CascadeItem<T, Z>(label: newTabName);
          selectedIndexes[page] = -1;

          /// 清空下下页以后的所有页面和tab数据
          pagesData.removeRange(page + 1, pagesData.length);
          selectedIndexes.removeRange(page + 1, selectedIndexes.length);
          selectedTabs.removeRange(page + 1, selectedTabs.length);
        } else {
          /// 添加新的页面
          isAnimateTextHide = true;
          isAddTabEvent = true;
          pagesData.add(data);
          selectedTabs.add(CascadeItem<T, Z>(label: newTabName));
          selectedIndexes.add(-1);
        }
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          moveSlider(page, isAdd: true);
        });
      } else {
        /// 如果下一页数据为空，那么更新本页数据
        final currentPage = page - 1;
        selectedTabs[currentPage] = currentPageItem;
        selectedIndexes[currentPage] = atIndex;

        /// 下一页数据为空，清空下一页以后的所有页面和tab数据
        pagesData.removeRange(page, pagesData.length);
        selectedIndexes.removeRange(page, selectedIndexes.length);
        selectedTabs.removeRange(page, selectedTabs.length);
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          // 调整滑块位置
          moveSlider(currentPage);
        });
      }
      // 滚动到最底部
      Future.delayed(const Duration(milliseconds: 500), () {
        scrollController.jumpTo(scrollController.position.maxScrollExtent);
      });
    }, page, atIndex, currentPageItem, this);
  }

  moveSlider(int page, {bool movePage = true, bool isAdd = false}) {
    if (movePage && urrentSelectPage != page) {
      /// 上一次选择的页面和本次选择的页面不同时，移动tab标签，
      /// 移动时先把isClickAndMoveTab设为true，防止滑动PageView
      /// 时moveSlider重复调用。
      isClickAndMoveTab = true;
    }
    isAddTabEvent = isAdd;
    urrentSelectPage = page;

    if (animateController.isAnimating) {
      animateController.stop();
    }
    RenderBox slider =
        sliderKey.currentContext?.findRenderObject() as RenderBox;
    Offset sliderPosition = slider.localToGlobal(Offset.zero);
    RenderBox currentTabBox =
        tabKeys[page].currentContext?.findRenderObject() as RenderBox;
    Offset currentTabPosition = currentTabBox.localToGlobal(Offset.zero);

    animTabWidth = currentTabBox.size.width;

    final begin = sliderPosition.dx - sliderFixMargin.value;
    final end = currentTabPosition.dx +
        (currentTabBox.size.width - sliderWidth) / 2 -
        sliderFixMargin.value;
    sliderAnimation =
        Tween<double>(begin: begin, end: end).animate(curvedAnimation);
    animateController.value = 0;
    animateController.forward();
    if (movePage) {
      pageController.animateToPage(page,
          curve: Curves.linear, duration: Duration(milliseconds: 500));
    }
  }

  @override
  void onClose() {
    animateController.dispose();
    pageController.dispose();
    scrollController.dispose();
    super.onClose();
  }
}

/// pageData: 下一页的数据
/// currentPage: 当前是第几页,
/// selectIndex: 当前页选中第几项
typedef void NextPageCallback<T, Z>(
    Function(List<CascadeItem<T, Z>>) pageData,
    int currentPage,
    int selectIndex,
    CascadeItem<T, Z> currentPageItem,
    SkCascadePickerController<T, Z> cascadeController);
