import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../../database/database.dart';
import '../../services/settings_service.dart';
import '../../state/settings.dart';
import '../app_router.dart';
import '../now_playing_bar.dart';

part 'bottom_nav_page.g.dart';

@Riverpod(keepAlive: true)
TabObserver bottomTabObserver(BottomTabObserverRef ref) {
  return TabObserver();
}

@Riverpod(keepAlive: true)
Stream<String> bottomTabPath(BottomTabPathRef ref) async* {
  final observer = ref.watch(bottomTabObserverProvider);
  await for (var tab in observer.path) {
    yield tab;
  }
}

@Riverpod(keepAlive: true)
class LastBottomNavStateService extends _$LastBottomNavStateService {
  @override
  Future<void> build() async {
    final db = ref.watch(databaseProvider);
    final tab = ref.watch(bottomTabPathProvider).valueOrNull;
    if (tab == null || tab == 'settings' || tab == 'search') {
      return;
    }

    await db.saveLastBottomNavState(LastBottomNavStateData(id: 1, tab: tab));
  }
}

class BottomNavTabsPage extends HookConsumerWidget {
  const BottomNavTabsPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final observer = ref.watch(bottomTabObserverProvider);
    const navElevation = 3.0;

    return AutoTabsRouter(
      lazyLoad: false,
      inheritNavigatorObservers: false,
      navigatorObservers: () => [observer],
      routes: const [
        LibraryRouter(),
        BrowseRouter(),
        SearchRouter(),
        SettingsRouter(),
      ],
      builder: (context, child, animation) {
        return AnnotatedRegion<SystemUiOverlayStyle>(
          value: SystemUiOverlayStyle.light.copyWith(
            systemNavigationBarColor: ElevationOverlay.applySurfaceTint(
              Theme.of(context).colorScheme.surface,
              Theme.of(context).colorScheme.surfaceTint,
              navElevation,
            ),
            statusBarColor: Colors.transparent,
          ),
          child: Scaffold(
            body: Stack(
              alignment: AlignmentDirectional.bottomStart,
              children: [
                FadeTransition(
                  opacity: animation,
                  child: child,
                ),
                const OfflineIndicator(),
              ],
            ),
            bottomNavigationBar: const _BottomNavBar(
              navElevation: navElevation,
            ),
          ),
        );
      },
    );
  }
}

class OfflineIndicator extends HookConsumerWidget {
  const OfflineIndicator({
    super.key,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final offline = ref.watch(offlineModeProvider);
    final testing = useState(false);

    if (!offline) {
      return Container();
    }

    return Padding(
      padding: const EdgeInsetsDirectional.only(
        start: 20,
        bottom: 20,
      ),
      child: FilledButton.tonal(
        style: const ButtonStyle(
          padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(
            EdgeInsets.zero,
          ),
          fixedSize: MaterialStatePropertyAll<Size>(
            Size(42, 42),
          ),
          minimumSize: MaterialStatePropertyAll<Size>(
            Size(42, 42),
          ),
        ),
        onPressed: () async {
          testing.value = true;
          await ref.read(offlineModeProvider.notifier).setMode(false);
          testing.value = false;
        },
        child: testing.value
            ? const SizedBox(
                height: 16,
                width: 16,
                child: CircularProgressIndicator(strokeWidth: 2.5),
              )
            : const Padding(
                padding: EdgeInsets.only(left: 2, bottom: 2),
                child: Icon(
                  Icons.cloud_off_rounded,
                  // color: Theme.of(context).colorScheme.secondary,
                  size: 20,
                ),
              ),
      ),
    );
  }
}

class _BottomNavBar extends HookConsumerWidget {
  final double navElevation;

  const _BottomNavBar({
    required this.navElevation,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final tabsRouter = AutoTabsRouter.of(context);

    useListenableSelector(tabsRouter, () => tabsRouter.activeIndex);

    return Column(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        const NowPlayingBar(),
        NavigationBar(
          elevation: navElevation,
          height: 50,
          labelBehavior: NavigationDestinationLabelBehavior.alwaysHide,
          selectedIndex: tabsRouter.activeIndex,
          onDestinationSelected: (index) {
            // TODO: replace this with a proper first-time setup flow
            final hasActiveSource = ref.read(settingsServiceProvider.select(
              (value) => value.activeSource != null,
            ));

            if (!hasActiveSource) {
              tabsRouter.setActiveIndex(3);
            } else {
              tabsRouter.setActiveIndex(index);
            }
          },
          destinations: [
            const NavigationDestination(
              icon: Icon(Icons.music_note),
              label: 'Library',
            ),
            NavigationDestination(
              icon: Builder(builder: (context) {
                return SvgPicture.asset(
                  'assets/tag_FILL0_wght400_GRAD0_opsz24.svg',
                  colorFilter: ColorFilter.mode(
                    IconTheme.of(context).color!.withOpacity(
                          IconTheme.of(context).opacity ?? 1,
                        ),
                    BlendMode.srcIn,
                  ),
                  height: 28,
                );
              }),
              label: 'Browse',
            ),
            const NavigationDestination(
              icon: Icon(Icons.search_rounded),
              label: 'Search',
            ),
            const NavigationDestination(
              icon: Icon(Icons.settings_rounded),
              label: 'Settings',
            ),
          ],
        ),
      ],
    );
  }
}
