// ignore_for_file: deprecated_member_use

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

import 'package:bot_toast/bot_toast.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/firebase_options.dart';
import 'package:didvan/models/notification_message.dart';
import 'package:didvan/models/requests/news.dart';
import 'package:didvan/models/requests/radar.dart';
import 'package:didvan/providers/media.dart';
import 'package:didvan/providers/theme.dart';
import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/route_generator.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/app_home_widget/home_widget_repository.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/notification/firebase_api.dart';
import 'package:didvan/services/notification/notification_service.dart';
import 'package:didvan/utils/my_custom_scroll_behavior.dart';
import 'package:didvan/views/ai/ai_chat_state.dart';
import 'package:didvan/views/ai/ai_state.dart';
import 'package:didvan/views/ai/bot_assistants_state.dart';
import 'package:didvan/views/ai/history_ai_chat_state.dart';
import 'package:didvan/views/podcasts/podcasts_state.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart';
import 'package:home_widget/home_widget.dart';
import 'package:provider/provider.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:app_links/app_links.dart';

import 'services/network/request.dart';

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
Uri? initialURI;

@pragma('vm:entry-point')
Future<void> _backgroundCallbackHomeWidget(Uri? uri) async {
  if (uri != null) {
    await HomeWidget.saveWidgetData("uri", uri.host);
  }
}

void main() async {
  runZonedGuarded(
    () async {
      WidgetsFlutterBinding.ensureInitialized();
      try {
        if (!kIsWeb) {
          HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget);
          HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget);
          await NotificationService.initializeNotification();
          try {
            if (Platform.isAndroid) {
              await FlutterDownloader.initialize(debug: true, ignoreSsl: true);
            }
          } catch (e) {
            e.printError();
          }
        }

        await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
        await FirebaseApi().initNotification();
      } catch (e) {
        debugPrint(e.toString());
      }

      await SentryFlutter.init(
        (options) {
          options.dsn = 'https://a4cfcaa7d67471240d295c25c968d91d@o4508585857384448.ingest.de.sentry.io/4508585886548048';
          options.tracesSampleRate = 1.0;
          options.profilesSampleRate = 1.0;
        },
        appRunner: () => runApp(const Didvan()),
      );
    },
    (error, stack) {
      Sentry.captureException(error, stackTrace: stack);
    },
  );
}

class Didvan extends StatefulWidget {
  const Didvan({Key? key}) : super(key: key);

  @override
  State<Didvan> createState() => _DidvanState();
}

class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
  late AppLinks _appLinks;
  StreamSubscription<Uri>? _linkSubscription;

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

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _linkSubscription?.cancel();
    if (MediaService.currentPodcast != null) {
      MediaService.audioPlayer.dispose();
    }
    super.dispose();
  }

  Future<void> _initDeepLinks() async {
    _appLinks = AppLinks();
    initialURI = await _appLinks.getInitialLink();
    _linkSubscription = _appLinks.uriLinkStream.listen((uri) {
      _navigateTo(uri);
    });
  }

  void _navigateTo(Uri uri) {
    if (mounted) {
      String path = uri.path;
      final Map<String, String> params = uri.queryParameters;

      final String? token = params['token'];

      if (token != null) {
        //todo: this didnt work
        print("DEBUG: received token in url, token: $token, path: $path");
        RequestService.token = token;
      }

      if (path.startsWith('/news/')) {
        final id = path.split('/news/').last;
        if (id.isNotEmpty) {
          navigatorKey.currentState?.pushNamed(
            Routes.newsDetails,
            arguments: {'id': int.parse(id), 'args': const NewsRequestArgs(page: 0)},
          );
        }
      } else if (path.startsWith('/radar/')) {
        final id = path.split('/radar/').last;
        if (id.isNotEmpty) {
          navigatorKey.currentState?.pushNamed(
            Routes.radarDetails,
            arguments: {'id': int.parse(id), 'args': const RadarRequestArgs(page: 0)},
          );
        }
      }
    }
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) async {
    if (!kIsWeb) {
      if (state == AppLifecycleState.resumed) {
        var r = await HomeWidget.getWidgetData("cRoute", defaultValue: '');
        if (r.toString() != Routes.splash) {
          await HomeWidgetRepository.decideWhereToGo();
          NotificationMessage? data = HomeWidgetRepository.data;
          if (data != null) {
            await HomeWidgetRepository.decideWhereToGoNotif();
          }
        }
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<PodcastsState>(create: (context) => PodcastsState()),
        ChangeNotifierProvider<MediaProvider>(create: (context) => MediaProvider()),
        ChangeNotifierProvider<UserProvider>(create: (context) => UserProvider()),
        ChangeNotifierProvider<ThemeProvider>(create: (context) => ThemeProvider()),
        ChangeNotifierProvider<StudioDetailsState>(create: (context) => StudioDetailsState()),
        ChangeNotifierProvider<HistoryAiChatState>(create: (context) => HistoryAiChatState()),
        ChangeNotifierProvider<AiState>(create: (context) => AiState()),
        ChangeNotifierProvider<AiChatState>(create: (context) => AiChatState()),
        ChangeNotifierProvider<BotAssistantsState>(create: (context) => BotAssistantsState()),
      ],
      child: Consumer<ThemeProvider>(
        builder: (context, themeProvider, child) => Container(
          color: Theme.of(context).colorScheme.surface,
          child: SafeArea(
            child: MaterialApp(
              scrollBehavior: MyCustomScrollBehavior(),
              navigatorKey: navigatorKey,
              debugShowCheckedModeBanner: false,
              title: 'Didvan',
              theme: LightThemeConfig.themeData.copyWith(
                  bottomSheetTheme: const BottomSheetThemeData(
                      surfaceTintColor: Colors.transparent,
                      backgroundColor: Colors.transparent),
                  textTheme: LightThemeConfig.themeData.textTheme.apply(
                    fontFamily: themeProvider.fontFamily,
                  )),
              darkTheme: DarkThemeConfig.themeData.copyWith(
                  bottomSheetTheme: const BottomSheetThemeData(
                      surfaceTintColor: Colors.transparent,
                      backgroundColor: Colors.transparent),
                  textTheme: DarkThemeConfig.themeData.textTheme.apply(
                    fontFamily: themeProvider.fontFamily,
                  )),
              color: LightThemeConfig.themeData.primaryColor,
              themeMode: themeProvider.themeMode,
              onGenerateRoute: (settings) =>
                  RouteGenerator.generateRoute(settings),
              builder: BotToastInit(),
              navigatorObservers: [BotToastNavigatorObserver()],
              initialRoute: "/",
              localizationsDelegates: const [
                GlobalCupertinoLocalizations.delegate,
                GlobalMaterialLocalizations.delegate,
                GlobalWidgetsLocalizations.delegate,
              ],
              supportedLocales: const [
                Locale("fa", "IR"),
              ],
              locale: const Locale("fa", "IR"),
            ),
          ),
        ),
      ),
    );
  }
}