
import 'dart:async';
import 'dart:developer';

import 'package:easy_debounce/easy_throttle.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
import 'package:provider/provider.dart';
import 'package:badges/badges.dart' as badges;

import 'api/mhsl/breaker/getBreakers/getBreakersResponse.dart';
import 'api/mhsl/server/userIndex/update/updateUserindex.dart';
import 'model/breakers/Breaker.dart';
import 'model/breakers/BreakerProps.dart';
import 'model/chatList/chatListProps.dart';
import 'model/timetable/timetableProps.dart';
import 'notification/notificationController.dart';
import 'notification/notificationTasks.dart';
import 'notification/notifyUpdater.dart';
import 'storage/base/settingsProvider.dart';
import 'view/pages/files/files.dart';
import 'view/pages/overhang.dart';
import 'view/pages/talk/chatList.dart';
import 'view/pages/timetable/timetable.dart';

class App extends StatefulWidget {
  const App({super.key});

  static PersistentTabController bottomNavigator = PersistentTabController(initialIndex: 0);

  @override
  State<App> createState() => _AppState();
}

class _AppState extends State<App> with WidgetsBindingObserver {
  late Timer refetchChats;
  late Timer updateTimings;

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    log("AppLifecycle: ${state.toString()}");

    if(state == AppLifecycleState.resumed) {
      EasyThrottle.throttle(
        "appLifecycleState",
        const Duration(seconds: 10),
        () {
          log("Refreshing due to LifecycleChange");
          NotificationTasks.updateProviders(context);
          Provider.of<TimetableProps>(context, listen: false).run();
        }
      );
    }
  }


  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      Provider.of<BreakerProps>(context, listen: false).run();
      Provider.of<ChatListProps>(context, listen: false).run();
    });

    updateTimings = Timer.periodic(const Duration(seconds: 30), (Timer t) => setState((){}));

    refetchChats = Timer.periodic(const Duration(seconds: 60), (timer) {
      WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
        Provider.of<ChatListProps>(context, listen: false).run();
      });
    });

    // User index
    UpdateUserIndex.index();

    // User Notifications
    if(Provider.of<SettingsProvider>(context, listen: false).val().notificationSettings.enabled) {
      update() => NotifyUpdater.registerToServer();
      FirebaseMessaging.instance.onTokenRefresh.listen((event) => update());
      update();
    }
    
    FirebaseMessaging.onMessage.listen((message) => NotificationController.onForegroundMessageHandler(message, context));
    FirebaseMessaging.onBackgroundMessage(NotificationController.onBackgroundMessageHandler);

    FirebaseMessaging.onMessageOpenedApp.listen((message) => NotificationController.onAppOpenedByNotification(message, context));
    FirebaseMessaging.instance.getInitialMessage().then((message) => message == null ? null : NotificationController.onAppOpenedByNotification(message, context));

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return PersistentTabView(
      controller: App.bottomNavigator,
      gestureNavigationEnabled: true,
      navBarOverlap: const NavBarOverlap.none(),
      backgroundColor: Theme.of(context).colorScheme.primary,

      screenTransitionAnimation: const ScreenTransitionAnimation(curve: Curves.easeOutQuad, duration: Duration(milliseconds: 200)),
      tabs: [
        PersistentTabConfig(
          screen: const Breaker(breaker: BreakerArea.timetable, child: Timetable()),
          item: ItemConfig(
            activeForegroundColor: Theme.of(context).primaryColor,
            inactiveForegroundColor: Theme.of(context).colorScheme.secondary,
            icon: const Icon(Icons.calendar_month),
            title: "Vertretung"
          ),
        ),
        PersistentTabConfig(
          screen: const Breaker(breaker: BreakerArea.talk, child: ChatList()),
          item: ItemConfig(
            activeForegroundColor: Theme.of(context).primaryColor,
            inactiveForegroundColor: Theme.of(context).colorScheme.secondary,
            icon: Consumer<ChatListProps>(
              builder: (context, value, child) {
                if(value.primaryLoading()) return const Icon(Icons.chat);
                int messages = value.getRoomsResponse.data.map((e) => e.unreadMessages).reduce((a, b) => a+b);
                return badges.Badge(
                  showBadge: messages > 0,
                  position: badges.BadgePosition.topEnd(top: -3, end: -3),
                  stackFit: StackFit.loose,
                  badgeStyle: badges.BadgeStyle(
                    padding: const EdgeInsets.all(3),
                    badgeColor: Theme.of(context).primaryColor,
                    elevation: 1,
                  ),
                  badgeContent: Text("$messages", style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold)),
                  child: const Icon(Icons.chat),
                );
              },
            ),
            title: "Talk",
          ),
        ),
        PersistentTabConfig(
          screen: const Breaker(breaker: BreakerArea.files, child: Files([])),
          item: ItemConfig(
              activeForegroundColor: Theme.of(context).primaryColor,
              inactiveForegroundColor: Theme.of(context).colorScheme.secondary,
              icon: const Icon(Icons.folder),
              title: "Dateien"
          ),
        ),
        PersistentTabConfig(
          screen: const Breaker(breaker: BreakerArea.more, child: Overhang()),
          item: ItemConfig(
              activeForegroundColor: Theme.of(context).primaryColor,
              inactiveForegroundColor: Theme.of(context).colorScheme.secondary,
              icon: const Icon(Icons.apps),
              title: "Mehr"
          ),
        ),
      ],
      navBarBuilder: (config) => Style6BottomNavBar(
        navBarConfig: config,
        navBarDecoration: NavBarDecoration(
          border: const Border(top: BorderSide(width: 1, color: Colors.grey)),
          color: Theme.of(context).colorScheme.surface,
        ),
      ),
    );
  }

  @override
  void dispose() {
    refetchChats.cancel();
    updateTimings.cancel();
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
}