/*
 * @Author: XianKaiQun
 * @Date: 2020-04-15 16:43:01
 * @LastEditors  : WuWei
 * @LastEditTime : 2023-06-26 15:46:08
 * @Descripttion:
 */

import 'package:flutter/material.dart';
import 'package:wisdom_cli/wisdom_cli.dart';
import 'package:wisdom_cli/src/assets.gen.dart';

///滚动视图，使用与[CustomScrollView]比较接近。
///
///通过传入[onInit],[onRefresh],[onLoad]函数进行相关回调。
///
///通过[GlobalKey<WisScrollViewState>()]去控制相关widget显示及操作
///
class WisScrollView extends StatefulWidget {
  WisScrollView({
    Key? key,
    this.onRefresh,
    this.onInit,
    this.onLoad,
    this.showInit,
    this.showOnLoad,
    this.emptyWidget,
    this.beforeWidget,
    this.loadingWidget,
    this.finishWidget,
    this.slivers,
    this.wantKeepAlive = true,
    this.controller,
    this.bottomSpace,
  }) : super(key: key);

  ///下拉刷新
  ///
  final Future<void> Function()? onRefresh;

  ///首次加载
  final Future<void> Function()? onInit;

  ///到底加载
  final Future<void> Function()? onLoad;

  ///是否显示第一次加载时的提示
  final bool? showInit;

  ///是否显示加载时的提示
  final bool? showOnLoad;

  ///为空时显示的widget
  final Widget? emptyWidget;

  ///加载前显示的widget
  final Widget? beforeWidget;

  ///加载时显示的widget
  final Widget? loadingWidget;

  ///加载完成时显示的widget
  final Widget? finishWidget;

  final List<Widget>? slivers;

  final bool? wantKeepAlive;
  final ScrollController? controller;
  final double? bottomSpace;
  @override
  WisScrollViewState createState() => WisScrollViewState();
}

enum _LoadingType {
  ///首次加载中
  initting,

  ///下拉刷新中
  refreshing,

  ///触底加载中
  loading,

  ///加载为空
  empty,

  ///加载已到底
  last,

  ///准备加载
  ready,
}

