import 'dart:convert';
import 'dart:io';
import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart';
import 'package:diplomaticquarterapp/pages/landing/landing_page.dart';
import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart';
import 'package:diplomaticquarterapp/uitl/app-permissions.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:huawei_push/huawei_push.dart' as h_push;
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_messaging/firebase_messaging.dart' as fir;
import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'app_shared_preferences.dart';
import 'navigation_service.dart';

// |--> Push Notification Background
Future<dynamic> backgroundMessageHandler(dynamic message) async {
  fir.RemoteMessage message_;
  if (message is h_push.RemoteMessage) {
    // if huawei remote message convert it to Firebase Remote Message
    message_ = toFirebaseRemoteMessage(message);
  }

  if (message.data != null && message.data['is_call'] == 'true') {
    _incomingCall(message.data);
    return;
  }
  h_push.Push.localNotification({h_push.HMSLocalNotificationAttr.TITLE: 'Background Message', h_push.HMSLocalNotificationAttr.MESSAGE: "By: BackgroundMessageHandler"});
}
// Push Notification Background <--|

RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message) {
  final payload_data = jsonDecode(message.data);
  final fire_message = RemoteMessage(
      from: message.from,
      collapseKey: message.collapseKey,
      data: payload_data['data'],
      messageId: message.messageId,
      sentTime: DateTime.fromMillisecondsSinceEpoch(message.sentTime * 1000),
      ttl: message.ttl,
      category: null,
      messageType: message.type,
      notification: RemoteNotification(
        title: message.notification.title,
        titleLocArgs: (message.notification.titleLocalizationArgs ?? []).map((e) => e.toString()).toList(),
        titleLocKey: message.notification.titleLocalizationKey,
        body: message.notification.body,
        bodyLocArgs: (message.notification.bodyLocalizationArgs ?? []).map((e) => e.toString()).toList(),
        bodyLocKey: message.notification.bodyLocalizationKey,
        android: AndroidNotification(
          channelId: message.notification.channelId,
          clickAction: message.notification.clickAction,
          color: message.notification.color,
          count: null,
          imageUrl: message.notification.imageUrl.path,
          link: message.notification.link.path,
          smallIcon: message.notification.icon,
          sound: message.notification.sound,
          ticker: message.notification.ticker,
          tag: message.notification.tag,
        ),
      ));
  return fire_message;
}

_incomingCall(Map data) async {
  LandingPage.incomingCallData = IncomingCallData.fromJson(data);
  if (LandingPage.isOpenCallPage == false) {
    LandingPage.isOpenCallPage = true;
    final permited = await AppPermission.askVideoCallPermission(currentContext);
    if (permited) await NavigationService.navigateToPage(IncomingCall(incomingCallData: LandingPage.incomingCallData));
    LandingPage.isOpenCallPage = false;
  }
  await Future.delayed(Duration(milliseconds: 500));
  await AppSharedPreferences().remove('call_data');
}

class PushNotificationHandler {
  final BuildContext context;
  static PushNotificationHandler _instance;

  PushNotificationHandler(this.context) {
    PushNotificationHandler._instance = this;
  }

  static PushNotificationHandler getInstance() => _instance;

  init() async {
    if (Platform.isIOS) {
      final permission = await FirebaseMessaging.instance.requestPermission();
      if (permission.authorizationStatus == AuthorizationStatus.denied) return;
    }

    if (Platform.isAndroid && (await FlutterHmsGmsAvailability.isHmsAvailable)) {
      // 'Android HMS' (Handle Huawei Push_Kit Streams)

      h_push.Push.enableLogger();
      final result = await h_push.Push.setAutoInitEnabled(true);

      h_push.Push.onNotificationOpenedApp.listen((message) {
        newMessage(toFirebaseRemoteMessage(message));
      }, onError: (e) => print(e.toString()));

      h_push.Push.onMessageReceivedStream.listen((message) {
        newMessage(toFirebaseRemoteMessage(message));
      }, onError: (e) => print(e.toString()));

      h_push.Push.getTokenStream.listen((token) {
        onToken(token);
      }, onError: (e) => print(e.toString()));
      await h_push.Push.getToken('');

      h_push.Push.registerBackgroundMessageHandler(backgroundMessageHandler);
    } else {
      // 'Android GMS or iOS' (Handle Firebase Messaging Streams)

      FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
        newMessage(message);
      });

      FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
        newMessage(message);
      });

      FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
        onToken(fcm_token);
      });

      FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);

      final fcmToken = await FirebaseMessaging.instance.getToken();
      if (fcmToken != null) onToken(fcmToken);
    }
  }

  newMessage(RemoteMessage remoteMessage) {
    if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) _incomingCall(remoteMessage.data);
  }

  onToken(String token) async {
    print("Push Notification Token: " + token);
    AppSharedPreferences().setString(PUSH_TOKEN, token);
    DEVICE_TOKEN = token;
  }

  onResume() async {
    var call_data = await AppSharedPreferences().getObject('call_data');
    if (call_data != null) {
      _incomingCall(call_data);
    }
  }
}

/* todo verify all functionality */
// _firebaseMessaging.configure(
//   // onMessage: (Map<String, dynamic> message) async {
//   //   // showDialog("onMessage: $message");
//   //   print("onMessage: $message");
//   //   print(message);
//   //   print(message['name']);
//   //   print(message['appointmentdate']);
//   //
//   //   if (Platform.isIOS) {
//   //     if (message['is_call'] == "true") {
//   //       var route = ModalRoute.of(context);
//   //
//   //       if (route != null) {
//   //         print(route.settings.name);
//   //       }
//   //s
//   //       Map<String, dynamic> myMap = new Map<String, dynamic>.from(mesage);
//   //       print(myMap);
//   //       LandingPage.isOpenCallPage = true;
//   //       LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
//   //       if (!isPageNavigated) {
//   //         isPageNavigated = true;
//   //         Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
//   //           isPageNavigated = false;
//   //         });
//   //       }
//   //     } else {
//   //       print("Is Call Not Found iOS");
//   //     }
//   //   } else {
//   //     print("Is Call Not Found iOS");
//   //   }
//   //
//   //   if (Platform.isAndroid) {
//   //     if (message['data'].containsKey("is_call")) {
//   //       var route = ModalRoute.of(context);
//   //
//   //       if (route != null) {
//   //         print(route.settings.name);
//   //       }
//   //
//   //       Map<String, dynamic> myMap = new Map<String, dynamic>.from(message['data']);
//   //       print(myMap);
//   //       if (LandingPage.isOpenCallPage) {
//   //         return;
//   //       }
//   //       LandingPage.isOpenCallPage = true;
//   //       LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
//   //       if (!isPageNavigated) {
//   //         isPageNavigated = true;
//   //         Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
//   //           Future.delayed(Duration(seconds: 5), () {
//   //             isPageNavigated = false;
//   //           });
//   //         });
//   //       }
//   //     } else {
//   //       print("Is Call Not Found Android");
//   //       LocalNotification.getInstance().showNow(title: message['notification']['title'], subtitle: message['notification']['body']);
//   //     }
//   //   } else {
//   //     print("Is Call Not Found Android");
//   //   }
//   // },
//   onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler,
//   onLaunch: (Map<String, dynamic> message) async {
//     print("onLaunch: $message");
//     // showDialog("onLaunch: $message");
//   },
//   onResume: (Map<String, dynamic> message) async {
//     print("onResume: $message");
//     print(message);
//     print(message['name']);
//     print(message['appointmentdate']);
//
//     // showDialog("onResume: $message");
//
//     if (Platform.isIOS) {
//       if (message['is_call'] == "true") {
//         var route = ModalRoute.of(context);
//
//         if (route != null) {
//           print(route.settings.name);
//         }
//
//         Map<String, dynamic> myMap = new Map<String, dynamic>.from(message);
//         print(myMap);
//         LandingPage.isOpenCallPage = true;
//         LandingPage.incomingCallData = IncomingCallData.fromJson(myMap);
//         if (!isPageNavigated) {
//           isPageNavigated = true;
//           Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) {
//             isPageNavigated = false;
//           });
//         }
//       } else {
//         print("Is Call Not Found iOS");
//       }
//     } else {
//       print("Is Call Not Found iOS");
//     }
//   },
// );
