import 'package:flutter/material.dart';
import 'package:peasmartcare/widgets/empty_box.dart';
import 'package:peasmartcare/widgets/fancy_bottom_navigation/internal/tab_item.dart';
import 'package:peasmartcare/widgets/fancy_bottom_navigation/paint/half_clipper.dart';
import 'package:peasmartcare/widgets/fancy_bottom_navigation/paint/half_painter.dart';

const double CIRCLE_SIZE = 60;
const double ARC_HEIGHT = 70;
const double ARC_WIDTH = 90;
const double CIRCLE_OUTLINE = 10;
const double SHADOW_ALLOWANCE = 20;
const double BAR_HEIGHT = 65;

class FancyBottomNavigation extends StatefulWidget {
  FancyBottomNavigation({@required this.tabs, @required this.onTabChangedListener, this.key, this.initialSelection, this.circleColor, this.activeIconColor, this.inactiveIconColor, this.textColor, this.barBackgroundColor})
      : assert(onTabChangedListener != null),
        assert(tabs != null),
        assert(tabs.length > 1 && tabs.length < 5);

  final Function(int position) onTabChangedListener;
  final Color circleColor;
  final Color activeIconColor;
  final Color inactiveIconColor;
  final Color textColor;
  final Color barBackgroundColor;
  final List<TabData> tabs;
  final int initialSelection;

  final Key key;

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

class FancyBottomNavigationState extends State<FancyBottomNavigation> with TickerProviderStateMixin, RouteAware {
  // IconData nextIcon = Icons.search;
  // IconData activeIcon = Icons.search;

  dynamic nextIcon = Icon(Icons.search);
  dynamic activeIcon = Icon(Icons.search);

  int currentSelected = 0;
  double _circleAlignX = 0;
  double _circleIconAlpha = 1;

  Color circleColor;
  Color activeIconColor;
  Color inactiveIconColor;
  Color barBackgroundColor;
  Color textColor;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    // activeIcon = widget.tabs[currentSelected].iconData;
    activeIcon = widget.tabs[currentSelected].imageIcon ?? widget.tabs[currentSelected].icon;

    circleColor = (widget.circleColor == null)
        ? (Theme.of(context).brightness == Brightness.dark)
            ? Colors.white
            : Theme.of(context).primaryColor
        : widget.circleColor;

    activeIconColor = (widget.activeIconColor == null)
        ? (Theme.of(context).brightness == Brightness.dark)
            ? Colors.black54
            : Colors.white
        : widget.activeIconColor;

    barBackgroundColor = (widget.barBackgroundColor == null)
        ? (Theme.of(context).brightness == Brightness.dark)
            ? Color(0xFF212121)
            : Colors.white
        : widget.barBackgroundColor;
    textColor = (widget.textColor == null)
        ? (Theme.of(context).brightness == Brightness.dark)
            ? Colors.white
            : Colors.grey
        : widget.textColor;
    inactiveIconColor = (widget.inactiveIconColor == null)
        ? (Theme.of(context).brightness == Brightness.dark)
            ? Colors.white
            : Theme.of(context).primaryColor
        : widget.inactiveIconColor;
  }

  @override
  void initState() {
    super.initState();
    if (widget.initialSelection > -1) _setSelected(widget.tabs[widget.initialSelection].key);
  }

