import 'package:auto_size_text/auto_size_text.dart';
import 'package:design/design.dart';
import 'package:guru_widgets/common/custom_rrect_tab_indicator.dart';
import 'package:guru_widgets/common/flexible_container.dart';
import 'package:guru_widgets/common/spacer.dart';
import 'package:guru_widgets/theme/guru_theme.dart';
import 'package:guru_utils/widget/widget_utils.dart';

part 'guru_tab_bar.g.dart';

@DesignSpec(width: 750, height: 1624, specMode: SpecMode.nested)
abstract class GuruTabBarDesignSpec implements BasicDesignSpec {
  @SpecHorizontal(40)
  double get tabHorizontalSpacing;

  @SpecVertical(8)
  double get tabBarBottomMargin;

  @SpecHeight(40)
  double get tabBarRadius;

  @SpecHeight(80)
  double get tabBarHeight;

  @SpecFontSize(26)
  double get tabBarLabelFontSize;

  @SpecFontSize(20)
  double get tabBarLabelMinFontSize;

  @SpecHorizontal(32)
  double get tabBarLabelHorizontalSpacing;

  @SpecHeight(56)
  double get tabBarIconSize;

  @SpecHeight(8)
  double get tabIndicatorInset;

  static GuruTabBarDesignSpec create(Size size,
          {Offset offset = Offset.zero}) =>
      _GuruTabBarDesignSpec.from(size, offset: offset);
}

/// Guru Tab Bar Item (tabs 标签)
/// [GuruTabBarItem] Used to create [GuruTabBar]'s items
/// items can have up to four tabs，Three times display text,
/// four times if there is an icon display, no text display

class GuruTabBarItem {
  /// Title is tab text
  final String title;

  /// Icon is a image instead of title
  final String? icon;

  final String? activeIcon;

  GuruTabBarItem({required this.title, this.icon, this.activeIcon});
}

/// Guru Tab Bar (Tabs 标签页组件).
/// Guru Tab Bar provides a tabbar where each tab indicator is a toggle button.
/// It allows you to create interactive and compliant tab bars for your Flutter applications
///
/// {@tool dartpad}
/// This is an example to create [GuruTabBar]
///
/// ** See code in examples/lib/pages/tabbar/tarbar_View.dart **
/// {@end-tool}

class GuruTabBar extends StatefulWidget {
  /// initialIndex
  /// [GuruTabBar] tab index initially selected. The default value is 0.
  /// [GuruTabBar] 初始选中的标签的index， 默认为0。

  final int? initialIndex;

  /// Items
  /// [GuruTabBar] tabs's configure, Up to four items, item is [GuruTabBarItem].
  /// [GuruTabBar] 配置选项卡内容，最多四个标签项, 标签为[GuruTabBarItem]。

  final List<GuruTabBarItem> items;

  /// TabViews
  /// [GuruTabBar] Display content corresponding to tabs,Quantity is equal to the number of items.
  /// [GuruTabBar] 标签对应的展示内容的数组，数量等于items的数量

  final List<Widget>? tabViews;

  final bool showIcon;

  final double? tabbarTopSpacing;

  final double? tabbarBottomSpacing;

  /// indicator
  /// [GuruTabBar] The tabbar's indicator Decoration.
  /// [GuruTabBar] tabbar 的指示器样式

  final Decoration? indicator;

  /// color
  /// [GuruTabBar] The color of the tab text or image when it is not selected.
  /// [GuruTabBar] 标签文字或者图片未选中时的颜色

  final Color? unSelctedColor;

  /// selectedColor
  /// [GuruTabBar] The color of the tab text or image when it is selected.
  /// [GuruTabBar] 标签文字或者图片选中时的颜色

  final Color? selectedColor;

  /// bgColor
  /// [GuruTabBar] The background color of the tab when it is not selected.
  /// [GuruTabBar] 标签未选中时的背景颜色

  final Color? backgroundColor;

  /// selectedBgColor
  /// [GuruTabBar] The background color of the tab when it is selected.
  /// [GuruTabBar] 标签选中时的背景颜色

  final Color? selectedBackgroundColor;

  /// unSelectedBackgroundColor
  /// [GuruTabBar] The background color of the tab when it is selected.
  /// [GuruTabBar] 标签未选中时的背景颜色

  final Color? unSelectedBackgroundColor;

  /// onChange
  /// [GuruTabBar] The callback function for tab index change.
  /// [GuruTabBar] 标签页切换的回调函数

  final ValueChanged<int>? onChange;

  const GuruTabBar(
      {super.key,
      this.initialIndex,
      required this.items,
      this.showIcon = false,
      this.tabbarTopSpacing,
      this.tabbarBottomSpacing,
      this.tabViews,
      this.indicator,
      this.backgroundColor,
      this.selectedColor,
      this.selectedBackgroundColor,
      this.unSelctedColor,
      this.unSelectedBackgroundColor,
      this.onChange});

  @override
  State<GuruTabBar> createState() => _GuruTabBarState();
}

class _GuruTabBarState extends State<GuruTabBar> with TickerProviderStateMixin {
  final designSpec = GuruThemeDesignSpec.get().tabBarDesignSpec;
  late final TabController _tabController;
  late int currentIndex;

