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

import 'package:device_info_plus/device_info_plus.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart' as fir;
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart';

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:hmg_patient_app_new/core/utils/local_notifications.dart';
import 'package:hmg_patient_app_new/core/utils/utils.dart';
import 'package:permission_handler/permission_handler.dart';

import '../cache_consts.dart';

// |--> Push Notification Background
@pragma('vm:entry-point')
Future<dynamic> backgroundMessageHandler(dynamic message) async {
  print("Firebase backgroundMessageHandler!!!");
  await Firebase.initializeApp();
  fir.RemoteMessage message_;

  if (message.data != null && (message.data['is_call'] == 'true' || message.data['is_call'] == true)) {
    // showCallkitIncoming(message);
    _incomingCall(message.data);
    return;
  } else {}
}

callPage(String sessionID, String token) async {}

_incomingCall(Map<String, dynamic> data) async {
  // LandingPage.incomingCallData = IncomingCallData.fromJson(data);
  // var dataItem = await AppSharedPreferences().getObject('call_data');
  // if(dataItem != null ) return; // to stop repeated attempt to invoke the call
  // if (LandingPage.isOpenCallPage == false) {
  //   LandingPage.isOpenCallPage = true;
  WidgetsFlutterBinding.ensureInitialized();
  // var _currentUuid = Uuid().v4();
  // await FlutterCallkitIncoming.showCallkitIncoming(callKitParams);
  // }
  // LandingPage.isOpenCallPage = false;
  await Future.delayed(Duration(milliseconds: 500));
}

Future<void> openCallPage(BuildContext context) async {
  try {
    // if (incomingCallData!.background == "0") {
    // Zoom Call Page
    // Navigator.of(context).pop();
    Navigator.pushReplacementNamed(
      context,
      "zoom_call_page",
      // arguments: CallArguments(incomingCallData!.sessionId!, "123", "Patient", "40", "0", false, int.parse(incomingCallData!.appointmentNo!)),
    );
    // } else {
    //   // OpenTok Call Page
    //   await Navigator.of(context).pushReplacement(
    //     MaterialPageRoute(
    //       // fullscreenDialog: true,
    //       builder: (BuildContext context) {
    //         // final caller = widget.incomingCallData.callerID;
    //         // final receiver = widget.incomingCallData.receiverID;
    //         // final host = widget.incomingCallData.server;
    //         // if(widget.incomingCallData.isWebRTC == "true"){
    //         //   return StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host);
    //         // }else{
    //         return OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: incomingCallData!.sessionId!, token: incomingCallData!.token!);
    //       },
    //     ),
    //   );
    // }
  } catch (err) {
    print(err);
    // await PlatformExceptionAlertDialog(
    //   exception: Exception(err),
    // ).show(context);
  }
}

// Future<void> showCallkitIncoming(Map message) async {
//   // if (message['type'] == 'ReservationCallStart') {
//     var params = CallKitParams(
//         id: DateTime.now().millisecondsSinceEpoch.toString(),
//         nameCaller: 'Dr Sulaiman Al Habib',
//         appName: 'Dr Sulaiman Al Habib',
//         avatar: 'https://play-lh.googleusercontent.com/FBNNpxb7m6eM6wtW7MV1Ffp6OXOGLI38q47zcvP29OCYA1yhYH5mZzl5itZi0TgOyZpG',
//         handle: 'LiveCare Call',
//         type: 1,
//         duration: 60000,
//         textAccept: 'Accept',
//         textDecline: 'Decline',
//         textMissedCall: 'Missed call',
//         textCallback: 'Call back',
//         extra: <String, dynamic>{
//           // 'reservationID': message['id'],
//           'userId': '1a2b3c4d'
//         },
//         headers: <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
//         android: AndroidParams(
//           isCustomNotification: true,
//           isShowLogo: false,
//           isShowCallback: false,
//           ringtonePath: 'system_ringtone_default',
//           backgroundColor: '#424242FF',
//           // 'backgroundUrl': 'https://i.pravatar.cc/500',
//           actionColor: '#4CAF50',
//           incomingCallNotificationChannelName: "Incoming Call",
//           missedCallNotificationChannelName: "Missed Call",
//         ),
//         ios: IOSParams(
//             iconName: 'CallKitLogo',
//             handleType: '',
//             supportsVideo: true,
//             maximumCallGroups: 2,
//             maximumCallsPerCallGroup: 1,
//             audioSessionMode: 'default',
//             audioSessionActive: true,
//             audioSessionPreferredSampleRate: 44100.0,
//             audioSessionPreferredIOBufferDuration: 0.005,
//             supportsDTMF: true,
//             supportsHolding: true,
//             supportsGrouping: false,
//             supportsUngrouping: false,
//             ringtonePath: 'system_ringtone_default'));
//     await FlutterCallkitIncoming.showCallkitIncoming(params);
//   // } else if (message['type'] == 'ReservationCallFinished') {
//   //   await FlutterCallkitIncoming.endAllCalls();
//   // }
// }

