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

import 'package:app_links/app_links.dart';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:hub/backend/notifications/notification_service.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/flutter_flow/nav/nav.dart';
import 'package:hub/pages/forgot_password_page/forgot_password_screen.dart';
import 'package:hub/shared/helpers/shared_preferences_storage_helper.dart';
import 'package:hub/shared/services/localization/localization_service.dart';
import 'package:hub/shared/utils/device_util.dart';
import 'package:hub/shared/utils/storage_util.dart';
import 'package:responsive_framework/responsive_framework.dart';

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

void main() async {
  await initializeApp();
  runApp(const App());
  FirebaseMessaging.onBackgroundMessage(_backgroundHandlerMessage);
}

Future<void> initializeApp() async {
  WidgetsFlutterBinding.ensureInitialized();
  await _initializeTracking();
  await _initializeStorageHelpers();

  await _initializeFirebase();
  await _initializeNotificationService();
  _initializeUrlStrategy();
  _initializeSystemSettings();
  await _initializeFlutterFlow();
}

Future<void> _initializeStorageHelpers() async {
  log('Initializing SharedPreferencesStorageHelper');
  await SharedPreferencesStorageHelper().initialize();
  log('Initializing SharedPreferencesStorageHelper');
  await StorageUtil().ensureInitialization();
}

Future<void> _initializeTracking() async {
  await AppTrackingTransparency.requestTrackingAuthorization();
}

Future<void> _initializeFirebase() async {
  await Firebase.initializeApp();
}

Future<void> _initializeNotificationService() async {
  await NotificationService.initialize();
}

void _initializeUrlStrategy() {
  setUrlStrategy(PathUrlStrategy());
}

void _initializeSystemSettings() {
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  if (kDebugMode) {
    log("Aplicativo em Debug Mode, crashlytics desabilitado!");
  } else {
    final crashlyticsInstance = FirebaseCrashlytics.instance;
    if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
      FlutterError.onError = crashlyticsInstance.recordFlutterError;
    }
  }
}

Future<void> _initializeFlutterFlow() async {
  await FlutterFlowTheme.initialize();
  await FFLocalizations.initialize();
  GoRouter.optionURLReflectsImperativeAPIs = true;
  usePathUrlStrategy();
}

Future<void> _foregroundHandlerMessage(RemoteMessage message) async {
  if (message.data['click_action'] == 'enroll_cond') {
    StorageUtil().haveLocal = true;
    StorageUtil().context?.go('/homePage');
  }
  if (!Platform.isIOS) {
    NotificationService.show(
        title: message.notification!.title!,
        body: message.notification!.body!,
        payload: Map<String, String>.from(message.data));
  }
}

Future<void> _backgroundHandlerMessage(RemoteMessage message) async {
  if (message.data['click_action'] == 'enroll_cond') {
    log('backgroundHandlerMessage');
    StorageUtil().haveLocal = true;
    StorageUtil().context?.go('/homePage');
  }
}

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

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

  static _AppState of(BuildContext context) =>
      context.findAncestorStateOfType<_AppState>()!;
}

class _AppState extends State<App>  with WidgetsBindingObserver {
  Locale? _locale = FFLocalizations.getStoredLocale();
  ThemeMode _themeMode = FlutterFlowTheme.themeMode;
  late AppStateNotifier _appStateNotifier;
  late GoRouter _router;
  bool displaySplashImage = true;
  late AppLinks _appLinks;
  StreamSubscription<Uri>? _linkSubscription;

  final ThemeData _darkTheme = ThemeData(
    brightness: Brightness.dark,
    scrollbarTheme: ScrollbarThemeData(
      thumbVisibility: WidgetStateProperty.all(false),
      interactive: false,
      thumbColor: WidgetStateProperty.resolveWith((states) {
        if (states.contains(WidgetState.dragged)) {
          return const Color(0xff1aab5f);
        }
        if (states.contains(WidgetState.hovered)) {
          return const Color(0xff1aab5f);
        }
        return const Color(0xff1aab5f);
      }),
    ),
  );
  final ThemeData _theme = ThemeData(
    brightness: Brightness.light,
    scrollbarTheme: ScrollbarThemeData(
      thumbVisibility: WidgetStateProperty.all(false),
      interactive: false,
      thumbColor: WidgetStateProperty.resolveWith((states) {
        if (states.contains(WidgetState.dragged)) {
          return const Color(0xff1aab5f);
        }
        if (states.contains(WidgetState.hovered)) {
          return const Color(0xff1aab5f);
        }
        return const Color(0xff1aab5f);
      }),
    ),
  );
  final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates =
      const [
    FFLocalizationsDelegate(),
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ];
  final Iterable<Locale> supportedLocales = const [
    Locale('pt'),
    Locale('en'),
  ];
  Widget Function(BuildContext, Widget?)? builder = (context, widget) {
    const String HD4K = '4K';
    const String ULTRAWIDE = 'ULTRAWIDE';

    final breakpoints = [
      const Breakpoint(start: 0, end: 450, name: MOBILE),
      const Breakpoint(start: 451, end: 800, name: TABLET),
      const Breakpoint(start: 801, end: 1920, name: DESKTOP),
      const Breakpoint(start: 1921, end: 2560, name: HD4K),
      const Breakpoint(start: 2561, end: double.infinity, name: ULTRAWIDE),
    ];
    return ResponsiveBreakpoints.builder(
      child: BouncingScrollWrapper.builder(context, widget!),
      breakpoints: breakpoints,
    );
  };