  @override
  void initState() {
    super.initState();
    currentIndex = widget.initialIndex ?? 0;
    _tabController = TabController(
        initialIndex: widget.initialIndex ?? 0,
        length: widget.items.length,
        vsync: this);
    _tabController.addListener(() {
      if (_tabController.index != currentIndex) {
        setState(() {
          currentIndex = _tabController.index;
        });
        widget.onChange?.call(_tabController.index);
      }
    });
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  List<Widget> _buidlTabBarItem(BuildContext context) {
    final guruTheme = GuruTheme.of(context);
    final tabBarTheme = guruTheme.tabBarTheme;
    final Color color = widget.unSelctedColor ??
        tabBarTheme.unSelctedColor ??
        Colors.white.withOpacity(0.4);
    final Color selectedColor =
        widget.selectedColor ?? tabBarTheme.selectedColor ?? Colors.white;

    final List<Widget> widgets = [];
    for (int i = 0; i < widget.items.length; i++) {
      final GuruTabBarItem item = widget.items[i];
      if (widget.showIcon && item.icon != null) {
        final icon =
            currentIndex == i ? (item.activeIcon ?? item.icon!) : item.icon!;
        widgets.add(Image.asset(icon,
            width: designSpec.tabBarIconSize,
            height: designSpec.tabBarIconSize,
            color: item.activeIcon != null
                ? null
                : (currentIndex == i ? selectedColor : color)));
      } else {
        widgets.add(
          FlexibleContainer(
              height: designSpec.tabBarHeight,
              alignment: Alignment.center,
              child: Text(item.title,
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                  style: const TextStyle(height: 1.1),
                  textAlign: TextAlign.center)),
        );
      }
    }
    return widgets;
  }

  @override
  Widget build(BuildContext context) {
    final guruTheme = GuruTheme.of(context);
    final colorScheme = guruTheme.colorScheme;
    final tabBarTheme = guruTheme.tabBarTheme;

    String maxTitle = '';

    for (var item in widget.items) {
      if (item.title.length > maxTitle.length) {
        maxTitle = item.title;
      }
    }

    final List<dynamic> labelFontSize = WidgetUtils.calculateFontSize(
        context,
        maxTitle,
        BoxConstraints(
            maxHeight:
                designSpec.tabBarHeight - (designSpec.tabIndicatorInset * 2),
            maxWidth: (designSpec.measuredSize.width -
                        (designSpec.tabHorizontalSpacing * 2) -
                        (designSpec.tabIndicatorInset * 2)) /
                    widget.items.length -
                (designSpec.tabBarLabelHorizontalSpacing * 2)),
        textAlign: TextAlign.center,
        maxLines: 2,
        maxFontSize: designSpec.tabBarLabelFontSize,
        minFontSize: designSpec.tabBarLabelMinFontSize);

    final items = <Widget>[
      FlexibleContainer(
        color: widget.backgroundColor ??
            tabBarTheme.backgroundColor ??
            const Color(0xFF343436),
        margin: EdgeInsets.only(
            top: widget.tabbarTopSpacing ?? 0,
            left: designSpec.tabHorizontalSpacing,
            right: designSpec.tabHorizontalSpacing,
            bottom:
                widget.tabbarBottomSpacing ?? designSpec.tabBarBottomMargin),
        height: designSpec.tabBarHeight,
        radius: BorderRadius.circular(designSpec.tabBarRadius),
        padding: EdgeInsets.all(designSpec.tabIndicatorInset),
        child: TabBar(
          indicator: widget.indicator ??
              tabBarTheme.indicator ??
              CustomRRecTabIndicator(
                  radius: designSpec.tabBarHeight * 0.5,
                  color: widget.selectedBackgroundColor ??
                      tabBarTheme.selectedBackgroundColor ??
                      colorScheme.primaryColor),
          indicatorSize: TabBarIndicatorSize.tab,
          indicatorWeight: 0,
          labelColor:
              widget.selectedColor ?? tabBarTheme.selectedColor ?? Colors.white,
          labelStyle: TextStyle(
            fontSize: labelFontSize[0],
            color: widget.selectedColor ??
                tabBarTheme.selectedColor ??
                Colors.white,
            fontWeight: GuruTheme.fwSemiBold,
            fontFamily: "EncodeSansExpanded",
          ),
          labelPadding: EdgeInsets.symmetric(
              horizontal: designSpec.tabBarLabelHorizontalSpacing),
          unselectedLabelColor: widget.unSelctedColor ??
              tabBarTheme.unSelctedColor ??
              Colors.white.withOpacity(0.4),
          unselectedLabelStyle: TextStyle(
            fontSize: labelFontSize[0],
            fontWeight: GuruTheme.fwMedium,
            fontFamily: "EncodeSansExpanded",
          ),
          tabs: _buidlTabBarItem(context),
          controller: _tabController,
          dividerHeight: 0
        ),
      ),
    ];

    if (widget.tabViews != null) {
      items.add(Expanded(
        flex: 1,
        child: TabBarView(
            controller: _tabController,
            // physics: const NeverScrollableScrollPhysics(),
            children: widget.tabViews ?? [Container()]),
      ));
    }

    return Column(
      children: items,
    );
  }
}