class PushNotificationHandler {
  late BuildContext context;
  static final PushNotificationHandler _instance = PushNotificationHandler._internal();

  // late HmsApiAvailability hmsApiAvailability;

  // final voIPKit = FlutterIOSVoIPKit.instance;

  late Timer timeOutTimer;
  bool isTalking = false;

  var data = {
    "AppointmentNo": "2016059247",
    "ProjectID": "15",
    "NotificationType": "10",
    "background": "0",
    "doctorname": "Call from postman",
    "clinicname": "LIVECARE FAMILY MEDICINE AND GP",
    "speciality": "General Practioner",
    "appointmentdate": "2022-01-19",
    "appointmenttime": "12:10",
    "PatientName": "Testing",
    "session_id": "1_MX40NjIwOTk2Mn5-MTY1NDE2NDQxMjc2Mn5xc3NCZkNIejJOdzgzTkg2TmlXblhQdnl-fg",
    "token":
        "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9MTliNTA3NDAxYmU0MjI5OGY5NTcxZTdhNzQyMTcyZjRjMjBhNjljZTpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTFOREUyTkRReE1qYzJNbjV4YzNOQ1prTkllakpPZHpnelRrZzJUbWxYYmxoUWRubC1mZyZjcmVhdGVfdGltZT0xNjU0MTY0NDEzJm5vbmNlPTAuNjM3ODkzNDk4NDQ2NTIxOSZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjU0MjUwODEzJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9",
    "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg",
    "callerID": "9920",
    "PatientID": "1231755",
    "is_call": "true"
  };

  PushNotificationHandler._internal();

  factory PushNotificationHandler() => _instance;

  static PushNotificationHandler getInstance() => _instance;

  // void _timeOut({
  //   int seconds = 30,
  // }) async {
  //   timeOutTimer = Timer(Duration(seconds: seconds), () async {
  //     print('🎈 example: timeOut');
  //     final incomingCallerName = await voIPKit.getIncomingCallerName();
  //     voIPKit.unansweredIncomingCall(
  //       skipLocalNotification: false,
  //       missedCallTitle: '📞 Missed call',
  //       missedCallBody: 'There was a call from $incomingCallerName',
  //     );
  //   });
  // }

  init(BuildContext context) async {
    this.context = context;

    if (Platform.isIOS) {
      // voIPKit.getVoIPToken().then((value) {
      //   print("APNS VOIP KIT TOKEN: $value");
      //   AppSharedPreferences().setString(APNS_TOKEN, value!);
      // });
      //
      // voIPKit.onDidUpdatePushToken = (String token) {
      //   print('🎈 example: onDidUpdatePushToken: $token');
      // };
      //
      // voIPKit.onDidReceiveIncomingPush = (
      //   Map<String, dynamic> payload,
      // ) async {
      //   print('🎈 example: onDidReceiveIncomingPush $payload');
      //   _timeOut();
      // };
      //
      // voIPKit.onDidRejectIncomingCall = (
      //   String uuid,
      //   String callerId,
      // ) async {
      //   try {
      //     print('🎈 example: onDidRejectIncomingCall $uuid - $callerId');
      //     timeOutTimer.cancel();
      //   } catch (err) {}
      // };
      //
      // voIPKit.onDidAcceptIncomingCall = (
      //   String uuid,
      //   String callerId,
      // ) async {
      //   print('🎈 example: onDidAcceptIncomingCall $uuid - $callerId');
      //   await voIPKit.acceptIncomingCall(callerState: CallStateType.calling);
      //   await voIPKit.callConnected();
      //   await Future.delayed(Duration(seconds: 1));
      //
      //   Navigator.pushNamed(
      //     locator<NavigationService>().navigatorKey.currentContext!,
      //     "zoom_call_page",
      //     arguments: CallArguments("hoover-dam", "123", "Patient", "40", "1", false),
      //   );
      //
      //   await voIPKit.endCall();
      //
      //   // Navigator.pushNamed(navigatorKey.currentContext!, VIDEO_CALL_SCREEN,
      //   //     arguments: VideoArgus(
      //   //         reservationId: int.parse(callerId), token: null, isVideo: true));
      //
      //   timeOutTimer.cancel();
      // };
    }

    if (Platform.isAndroid) {
      try {
        final fcmToken = await FirebaseMessaging.instance.getToken().catchError((err) {
          print(err);
        });
        if (fcmToken != null) onToken(fcmToken);
        // }
      } catch (ex) {
        print("Notification Exception: " + ex.toString());
      }
      FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler);
    }

