content: import 'dart:io';
  
  import 'package:fl_clash/common/common.dart';
  import 'package:fl_clash/enum/enum.dart';
  import 'package:fl_clash/models/models.dart';
  import 'package:fl_clash/providers/providers.dart';
  import 'package:fl_clash/state.dart';
  import 'package:fl_clash/widgets/widgets.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter_riverpod/flutter_riverpod.dart';
  import 'package:intl/intl.dart';
  
  typedef OnSelected = void Function(int index);
  
  class HomePage extends StatelessWidget {
    const HomePage({super.key});
  
    @override
    Widget build(BuildContext context) {
      return HomeBackScope(
        child: Consumer(
          builder: (_, ref, child) {
            final state = ref.watch(homeStateProvider);
            final viewMode = state.viewMode;
            final navigationItems = state.navigationItems;
            final pageLabel = state.pageLabel;
            final index = navigationItems.lastIndexWhere(
              (element) => element.label == pageLabel,
            );
            final currentIndex = index == -1 ? 0 : index;
            final navigationBar = CommonNavigationBar(
              viewMode: viewMode,
              navigationItems: navigationItems,
              currentIndex: currentIndex,
            );
            final bottomNavigationBar =
                viewMode == ViewMode.mobile ? navigationBar : null;
            final sideNavigationBar =
                viewMode != ViewMode.mobile ? navigationBar : null;
            return CommonScaffold(
              key: globalState.homeScaffoldKey,
              title: Intl.message(
                pageLabel.name,
              ),
              sideNavigationBar: sideNavigationBar,
              body: child!,
              bottomNavigationBar: bottomNavigationBar,
            );
          },
          child: _HomePageView(),
        ),
      );
    }
  }
  
  class _HomePageView extends ConsumerStatefulWidget {
    const _HomePageView();
  
    @override
    ConsumerState createState() => _HomePageViewState();
  }
  
  class _HomePageViewState extends ConsumerState<_HomePageView> {
    late PageController _pageController;
  
    @override
    void initState() {
      super.initState();
      _pageController = PageController(
        initialPage: _pageIndex,
        keepPage: true,
      );
      ref.listenManual(currentPageLabelProvider, (prev, next) {
        if (prev != next) {
          _toPage(next);
        }
      });
      ref.listenManual(currentNavigationsStateProvider, (prev, next) {
        if (prev?.value.length != next.value.length) {
          _updatePageController();
        }
      });
    }
  
    int get _pageIndex {
      final navigationItems = ref.read(currentNavigationsStateProvider).value;
      return navigationItems.indexWhere(
        (item) => item.label == globalState.appState.pageLabel,
      );
    }
  
    _toPage(PageLabel pageLabel, [bool ignoreAnimateTo = false]) async {
      if (!mounted) {
        return;
      }
      final navigationItems = ref.read(currentNavigationsStateProvider).value;
      final index = navigationItems.indexWhere((item) => item.label == pageLabel);
      if (index == -1) {
        return;
      }
      final isAnimateToPage = ref.read(appSettingProvider).isAnimateToPage;
      final isMobile = ref.read(isMobileViewProvider);
      if (isAnimateToPage && isMobile && !ignoreAnimateTo) {
        await _pageController.animateToPage(
          index,
          duration: kTabScrollDuration,
          curve: Curves.easeOut,
        );
      } else {
        _pageController.jumpToPage(index);
      }
    }
  
    _updatePageController() {
      final pageLabel = globalState.appState.pageLabel;
      _toPage(pageLabel, true);
    }
  
    @override
    void dispose() {
      _pageController.dispose();
      super.dispose();
    }
  
    @override
    Widget build(BuildContext context) {
      final navigationItems = ref.watch(currentNavigationsStateProvider).value;
      return PageView.builder(
        controller: _pageController,
        physics: const NeverScrollableScrollPhysics(),
        itemCount: navigationItems.length,
        // onPageChanged: (index) {
        //   debouncer.call(DebounceTag.pageChange, () {
        //     WidgetsBinding.instance.addPostFrameCallback((_) {
        //       if (_pageIndex != index) {
        //         final pageLabel = navigationItems[index].label;
        //         _toPage(pageLabel, true);
        //       }
        //     });
        //   });
        // },
        itemBuilder: (_, index) {
          final navigationItem = navigationItems[index];
          return KeepScope(
            keep: navigationItem.keep,
            key: Key(navigationItem.label.name),
            child: navigationItem.fragment,
          );
        },
      );
    }
  }
  
  class CommonNavigationBar extends ConsumerWidget {
    final ViewMode viewMode;
    final List<NavigationItem> navigationItems;
    final int currentIndex;
  
    const CommonNavigationBar({
      super.key,
      required this.viewMode,
      required this.navigationItems,
      required this.currentIndex,
    });
  
    @override
    Widget build(BuildContext context, ref) {
      if (viewMode == ViewMode.mobile) {
        return NavigationBarTheme(
          data: _NavigationBarDefaultsM3(context),
          child: NavigationBar(
            destinations: navigationItems
                .map(
                  (e) => NavigationDestination(
                    icon: e.icon,
                    label: Intl.message(e.label.name),
                  ),
                )
                .toList(),
            onDestinationSelected: (index) {
              globalState.appController.toPage(navigationItems[index].label);
            },
            selectedIndex: currentIndex,
          ),
        );
      }
      final showLabel = ref.watch(appSettingProvider).showLabel;
      return Material(
        color: context.colorScheme.surfaceContainer,
        child: Column(
          children: [
            Expanded(
              child: ScrollConfiguration(
                behavior: HiddenBarScrollBehavior(),
                child: SingleChildScrollView(
                  child: IntrinsicHeight(
                    child: NavigationRail(
                      backgroundColor: context.colorScheme.surfaceContainer,
                      selectedIconTheme: IconThemeData(
                        color: context.colorScheme.onSurfaceVariant,
                      ),
                      unselectedIconTheme: IconThemeData(
                        color: context.colorScheme.onSurfaceVariant,
                      ),
                      selectedLabelTextStyle:
                          context.textTheme.labelLarge!.copyWith(
                        color: context.colorScheme.onSurface,
                      ),
                      unselectedLabelTextStyle:
                          context.textTheme.labelLarge!.copyWith(
                        color: context.colorScheme.onSurface,
                      ),
                      destinations: navigationItems
                          .map(
                            (e) => NavigationRailDestination(
                              icon: e.icon,
                              label: Text(
                                Intl.message(e.label.name),
                              ),
                            ),
                          )
                          .toList(),
                      onDestinationSelected: (index) {
                        globalState.appController
                            .toPage(navigationItems[index].label);
                      },
                      extended: false,
                      selectedIndex: currentIndex,
                      labelType: showLabel
                          ? NavigationRailLabelType.all
                          : NavigationRailLabelType.none,
                    ),
                  ),
                ),
              ),
            ),
            const SizedBox(
              height: 16,
            ),
            IconButton(
              onPressed: () {
                ref.read(appSettingProvider.notifier).updateState(
                      (state) => state.copyWith(
                        showLabel: !state.showLabel,
                      ),
                    );
              },
              icon: const Icon(Icons.menu),
            ),
            const SizedBox(
              height: 16,
            ),
          ],
        ),
      );
    }
  }
  
  class _NavigationBarDefaultsM3 extends NavigationBarThemeData {
    _NavigationBarDefaultsM3(this.context)
        : super(
            height: 80.0,
            elevation: 3.0,
            labelBehavior: NavigationDestinationLabelBehavior.alwaysShow,
          );
  
    final BuildContext context;
    late final ColorScheme _colors = Theme.of(context).colorScheme;
    late final TextTheme _textTheme = Theme.of(context).textTheme;
  
    @override
    Color? get backgroundColor => _colors.surfaceContainer;
  
    @override
    Color? get shadowColor => Colors.transparent;
  
    @override
    Color? get surfaceTintColor => Colors.transparent;
  
    @override
    WidgetStateProperty<IconThemeData?>? get iconTheme {
      return WidgetStateProperty.resolveWith((Set<WidgetState> states) {
        return IconThemeData(
          size: 24.0,
          color: states.contains(WidgetState.disabled)
              ? _colors.onSurfaceVariant.opacity38
              : states.contains(WidgetState.selected)
                  ? _colors.onSecondaryContainer
                  : _colors.onSurfaceVariant,
        );
      });
    }
  
    @override
    Color? get indicatorColor => _colors.secondaryContainer;
  
    @override
    ShapeBorder? get indicatorShape => const StadiumBorder();
  
    @override
    WidgetStateProperty<TextStyle?>? get labelTextStyle {
      return WidgetStateProperty.resolveWith((Set<WidgetState> states) {
        final TextStyle style = _textTheme.labelMedium!;
        return style.apply(
            overflow: TextOverflow.ellipsis,
            color: states.contains(WidgetState.disabled)
                ? _colors.onSurfaceVariant.opacity38
                : states.contains(WidgetState.selected)
                    ? _colors.onSurface
                    : _colors.onSurfaceVariant);
      });
    }
  }
  
  class HomeBackScope extends StatelessWidget {
    final Widget child;
  
    const HomeBackScope({super.key, required this.child});
  
    @override
    Widget build(BuildContext context) {
      if (Platform.isAndroid) {
        return CommonPopScope(
          onPop: () async {
            final canPop = Navigator.canPop(context);
            if (canPop) {
              Navigator.pop(context);
            } else {
              await globalState.appController.handleBackOrExit();
            }
            return false;
          },
          child: child,
        );
      }
      return child;
    }
  }
  