  _setSelected(UniqueKey key) {
    int selected = widget.tabs.indexWhere((tabData) => tabData.key == key);

    if (mounted) {
      setState(() {
        currentSelected = selected;
        _circleAlignX = -1 + (2 / (widget.tabs.length - 1) * selected);
        // nextIcon = widget.tabs[selected].iconData;
        nextIcon = widget.tabs[selected].imageIcon ?? widget.tabs[selected].icon;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      overflow: Overflow.visible,
      alignment: Alignment.bottomCenter,
      children: <Widget>[
        Container(
          height: BAR_HEIGHT,
          decoration: BoxDecoration(
            color: barBackgroundColor,
            boxShadow: [
              BoxShadow(
                color: Colors.black12,
                offset: Offset(0, -1),
                blurRadius: 8,
              ),
            ],
          ),
          child: Row(
            mainAxisSize: MainAxisSize.max,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: widget.tabs
                .map((t) => TabItem(
                    uniqueKey: t.key,
                    selected: widget.initialSelection < 0 ? false : t.key == widget.tabs[currentSelected].key,
                    // iconData: t.iconData,
                    isShowBadgeCount: t.isShowBadgeCount,
                    badgeCount: t.badgeCount,
                    icon: t.icon,
                    imageIcon: t.imageIcon,
                    title: t.title,
                    iconColor: inactiveIconColor,
                    textColor: textColor,
                    callbackFunction: (uniqueKey) {
                      int selected = widget.tabs.indexWhere((tabData) => tabData.key == uniqueKey);
                      widget.onTabChangedListener(selected);
                      // _setSelected(uniqueKey);
                      _initAnimationAndStart(_circleAlignX, 1);
                    }))
                .toList(),
          ),
        ),
        widget.initialSelection > -1
            ? Positioned.fill(
                top: -(CIRCLE_SIZE + CIRCLE_OUTLINE + SHADOW_ALLOWANCE) / 2,
                child: Container(
                  child: AnimatedAlign(
                    duration: Duration(milliseconds: ANIM_DURATION),
                    curve: Curves.easeOut,
                    alignment: Alignment(_circleAlignX, 1),
                    child: Padding(
                      padding: const EdgeInsets.only(bottom: 15),
                      child: FractionallySizedBox(
                        widthFactor: 1 / widget.tabs.length,
                        child: GestureDetector(
                          onTap: widget.tabs[currentSelected].onclick,
                          child: Stack(
                            alignment: Alignment.center,
                            children: <Widget>[
                              SizedBox(
                                height: CIRCLE_SIZE + CIRCLE_OUTLINE + SHADOW_ALLOWANCE,
                                width: CIRCLE_SIZE + CIRCLE_OUTLINE + SHADOW_ALLOWANCE,
                                child: ClipRect(
                                  clipper: HalfClipper(),
                                  child: Container(
                                    child: Center(
                                      child: Container(
                                        width: CIRCLE_SIZE + CIRCLE_OUTLINE,
                                        height: CIRCLE_SIZE + CIRCLE_OUTLINE,
                                        decoration: BoxDecoration(
                                          color: Colors.white,
                                          shape: BoxShape.circle,
                                          boxShadow: [
                                            BoxShadow(
                                              color: Colors.black12,
                                              blurRadius: 8,
                                            ),
                                          ],
                                        ),
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                              SizedBox(
                                  height: ARC_HEIGHT,
                                  width: ARC_WIDTH,
                                  child: CustomPaint(
                                    painter: HalfPainter(barBackgroundColor),
                                  )),
                              Stack(
                                children: [
                                  SizedBox(
                                    height: CIRCLE_SIZE,
                                    width: CIRCLE_SIZE,
                                    child: Container(
                                      decoration: BoxDecoration(
                                        shape: BoxShape.circle,
                                        color: circleColor,
                                      ),
                                      child: Padding(
                                        padding: const EdgeInsets.all(0.0),
                                        child: AnimatedOpacity(
                                          duration: Duration(milliseconds: ANIM_DURATION ~/ 5),
                                          opacity: _circleIconAlpha,
                                          child: Container(
                                            height: double.infinity,
                                            alignment: Alignment.center,
                                            child: activeIcon,
                                          ),
                                        ),
                                      ),
                                    ),
                                  ),
                                  (widget.tabs[currentSelected].badge != null)
                                      ? widget.tabs[currentSelected].badge
                                      : SizedBox(
                                          height: 25,
                                          width: 25,
                                        ),
                                  (widget.tabs[currentSelected].badge == null && widget.tabs[currentSelected].badgeCount != null && widget.tabs[currentSelected].isShowBadgeCount)
                                      ? Positioned(
                                          top: 0,
                                          right: 0,
                                          child: Container(
                                            padding: EdgeInsets.all(1),
                                            decoration: BoxDecoration(
                                              color: Colors.red,
                                              borderRadius: BorderRadius.circular(50),
                                            ),
                                            constraints: BoxConstraints(
                                              minWidth: 25,
                                              minHeight: 25,
                                            ),
                                            child: widget.tabs[currentSelected].badgeCount,
                                            // child: Text(
                                            //   widget.tabs[currentSelected].badgeCount.toString(),
                                            //   style: TextStyle(
                                            //     color: Colors.white,
                                            //     fontSize: 15,
                                            //   ),
                                            //   textAlign: TextAlign.center,
                                            // ),
                                          ),
                                        )
                                      : SizedBox(
                                          height: 25,
                                          width: 25,
                                        ),
                                ],
                              ),
                              // widget.tabs[currentSelected].badgeCount != null
                              //     ? Positioned(
                              //         top: 10,
                              //         right: 30.0 - (widget.tabs[currentSelected].badgeCount.toString().length * 6),
                              //         child: Container(
                              //           padding: EdgeInsets.all(1),
                              //           decoration: BoxDecoration(
                              //             color: Colors.red,
                              //             borderRadius: BorderRadius.circular(50),
                              //           ),
                              //           constraints: BoxConstraints(
                              //             minWidth: 25,
                              //             minHeight: 25,
                              //           ),
                              //           child: Text(
                              //             widget.tabs[currentSelected].badgeCount.toString(),
                              //             style: TextStyle(
                              //               color: Colors.white,
                              //               fontSize: 15,
                              //             ),
                              //             textAlign: TextAlign.center,
                              //           ),
                              //         ),
                              //       )
                              //     : EmptyBox(),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              )
            : EmptyBox(),
      ],
    );
  }

  _initAnimationAndStart(double from, double to) {
    _circleIconAlpha = 0;

    Future.delayed(Duration(milliseconds: ANIM_DURATION ~/ 5), () {
      setState(() {
        activeIcon = nextIcon;
      });
    }).then((_) {
      Future.delayed(Duration(milliseconds: (ANIM_DURATION ~/ 5 * 3)), () {
        setState(() {
          _circleIconAlpha = 1;
        });
      });
    });
  }

  void setPage(int page) {
    widget.onTabChangedListener(page);
    _setSelected(widget.tabs[page].key);
    _initAnimationAndStart(_circleAlignX, 1);

    setState(() {
      currentSelected = page;
    });
  }
}

class TabData {
  // TabData({@required this.iconData, @required this.title, this.onclick});
  TabData({
    this.icon,
    this.imageIcon,
    @required this.title,
    this.badgeCount,
    this.badge,
    this.isShowBadgeCount = true,
    this.onclick,
  });

  // IconData iconData;
  Icon icon;
  Widget imageIcon;
  String title;
  Widget badgeCount;
  Widget badge;
  bool isShowBadgeCount;
  Function onclick;
  final UniqueKey key = UniqueKey();
}