  Future<void> initDeepLinks() async {
    _appLinks = AppLinks();
    _linkSubscription = _appLinks.uriLinkStream.listen((uri) {
      final bool isRecovered = StorageUtil().isRecovered;
      if (!isRecovered) openAppLink(uri);
    });
  }

  void openAppLink(Uri uri) {
    final bool isRecovered = StorageUtil().isRecovered;
    log('isRecovered: $isRecovered');
    if (isRecovered) return;
    StorageUtil().isRecovered = true;
    final String email = uri.queryParameters['email'] ?? '';
    final String token = uri.queryParameters['token'] ?? '';
    final bool isNotEmpty = email.isNotEmpty && token.isNotEmpty;
    if (isNotEmpty) {
      final BuildContext context = StorageUtil().context!;
      final MediaQueryData mediaQuery = MediaQuery.of(context);
      final double height = mediaQuery.size.height * 0.6;
      final FlutterFlowTheme theme = FlutterFlowTheme.of(context);
      final Widget screen = ForgotPasswordScreen(email: email, token: token);
      builder(context) => screen;
      showModalBottomSheet(
        context: context,
        builder: (context) => Padding(
            padding: MediaQuery.viewInsetsOf(context), child: builder(context)),
        isScrollControlled: true,
        // barrierColor: theme.primaryBackground.withOpacity(0.2),
        backgroundColor: theme.primaryBackground,
        showDragHandle: true,
        useSafeArea: true,
        enableDrag: true,
        // isDismissible: true,
      ).whenComplete(() => StorageUtil().isRecovered = false);
    }
  }

  void _setupFirebaseMessaging() async {
    FirebaseMessaging messaging = FirebaseMessaging.instance;
    RemoteMessage? initialMessage = await messaging.getInitialMessage();
    if (initialMessage != null) {
      log('initialMessage');
      _backgroundHandlerMessage(initialMessage);
    }

    FirebaseMessaging.onMessage.listen(_foregroundHandlerMessage);
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      if (message.data['click_action'] == 'enroll_cond') {
        StorageUtil().haveLocal = true;
        log('onMessageOpenedApp');
      } else {
        onMessageReceived(message.data, message.notification!.body,
            message.data['click_action']);
      }
    });
    FirebaseMessaging.instance.getInitialMessage().then((message) {
      if (message != null) {
        if (message.data['click_action'] == 'enroll_cond') {
          StorageUtil().haveLocal = true;
          log('getInitialMessage');
        }
      }
    });
  }

  void setLocale(String language) {
    setState(() => _locale = createLocale(language));
    FFLocalizations.storeLocale(language);
  }

  void setThemeMode(ThemeMode mode) {
    setState(() {
      _themeMode = mode;
      FlutterFlowTheme.saveThemeMode(mode);
    });
  }

  @override void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);

    log('DeviceUtil: ${DeviceUtil.getDeviceOSVersion()}');

    FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
    _appStateNotifier = AppStateNotifier.instance;
    _router = createRouter(_appStateNotifier);
    Future.delayed(const Duration(milliseconds: 1000),
        () => setState(() => _appStateNotifier.stopShowingSplashImage()));

    _setupFirebaseMessaging();
    WidgetsBinding.instance.addPersistentFrameCallback((_) => initDeepLinks());
  }

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

  @override void didChangeAppLifecycleState(AppLifecycleState state) async {
    bool initialize = await StorageUtil().ensureInitialization();
    if(initialize) await LocalizationService.processLocals(context);
  }

  @override Widget build(BuildContext context) {
    return MaterialApp.router(
      key: navigatorKey,
      title: 'FRE ACCESS HUB',
      builder: builder,
      localizationsDelegates: localizationsDelegates,
      locale: _locale,
      supportedLocales: supportedLocales,
      theme: _theme,
      darkTheme: _darkTheme,
      themeMode: _themeMode,
      routerConfig: _router,
    );
  }
}
