import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:road24_mobile/utils/check_internet.dart';
import 'package:road24_mobile/data/repository/DevicesRepository.dart';
import 'package:road24_mobile/data/shared_data.dart';
import 'package:road24_mobile/model/blocs/notifications/notifications_bloc.dart';
import 'package:road24_mobile/utils/frequent_widgets.dart';
import 'package:road24_mobile/view/home/dash_board.dart';
import 'package:road24_mobile/view/notifications/notification_page.dart';
import 'package:road24_mobile/view/settings/rocket_chat.dart';
import 'package:road24_mobile/view/widgets/custom_bottom_tabbar.dart';
import 'package:road24_mobile/view/widgets/fade_route.dart';
import 'package:url_launcher/url_launcher.dart';
import '../my_app.dart';

class FirebaseNotifications {
  static late FirebaseMessaging firebaseMessaging;
  String _channelId = 'Road24';
  String _channelTitle = 'Road24 Channel';
  String _channelDescription = 'Channel for receiving notifications';

  static signOutFromNotifications() async {
    try {
      await DeviceRepository().deactivateDevice(
          registeredId: MyApp.preferences?.getMessagingToken() ?? "");
    } catch (ex) {
      print("error in deactivate device...$ex");
    }
    await MyApp.preferences?.setMessagingToken(null);

    await MyApp.preferences?.setRegisteredDevice(false);

    await MyApp.preferences?.setToken(null);

    await MyApp.preferences?.setRefreshToken("");

    // await MyApp.preferences?.setUserLocation(null);
  }

  Future<void> setUpFirebase(BuildContext context) async {
    firebaseMessaging = FirebaseMessaging.instance;

    firebaseMessaging.setAutoInitEnabled(true);

    print('FIREBASE SETUP There');

    if (MyApp.preferences == null) {
      MyApp.preferences = await Preferences.getInstance();
    }
    await requestNotificationPermission();

    if (MyApp.preferences?.getMessagingToken() == null ||
        MyApp.preferences?.getMessagingToken() == "") {
      print("A TOKEN");

      firebaseCloudMessagingListeners();
    } else {
      print("B firebase token");
      print(MyApp.preferences?.getMessagingToken());

      onMessageFunc();
    }
  }

  static bool isCalled = false;
  onMessageFunc() {
    if (!isCalled) {
      isCalled = true;
      FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
        RemoteNotification? notification = message.notification;
        print("message coming.....$notification");

        print(message.data["android_url"]);
        print(message.data["ios_url"]);
        if (notification != null) {
          await _showNotification(
            notification.hashCode, notification.title,
            notification.body, message,
            // isChat: isChat
          );
        }
      });

      FirebaseMessaging.instance
          .getInitialMessage()
          .then((RemoteMessage? message) {
        print("message coming 2.....");

        if (message != null) {
          if (message.data["screen"] != null &&
              message.data["screen"] == "chat") {
            DashBoard.activeTab.value = CustomBottomTabBar.indexMap['Settings'];

            Navigator.push(MyApp.navigatorKey.currentContext!,
                MaterialPageRoute(builder: (_) {
              return SupportChatPage(
                isChat: true,
              );
            }));
          }
          if (message.data["android_url"] != null) {
            var url = message.data["android_url"];
            if (Platform.isIOS) {
              url = message.data["ios_url"];
            }
            launch(url);
          }
        }
      });

      FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
        print("message coming 3.....");

        print(message.data["android_url"]);
        print(message.data["ios_url"]);

