import 'package:chat/utils/screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

class GZXDropdownMenuController extends ChangeNotifier {
  double dropDownHearderHeight;

  int menuIndex = 0;

  bool isShow = false;

  void show(int index) {
    isShow = true;
    menuIndex = index;
    notifyListeners();
  }

  void hide() {
    isShow = false;
    notifyListeners();
  }
}

typedef OnItemTap<T> = void Function(T value);

class GZXDropDownHeader extends StatefulWidget {
  final Color color;
  final double borderWidth;
  final Color borderColor;
  final TextStyle style;
  final TextStyle dropDownStyle;
  final double iconSize;
  final Color iconColor;
  final Color iconDropDownColor;

//  final List<String> menuStrings;
  final double height;
  final double dividerHeight;
  final Color dividerColor;
  final GZXDropdownMenuController controller;
  final OnItemTap onItemTap;
  final List<GZXDropDownHeaderItem> items;
  final GlobalKey stackKey;

  GZXDropDownHeader({
    Key key,
    @required this.items,
    @required this.controller,
    @required this.stackKey,
    this.style = const TextStyle(color: Color(0xFF666666), fontSize: 13),
    this.dropDownStyle,
    this.height = 40,
    this.iconColor = const Color(0xFFafada7),
    this.iconDropDownColor,
    this.iconSize = 20,
    this.borderWidth = 0,
    this.borderColor = const Color(0xFFeeede6),
    this.dividerHeight = 20,
    this.dividerColor = const Color(0xFFeeede6),
    this.onItemTap,
    this.color = Colors.white,
  }) : super(key: key);

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

class _GZXDropDownHeaderState extends State<GZXDropDownHeader>
    with SingleTickerProviderStateMixin {
  bool _isShowDropDownItemWidget = false;

  int _menuCount;
  GlobalKey _keyDropDownHearder = GlobalKey();

  @override
  void initState() {

    super.initState();

    widget.controller.addListener(_onController);
  }

  _onController() {
//    print(widget.controller.menuIndex);
  }

  @override
  Widget build(BuildContext context) {
//    print('_GZXDropDownHeaderState.build');

    _menuCount = widget.items.length;

    var gridView = GridView.count(
      physics: new NeverScrollableScrollPhysics(),
      crossAxisCount: _menuCount,
      childAspectRatio: (Screen.width / _menuCount) / widget.height,
      children: widget.items.map<Widget>((item) {
        return _menu(item);
      }).toList(),
    );

    return Container(
      key: _keyDropDownHearder,
      height: widget.height,
      margin: EdgeInsets.zero,
      padding: EdgeInsets.symmetric(horizontal: 10),
      decoration: BoxDecoration(
        border:
            Border.all(color: widget.borderColor, width: widget.borderWidth),
      ),
      child: gridView,
    );
  }

  dispose() {
    super.dispose();
  }

  _menu(GZXDropDownHeaderItem item) {
    int index = widget.items.indexOf(item);
    int menuIndex = widget.controller.menuIndex;
    _isShowDropDownItemWidget = index == menuIndex && widget.controller.isShow;

    return GestureDetector(
      onTap: () {
        final RenderBox overlay =
            widget.stackKey.currentContext.findRenderObject();

        final RenderBox dropDownItemRenderBox =
            _keyDropDownHearder.currentContext.findRenderObject();

        var position =
            dropDownItemRenderBox.localToGlobal(Offset.zero, ancestor: overlay);
//        print("POSITION : $position ");
        var size = dropDownItemRenderBox.size;
//        print("SIZE : $size");

        widget.controller.dropDownHearderHeight = size.height + position.dy;

        if (widget.controller.isShow) {
          widget.controller.hide();
        } else {
          widget.controller.show(index);
        }
        if (widget.onItemTap != null) {
          widget.onItemTap(index);
        }
        setState(() {});
      },
      child: Container(
          color: widget.color,
          width: Screen.width/3-20,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Expanded(
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Flexible(
                        child: Text(
                      item.title,  textScaleFactor: 1.0,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      style: _isShowDropDownItemWidget
                          ? widget.dropDownStyle
                          ??TextStyle(color: Theme.of(context).primaryColor, fontSize: 13)
                          : widget.style,
                    )),
                    Icon(
                      !_isShowDropDownItemWidget
                          ? item.iconData ?? Icons.arrow_drop_down
                          : item.iconData ?? Icons.arrow_drop_up,
                      color: _isShowDropDownItemWidget
                          ? widget.iconDropDownColor ?? Theme.of(context).primaryColor
                          : widget.iconColor,
                      size: item.iconSize ?? widget.iconSize,
                    ),
                  ],
                ),
              )
            ],
          )),
    );
  }
}

