 import 'dart:developer';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:sfm_app/firebase_options.dart';
import 'product/services/api_services.dart';
import 'product/services/notification_services.dart';
import 'product/services/theme_services.dart';
import 'product/services/language_services.dart';
import 'bloc/main_bloc.dart';
import 'product/base/bloc/base_bloc.dart';
import 'product/constant/navigation/navigation_router.dart';

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  await setupFlutterNotifications();
  showFlutterNotification(message);
  print('Handling a background message ${message.messageId}');
}


/// Create a [AndroidNotificationChannel] for heads up notifications
late AndroidNotificationChannel channel;

bool isFlutterLocalNotificationsInitialized = false;

Future<void> setupFlutterNotifications() async {
  if (isFlutterLocalNotificationsInitialized) {
    return;
  }
  channel = const AndroidNotificationChannel(
    'high_importance_channel', // id
    'High Importance Notifications', // title
    description:
        'This channel is used for important notifications.', // description
    importance: Importance.high,
  );

  flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

  /// Create an Android Notification Channel.
  ///
  /// We use this channel in the `AndroidManifest.xml` file to override the
  /// default FCM channel to enable heads up notifications.
  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
          AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);

  /// Update the iOS foreground notification presentation options to allow
  /// heads up notifications.
  await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
    alert: true,
    badge: true,
    sound: true,
  );
  isFlutterLocalNotificationsInitialized = true;
}

void showFlutterNotification(RemoteMessage message) {
  RemoteNotification? notification = message.notification;
  AndroidNotification? android = message.notification?.android;
  if (notification != null && android != null && !kIsWeb) {
    flutterLocalNotificationsPlugin.show(
      notification.hashCode,
      notification.title,
      notification.body,
      NotificationDetails(
        android: AndroidNotificationDetails(
          channel.id,
          channel.name,
          channelDescription: channel.description,
          // TODO add a proper drawable resource to android, for now using
          //      one that already exists in example app.
          icon: 'launch_background',
        ),
      ),
    );
  }
}

/// Initialize the [FlutterLocalNotificationsPlugin] package.
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  // Set the background messaging handler early on, as a named top-level function
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  if (!kIsWeb) {
    await setupFlutterNotifications();
  }

  runApp(
    BlocProvider(
      child: const MyApp(),
      blocBuilder: () => MainBloc(),
    ),
  );
}


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

  @override
  State<MyApp> createState() => _MyAppState();
  static void setLocale(BuildContext context, Locale newLocale) {
    _MyAppState? state = context.findAncestorStateOfType<_MyAppState>();
    state?.setLocale(newLocale);
  }

  static void setTheme(BuildContext context, ThemeData newTheme) {
    _MyAppState? state = context.findAncestorStateOfType<_MyAppState>();
    state?.setTheme(newTheme);
  }
}

class _MyAppState extends State<MyApp> {
  Locale? _locale;
  ThemeData? _themeData;
  late MainBloc mainBloc;
  LanguageServices languageServices = LanguageServices();
  ThemeServices themeServices = ThemeServices();
  // final NotificationServices notificationServices = NotificationServices();
  APIServices apiServices = APIServices();
  setLocale(Locale locale) {
    _locale = locale;
    mainBloc.sinkLanguage.add(_locale);
  }

  setTheme(ThemeData theme) {
    _themeData = theme;
    mainBloc.sinkTheme.add(_themeData);
  }
  
  @override
  void initState() {
    super.initState();
    mainBloc = BlocProvider.of(context);
    // // notificationServices.initLocalNotifications();
    // // notificationServices.firebaseInit(context);
    // // notificationServices.setupInteractMessage();
    // notificationServices.getDeviceToken().then((token){
    //   print("Firebase Token: $token");
    //   sendNotificationToken(token);
    // });
  }

  // void sendNotificationToken (String token) async {
  //   int statusCode = await apiServices.sendNotificationToken(token);
  //   log("Notification Send StatusCode : $statusCode");
  // }

  @override
  void didChangeDependencies() {
    languageServices.getLocale().then((locale) => {setLocale(locale)});
    themeServices.getTheme().then((theme) => {setTheme(theme)});
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    final router = goRouter();
    return StreamBuilder<Locale?>(
      stream: mainBloc.streamLanguage,
      initialData: _locale,
      builder: (context, languageSnapshot) {
        return StreamBuilder<ThemeData?>(
          stream: mainBloc.streamTheme,
          initialData: _themeData,
          builder: (context, themeSnapshot) {
            return MaterialApp.router(
              theme: themeSnapshot.data,
              routerConfig: router,
              debugShowCheckedModeBanner: false,
              localizationsDelegates: AppLocalizations.localizationsDelegates,
              supportedLocales: AppLocalizations.supportedLocales,
              locale: languageSnapshot.data,
            );
          }
        );
      },
    );
  }
}