class WisScrollViewState extends State<WisScrollView>
    with AutomaticKeepAliveClientMixin {
  ///手动触发下拉刷新
  refreshTrigger() {
    _refreshIndicatorKey.currentState?.show();
  }

  ///手动再次触发init
  initTrigger() {
    _onInit();
  }

  ///告诉组件加载到底了
  isLast() {
    setState(() {
      _stateType = _LoadingType.last;
    });
  }

  ///告诉组件加载为空
  isEmpty() {
    setState(() {
      _stateType = _LoadingType.empty;
    });
  }

  ScrollController? _controller;
  @override
  bool get wantKeepAlive => widget.wantKeepAlive ?? false;

  ///下拉刷新key
  final _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();

  ///如果有事件，那嘚让scrollview时刻都能滚动
  ScrollPhysics? get _physics =>
      widget.onRefresh != null ? AlwaysScrollableScrollPhysics() : null;

  _LoadingType? _stateType;

  Future<void> onSetInit() async => {
        _stateType = _LoadingType.initting,
        setState(() {}),
      };

  Future<void> _onInit() async {
    if (widget.onInit != null && mounted) {
      _stateType = _LoadingType.initting;
      setState(() {});
      await widget.onInit!();
      if (_stateType != _LoadingType.last && _stateType != _LoadingType.empty) {
        setState(() {
          _stateType = _LoadingType.ready;
        });
      }
    }
  }

  Future<void> _onRefresh() async {
    if (widget.onRefresh != null) {
      _stateType = _LoadingType.refreshing;
      setState(() {});
      await widget.onRefresh!();
      if (_stateType != _LoadingType.last && _stateType != _LoadingType.empty) {
        setState(() {
          _stateType = _LoadingType.ready;
        });
      }
    }
  }

  Future<void> _onLoad() async {
    if (widget.onLoad != null) {
      _stateType = _LoadingType.loading;
      setState(() {});
      await widget.onLoad!();
      if (_stateType != _LoadingType.last && _stateType != _LoadingType.empty) {
        setState(() {
          _stateType = _LoadingType.ready;
        });
      }
    }
  }

  @override
  void initState() {
    super.initState();
    _controller = widget.controller ?? ScrollController();
    if (widget.onInit != null) {
      ///触发首次加载
      WidgetsBinding.instance.addPostFrameCallback((callback) async {
        await _onInit();
      });
    }

    ///触发到底加载
    if (widget.onLoad != null) {
      _controller!.addListener(() async {
        var position = _controller!.position;
        if (position.pixels == position.maxScrollExtent) {
          if (_stateType == _LoadingType.ready) {
            await _onLoad();
          }
        }
      });
    }
  }

  _slivertobox({Widget? child}) {
    return SliverToBoxAdapter(
      child: Container(
        constraints: BoxConstraints(minHeight: 50),
        alignment: Alignment.center,
        child: child,
      ),
    );
  }

  _loadingW() {
    return _slivertobox(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          SizedBox(
            height: 15,
            width: 15,
            child: CircularProgressIndicator(
              valueColor: AlwaysStoppedAnimation(
                Theme.of(context).indicatorColor,
              ),
              strokeWidth: 1.5,
            ),
          ),
          Padding(
            padding: EdgeInsets.symmetric(horizontal: 10),
            child: Text(
              '加载中···',
              style: TextStyle(
                color: Color(0xffaaaaaa),
                fontSize: 12,
                height: 1,
              ),
            ),
          ),
        ],
      ),
    );
  }

  // _loadingInitW() {
  //   return _slivertobox(
  //     child: Row(
  //       mainAxisAlignment: MainAxisAlignment.center,
  //       children: <Widget>[
  //         SizedBox(
  //           height: 15,
  //           width: 15,
  //           child: CircularProgressIndicator(
  //             valueColor: AlwaysStoppedAnimation(
  //               Theme.of(context).indicatorColor,
  //             ),
  //             strokeWidth: 1.5,
  //           ),
  //         ),
  //         Padding(
  //           padding: EdgeInsets.symmetric(horizontal: 10),
  //           child: Text(
  //             '加载中···',
  //             style: TextStyle(
  //               color: Color(0xffaaaaaa),
  //               fontSize: 12,
  //               height: 1,
  //             ),
  //           ),
  //         ),
  //       ],
  //     ),
  //   );
  // }

  _lastW() {
    return _slivertobox(
      child: Wisdom.row(
        margin: EdgeInsets.only(bottom: widget.bottomSpace ?? 0),
        padding: EdgeInsets.only(top: 10.pt),
        children: <Widget>[
          Expanded(
            child: Container(
              height: 1,
              color: Color(0xffdddddd),
            ),
          ),
          Padding(
            padding: EdgeInsets.symmetric(horizontal: 20),
            child: Text(
              '暂无更多内容',
              style: TextStyle(color: Color(0xffaaaaaa), fontSize: 12),
            ),
          ),
          Expanded(
            child: Container(
              height: 1,
              color: Color(0xffdddddd),
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    Widget current = CustomScrollView(
      controller: _controller,
      physics: _physics,
      slivers: [
        if ((widget.slivers ?? []).length > 0) ...widget.slivers!,
        if (_stateType == _LoadingType.initting) _loadingW(),
        if (_stateType == _LoadingType.loading) _loadingW(),
        if (_stateType == _LoadingType.last && widget.onLoad != null) _lastW(),
        if (_stateType == _LoadingType.ready && widget.onLoad != null)
          _slivertobox(),
        if (_stateType == _LoadingType.empty && widget.emptyWidget == null)
          SliverFillRemaining(
            child: Container(
              color: Colors.white,
              child: Wisdom.column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Wisdom(
                    child: WImage(
                      image: AssetList.$empty_png_image,
                      width: 200.pt,
                    ),
                  ),
                  Wisdom(
                    child: Text(
                      '暂无数据',
                      style: TextStyle(
                        color: Color(0xffaaaaaa),
                        fontSize: 14.pt,
                        height: 2,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        if (_stateType == _LoadingType.empty && widget.emptyWidget != null)
          widget.emptyWidget!
      ],
    );

    if (widget.onRefresh != null) {
      current = RefreshIndicator(
        key: _refreshIndicatorKey,
        color: Theme.of(context).indicatorColor,
        child: current,
        onRefresh: _onRefresh,
      );
    }
    return current;
  }
}