class GZXDropDownHeaderItem {
  final String title;
  final IconData iconData;
  final double iconSize;

  GZXDropDownHeaderItem(
    this.title, {
    this.iconData,
    this.iconSize,
  });
}

class GZXDropdownMenuBuilder {
  final Widget dropDownWidget;
  final double dropDownHeight;
  final callback;

  GZXDropdownMenuBuilder(
      {@required this.dropDownWidget,
      @required this.dropDownHeight,
      @required this.callback});
}

class GZXDropDownMenu extends StatefulWidget {
  final GZXDropdownMenuController controller;
  final List<GZXDropdownMenuBuilder> menus;
  final int animationMilliseconds;

  const GZXDropDownMenu(
      {Key key,
      @required this.controller,
      @required this.menus,
      this.animationMilliseconds = 100})
      : super(key: key);

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

class _GZXDropDownMenuState extends State<GZXDropDownMenu>
    with SingleTickerProviderStateMixin {
  bool _isShowDropDownItemWidget = false;
  bool _isShowMask = false;
  bool _isControllerDisposed = false;
  Animation<double> _animation;
  AnimationController _controller;

  @override
  void initState() {

    super.initState();

    widget.controller.addListener(_onController);
    _controller = new AnimationController(
        duration: Duration(milliseconds: widget.animationMilliseconds),
        vsync: this);
  }

  _onController() {
//    print('_GZXDropDownMenuState._onController ${widget.controller.menuIndex}');

    _showDropDownItemWidget();
  }

  @override
  Widget build(BuildContext context) {
//    print('_GZXDropDownMenuState.build');
    _controller.duration = Duration(milliseconds: widget.animationMilliseconds);
    return _buildDropDownWidget();
  }

  dispose() {
    _controller.dispose();
    _isControllerDisposed = true;
    super.dispose();
  }

  _showDropDownItemWidget() {
    int menuIndex = widget.controller.menuIndex;
    if (menuIndex >= widget.menus.length || widget.menus[menuIndex] == null) {
      return;
    }

    _isShowDropDownItemWidget = !_isShowDropDownItemWidget;
    _isShowMask = !_isShowMask;

    _animation =
        new Tween(begin: 0.0, end: widget.menus[menuIndex].dropDownHeight)
            .animate(_controller)
              ..addListener(() {
                //这行如果不写，没有动画效果
                setState(() {});
              });

    if (_isControllerDisposed) return;

    if (_animation.status == AnimationStatus.completed) {
      _controller.reverse();
    } else {
      _controller.forward();
    }
  }

  _hideDropDownItemWidget() {
    _isShowDropDownItemWidget = !_isShowDropDownItemWidget;
    _isShowMask = !_isShowMask;
    _controller.reverse();
    widget.controller.isShow = false;
  }

  Widget _mask(callback) {
    if (_isShowMask) {
      return GestureDetector(
        onTap: () {
          print('到mask了');
          _hideDropDownItemWidget();
          if (callback != null) callback();
        },
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height * 2,
          color: Color.fromRGBO(0, 0, 0, 0.1),
        ),
      );
    } else {
      return Container(
        height: 0,
      );
    }
  }

  Widget _buildDropDownWidget() {
    int menuIndex = widget.controller.menuIndex;

    return Positioned(
        width: MediaQuery.of(context).size.width,
        top: widget.controller.dropDownHearderHeight,
        left: 0,
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.white,
              width: MediaQuery.of(context).size.width,
              height: _animation == null ? 0 : _animation.value,
              child: widget.menus[menuIndex].dropDownWidget,
            ),
            _mask(widget.menus[menuIndex].callback)
          ],
        ));
  }
}