    if (Platform.isIOS) {
      final permission = await FirebaseMessaging.instance.requestPermission();
      await FirebaseMessaging.instance.getAPNSToken().then((value) async {
        log("APNS token: " + value.toString());
        await Utils.saveStringFromPrefs(CacheConst.apnsToken, value.toString());
      });
      await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
        alert: true, // Required to display a heads up notification
        badge: true,
        sound: true,
      );
      if (permission.authorizationStatus == AuthorizationStatus.denied) return;
    } else {}

    try {
      FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) async {
        if (message != null) {
          if (Platform.isIOS) {
            await Future.delayed(Duration(milliseconds: 3000)).then((value) {
              if (message != null) newMessage(message);
            });
          } else if (message != null) newMessage(message);
        }
      });
    } catch (ex) {}

    FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
      print("Firebase onMessage!!!");
      // showCallkitIncoming();
      if (Platform.isIOS) {
        await Future.delayed(Duration(milliseconds: 3000)).then((value) {
          newMessage(message);
        });
      } else {
        newMessage(message);
      }
    });

    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
      print("Firebase onMessageOpenedApp!!!");
      if (Platform.isIOS) {
        await Future.delayed(Duration(milliseconds: 3000)).then((value) {
          newMessage(message);
        });
      } else {
        newMessage(message);
      }
    });

    FirebaseMessaging.instance.getToken().then((String? token) {
      print("Push Notification getToken: " + token!);
      onToken(token!);
    }).catchError((err) {
      print(err);
    });

    FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) {
      print("Push Notification onTokenRefresh: " + fcm_token);
      onToken(fcm_token);
    });

    if (Platform.isAndroid) {
      final deviceInfo = DeviceInfoPlugin();
      final androidInfo = await deviceInfo.androidInfo;

      int sdkInt = androidInfo.version.sdkInt ?? 0;
      if (sdkInt >= 33) {
        // await FlutterCallkitIncoming.requestFullIntentPermission();
      }
    }
  }

  newMessage(RemoteMessage remoteMessage) async {
    print("Remote Message: " + remoteMessage.data.toString());
    if (remoteMessage.data.isEmpty) {
      return;
    }
    debugPrint('the value of the remote message is ${remoteMessage.data}');
    if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) {
      _incomingCall(remoteMessage.data);
      // showCallkitIncoming();
    } else {
      // GetNotificationsResponseModel notification = new GetNotificationsResponseModel();
      //
      // notification.createdOn = DateUtil.convertDateToString(DateTime.now());
      // notification.messageTypeData = remoteMessage.data['picture'];
      // notification.message = remoteMessage.data['message'];
      // notification.notificationType = remoteMessage.data["NotificationType"].toString();
      // if (remoteMessage.data["NotificationType"] == "2") {
      //   notification.videoURL = remoteMessage.data["VideoUrl"];
      // }
      //
      // await NavigationService.navigateToPage(NotificationsDetailsPage(
      //   notification: notification,
      // ));
    }
  }

  onToken(String token) async {
    print("Push Notification Token: " + token);
    await Utils.saveStringFromPrefs(CacheConst.pushToken, token);
  }

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

  Future<void> requestPermissions() async {
    try {
      if (Platform.isIOS) {
        await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true, badge: true, sound: true);
      } else if (Platform.isAndroid) {
        Map<Permission, PermissionStatus> statuses = await [
          Permission.notification,
          // Permission.camera,
          // Permission.audio,
          // Permission.microphone,
        ].request();
        print("=-=-=-=-=-=-=-=-=-=-");
        print(statuses[Permission.notification]);
      }
    } catch (_) {
      debugPrint(_.toString());
    }
  }
}