        if (message.data["screen"] != null &&
            message.data["screen"] == "chat") {
          DashBoard.activeTab.value = CustomBottomTabBar.indexMap['Settings'];

          Navigator.push(MyApp.navigatorKey.currentContext!,
              MaterialPageRoute(builder: (_) {
            return SupportChatPage(
              isChat: true,
            );
          }));
        } else {
          if (message.data["android_url"] != null) {
            var url = message.data["android_url"];
            if (Platform.isIOS) {
              url = message.data["ios_url"];
            }
            launch(url);
          }
          DashBoard.notificationsBloc.add(GetUnreadNotificationsCountEvent());
        }
      });
    }
  }

  Future<void> _showNotification(
    int notificationId,
    String? notificationTitle,
    String? notificationContent,
    RemoteMessage message,
  ) async {
    var isSoundAvailable = message.data["action"] == "new_fine";

    var isChat = message.data["screen"] == "chat";

    var iosChannelDetails = IOSNotificationDetails(
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
    );

    var androidChannelDetails = AndroidNotificationDetails(
        _channelId, _channelTitle, _channelDescription,
        playSound: true,
        importance: Importance.max,
        priority: Priority.high,
        enableLights: true,
        enableVibration: true);

    var platformChannelSpecifics = new NotificationDetails(
        android: androidChannelDetails, iOS: iosChannelDetails);

    var iosChannelDetailsForFine = IOSNotificationDetails(
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
      sound: "police_siren.caf",
    );
    var androidChannelDetailsForFine = AndroidNotificationDetails(
        "Road24 Fines", "Road24 Fines", "For New Fines with sound",
        playSound: true,
        importance: Importance.max,
        priority: Priority.high,
        enableLights: true,
        sound: RawResourceAndroidNotificationSound("police_siren"),
        enableVibration: true);

    var platformChannelForFine = NotificationDetails(
        android: androidChannelDetailsForFine, iOS: iosChannelDetailsForFine);

    var iosChannelDetailsForChatting = IOSNotificationDetails(
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
    );
    var androidChannelDetailsForChatting = AndroidNotificationDetails(
        "Road24 Chat", "Road24 Chat", "For Tech Support Chat",
        playSound: true,
        importance: Importance.max,
        priority: Priority.high,
        enableLights: true,
        enableVibration: true);

    var platformChannelForChatting = NotificationDetails(
        android: androidChannelDetailsForChatting,
        iOS: iosChannelDetailsForChatting);

    var notificationDetails =
        isSoundAvailable ? platformChannelForFine : platformChannelSpecifics;

    if (isChat) {
      notificationDetails = platformChannelForChatting;
    }

    await MyApp.flutterLocalNotificationsPlugin.show(
      notificationId,
      notificationTitle,
      notificationContent,
      notificationDetails,
      payload: getPayload(message.data),
      // payload: message.data["screen"],
    );
  }

  Future<void> firebaseCloudMessagingListeners({bool isChat = false}) async {
    if (!await CheckInternet.isInternet()) {
      MyApp.hasInternet.value = false;
    } else {
      MyApp.hasInternet.value = true;
    }
    try {
      var token = await FirebaseMessaging.instance.getToken();

      if (token != null) {
        if (isChat) {
          await MyApp.preferences?.setChatToken(token);
        } else {
          await MyApp.preferences?.setMessagingToken(token);

          await registerDevice(token);
        }
      }
      print("messaging token...$token");

      onMessageFunc();
    } catch (e) {
      print("messagin token exception.....$e");
      MyApp.hasInternet.value = false;
      Fluttertoast.showToast(
        msg: "${e.toString()}",
        toastLength: Toast.LENGTH_LONG,
        // timeInSecForIosWeb: msg.length ~/ 15,
      );
    }
  }

  registerDevice(String token) async {
    var deviceId = MyApp.preferences?.getDeviceId();

    if (deviceId == null) deviceId = await FrequentWidgets.getDeviceId();

    DeviceRepository()
        .registerDevice(
            deviceId: deviceId,
            deviceType:
                (Platform.isAndroid) ? DeviceType.ANDROID : DeviceType.IOS,
            registrationId: token,
            active: true)
        .then((value) {
      MyApp.preferences?.setRegisteredDevice(true);
    });
  }

  static Future<void> requestNotificationPermission() async {
    final initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');

    final initializationSettingsIOS = IOSInitializationSettings();

    final initSettings = InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );

    await MyApp.flutterLocalNotificationsPlugin.initialize(
      initSettings,
      onSelectNotification: onSelectNotification,
    );
  }

  static Future<dynamic> onDidReceiveLocalNotification(
      int id, String? title, String? body, String? payload) async {}

  getPayload(Map<String, dynamic> messageData) {
    if (messageData.containsKey("android_url")) {
      var storeUrl = messageData["android_url"];

      if (Platform.isIOS) {
        storeUrl = messageData["ios_url"];
      }

      return "stores_$storeUrl";
    } else
      return messageData["screen"];
  }

  static Future onSelectNotification(String? payload) async {
    if (payload != null) {
      if (payload == "chat") {
        DashBoard.activeTab.value = CustomBottomTabBar.indexMap['Settings'];

        Navigator.push(MyApp.navigatorKey.currentContext!,
            MaterialPageRoute(builder: (_) {
          return SupportChatPage(
            isChat: true,
          );
        }));
      } else {
        // DashBoard.activeTab.value =
        //     CustomBottomTabBar.indexMap['NotificationPage'];

        if (payload.startsWith("stores_")) {
          var storeUrl = payload.split("_")[1];

          await launch(storeUrl);
        }
        DashBoard.activeTab.value = CustomBottomTabBar.indexMap['MyAvto'];

        DashBoard.notificationsBloc.add(GetUnreadNotificationsCountEvent());

        await Navigator.push(MyApp.navigatorKey.currentContext!,
            FadeRoute(page: NotificationScreen()));
      }
    }
  }
}
