import 'dart:convert';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:secure_string_operations/secure_string_operations.dart';
import 'package:sefer_admin1/constant/info.dart';
import 'package:sefer_admin1/env/env.dart';

import '../../constant/api_key.dart';
import '../../constant/box_name.dart';
import '../../constant/char_map.dart';
import '../../constant/colors.dart';
import '../../constant/links.dart';
import '../../constant/style.dart';
import '../../main.dart';
import '../../print.dart';
import '../../views/widgets/elevated_btn.dart';
import '../functions/encrypt_decrypt.dart';
import '../notification_controller.dart';
import 'local_notification.dart';
import 'token_access.dart';

class FirebaseMessagesController extends GetxController {
  final fcmToken = FirebaseMessaging.instance;

  List<String> tokens = [];
  List<String> tokensPassengers = [];
  List dataTokens = [];
  List dataTokensPassenger = [];
  late String driverID;
  late String driverToken;
  NotificationSettings? notificationSettings;
  bool isLoading = false;
  Future<void> getNotificationSettings() async {
    // Get the current notification settings
    NotificationSettings? notificationSettings =
        await FirebaseMessaging.instance.getNotificationSettings();
    'Notification authorization status: ${notificationSettings.authorizationStatus}';

    // Call the update function if needed
    update();
  }

  Future<void> requestFirebaseMessagingPermission() async {
    FirebaseMessaging messaging = FirebaseMessaging.instance;

    // Check if the platform is Android
    if (Platform.isAndroid) {
      // Request permission for Android
      await messaging.requestPermission();
    } else if (Platform.isIOS) {
      // Request permission for iOS
      NotificationSettings settings = await messaging.requestPermission(
        alert: true,
        announcement: true,
        badge: true,
        carPlay: true,
        criticalAlert: true,
        provisional: false,
        sound: true,
      );
      messaging.setForegroundNotificationPresentationOptions(
          alert: true, badge: true, sound: true);
    }
  }

  Future getTokens() async {
    var res = await http.post(
      Uri.parse(AppLink.getTokens),
      headers: {
        'Authorization':
            'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
      },
      body: {},
    );
    var jsonResponse = jsonDecode(res.body);
    if (jsonResponse['status'] == 'success') {
      dataTokens = jsonResponse['data'];
      for (var i = 0; i < dataTokens.length; i++) {
        tokens.add(jsonResponse['data'][i]['token']);
      }
      box.write(BoxName.tokens, tokens);
    } else {
      Get.defaultDialog(title: "Warning", middleText: "Server Error");
    }
  }

  var currentPage = 1;
  var totalPages = 1;
  Future<void> getAllTokenDrivers() async {
    isLoading = true;
    try {
      var res = await http.post(
        Uri.parse(AppLink.getDriversPhonesAndTokens),
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          'Authorization':
              'Bearer ${X.r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs).toString().split(AppInformation.addd)[0]}'
          // 'Authorization': 'Bearer ${box.read(BoxName.jwt)}'
        },
        body: {
          // 'page': page.toString(),
        },
      );

      var jsonResponse = jsonDecode(res.body);
      Log.print('jsonResponse: ${jsonResponse}');
      if (jsonResponse['status'] == 'success') {
        // var newData = jsonResponse['data'] as List;
        // Log.print('newData: ${newData}');
        // // if (page == 1) {
        // //   dataTokens.clear();
        // //   tokens.clear();
        // // }
        // dataTokens.addAll(newData);
        // for (var item in newData) {
        //   tokens.add(item['token']);
        // }
        // currentPage = int.parse(jsonResponse['currentPage']);
        // totalPages = jsonResponse['totalPages'];
        box.write(BoxName.tokensDrivers, jsonResponse);
        Log.print(
            'box.write(BoxName.tokensDrivers: ${box.read(BoxName.tokensDrivers)}');
      } else {
        Get.defaultDialog(
            title: "Warning", middleText: "No more data available");
      }
    } catch (e) {
      Get.defaultDialog(title: "Error", middleText: "Server Error: $e");
    } finally {
      isLoading = false;
    }
  }

  var currentPagePassenger = 1;
  var totalPagesPassenger = 1;
  Future<void> getAllTokenPassenger({int page = 1}) async {
    isLoading = true;
    try {
      var res = await http.post(
        Uri.parse(AppLink.getAllTokenPassengers),
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          'Authorization':
              'Bearer ${X.r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs).toString().split(AppInformation.addd)[0]}'
        },
        body: {},
      );

      var jsonResponse = jsonDecode(res.body);
      if (jsonResponse['status'] == 'success') {
        box.write(BoxName.tokensPassengers, jsonResponse);
        Log.print(
            'box.write(BoxName.tokensPassenger: ${box.read(BoxName.tokensPassengers)}');
      } else {
        Get.defaultDialog(
            title: "Warning", middleText: "No more data available");
      }
    } catch (e) {
      Get.defaultDialog(title: "Error", middleText: "Server Error: $e");
    } finally {
      isLoading = false;
    }
  }

  bool isSendingNotifications = false;
  Future<void> loadAllPagesAndSendNotifications() async {
    isSendingNotifications = true;
    // currentPage = 1;

    // while (currentPage <= totalPages) {
    // await getAllTokenDrivers(page: currentPage);
    await getAllTokenDrivers();
    // Log.print('tokens: ${tokens}');
    await NotificationController().sendNotificationDrivers();
    // print(tokens);

    // if (currentPage < totalPages) {
    //   await Future.delayed(const Duration(seconds: 3));
    // }
    // currentPage++;
    // }

    isSendingNotifications = false;
    Get.snackbar("Success", "All notifications sent!");
  }

  bool isSendingNotificationsPassenger = false;
  Future<void> loadAllPagesAndSendNotificationsPassengers() async {
    isSendingNotificationsPassenger = true;
    currentPage = 1;

    // while (currentPagePassenger <= totalPagesPassenger) {
    await getAllTokenPassenger();
    await NotificationController().sendNotificationPassengers();
    // print(tokensPassengers);
    // if (currentPagePassenger < totalPagesPassenger) {
    //   await Future.delayed(const Duration(seconds: 3));
    // }
    // currentPagePassenger++;
    // }

    isSendingNotificationsPassenger = false;
    Get.snackbar("Success", "All notifications sent!");
  }

  Future getAllTokenPassengers() async {
    var res = await http.post(
      Uri.parse(AppLink.getAllTokenPassengers),
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        'Authorization':
            'Bearer ${X.r(X.r(X.r(box.read(BoxName.jwt), cn), cC), cs).toString().split(AppInformation.addd)[0]}'
        // 'Authorization': 'Bearer ${box.read(BoxName.jwt)}'
      },
      body: {},
    );
    var jsonResponse = jsonDecode(res.body);
    if (jsonResponse['status'] == 'success') {
      dataTokens = jsonResponse['data'];
      for (var i = 0; i < dataTokens.length; i++) {
        tokensPassengers.add(jsonResponse['data'][i]['token']);
      }
      box.write(BoxName.tokensPassengers, jsonResponse['data']);
    } else {
      Get.defaultDialog(title: "Warning", middleText: "Server Error");
    }
  }

  Future getToken() async {
    fcmToken.getToken().then((token) {
      if (box.read(BoxName.email) == null) {
        box.write(BoxName.tokenDriver, token);
      } else {
        box.write(BoxName.tokenFCM, token);
      }
    });

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      // If the app is in the background or terminated, show a system tray message
      RemoteNotification? notification = message.notification;
      AndroidNotification? android = notification?.android;
      // if (notification != null && android != null) {
      if (message.data.isNotEmpty && message.notification != null) {
        fireBaseTitles(message);
      }
    });
  }

  void fireBaseTitles(RemoteMessage message) {
    if (message.notification!.title! == 'Order') {
      if (Platform.isAndroid) {
        // NotificationController().showNotification('Order', '', 'order');
      }
      var myListString = message.data['DriverList'];
      // var points = message.data['PolylineJson'];

      var myList = jsonDecode(myListString) as List<dynamic>;
      // var myPoints = jsonDecode(points) as List<dynamic>;
      driverToken = myList[14].toString();
      // This is for location using and uploading status

      update();
    }
  }

  SnackbarController driverAppliedTripSnakBar() {
    return Get.snackbar(
      'Driver Applied the Ride for You'.tr,
      '',
      colorText: AppColor.greenColor,
      duration: const Duration(seconds: 3),
      snackPosition: SnackPosition.TOP,
      titleText: Text(
        'Applied'.tr,
        style: const TextStyle(color: AppColor.redColor),
      ),
      messageText: Text(
        'Driver Applied the Ride for You'.tr,
        style: AppStyle.title,
      ),
      icon: const Icon(Icons.approval),
      shouldIconPulse: true,
      margin: const EdgeInsets.all(16),
      padding: const EdgeInsets.all(16),
    );
  }

  Future<dynamic> passengerDialog(String message) {
    return Get.defaultDialog(
        barrierDismissible: false,
        title: 'message From passenger'.tr,
        titleStyle: AppStyle.title,
        middleTextStyle: AppStyle.title,
        middleText: message.tr,
        confirm: MyElevatedButton(
            title: 'Ok'.tr,
            onPressed: () {
              //   FirebaseMessagesController().sendNotificationToPassengerToken(
              //       'Hi ,I will go now'.tr,
              //       'I will go now'.tr,
              //       Get.find<MapPassengerController>().driverToken, []);
              //   Get.find<MapPassengerController>()
              //       .startTimerDriverWaitPassenger5Minute();

              Get.back();
            }));
  }

  // Future<dynamic> driverFinishTripDialoge(List<dynamic> driverList) {
  //   return Get.defaultDialog(
  //       title: 'Driver Finish Trip'.tr,
  //       content: const DriverTipWidget(),
  //       confirm: MyElevatedButton(
  //         title: 'Yes'.tr,
  //         onPressed: () async {
  //           var tip = (Get.find<MapPassengerController>().totalPassenger) *
  //               (double.parse(box.read(BoxName.tipPercentage.toString())));
  //           var res = await CRUD().post(link: AppLink.addTips, payload: {
  //             'passengerID': box.read(BoxName.passengerID),
  //             'driverID': driverList[0].toString(),
  //             'rideID': driverList[1].toString(),
  //             'tipAmount': tip.toString(),
  //           });
  //           await CRUD().post(link: AppLink.addPassengersWallet, payload: {
  //             'passenger_id': box.read(BoxName.passengerID).toString(),
  //             'balance': ((-1) * tip).toString()
  //           });

  //           await CRUD().post(link: AppLink.addDriversWalletPoints, payload: {
  //             'driverID': driverList[0].toString(),
  //             'paymentID': '${Get.find<MapPassengerController>().rideId}tip',
  //             'amount': (tip * 100).toString(),
  //             'paymentMethod': 'visa-tip',
  //           });

  //           if (res != 'failure') {
  //             FirebaseMessagesController().sendNotificationToAnyWithoutData(
  //               'You Have Tips',
  //               '${'${tip.toString()}\$${' tips\nTotal is'.tr}'} ${tip + (Get.find<MapPassengerController>().totalPassenger)}',
  //               driverList[2].toString(),
  //             );
  //           }
  //           Get.to(() => RateDriverFromPassenger(), arguments: {
  //             'driverId': driverList[0].toString(),
  //             'rideId': driverList[1].toString(),
  //             'price': driverList[3].toString()
  //           });
  //         },
  //         kolor: AppColor.greenColor,
  //       ),
  //       cancel: MyElevatedButton(
  //         title: 'No,I want'.tr,
  //         onPressed: () {
  //           Get.to(() => RateDriverFromPassenger(), arguments: {
  //             'driverId': driverList[0].toString(),
  //             'rideId': driverList[1].toString(),
  //             'price': driverList[3].toString()
  //           });
  //         },
  //         kolor: AppColor.redColor,
  //       ));
  // }

  void sendNotificationAll(String title, body) async {
    // Get the token you want to subtract.
    String token = box.read(BoxName.tokenFCM);
    tokens = box.read(BoxName.tokens);
    // Subtract the token from the list of tokens.
    tokens.remove(token);

    // Save the list of tokens back to the box.
    // box.write(BoxName.tokens, tokens);
    tokens = box.read(BoxName.tokens);
    for (var i = 0; i < tokens.length; i++) {
      String serviceAccountKeyJson = '''{
  "type": "service_account",
  "project_id": "ride-b1bd8",
  "private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249",
  "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n",
  "client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com",
  "client_id": "111210077025005706623",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-o2wqi%40ride-b1bd8.iam.gserviceaccount.com",
  "universe_domain": "googleapis.com"
}
'''; // As defined above

      // Initialize AccessTokenManager
      final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);

      // Obtain an OAuth 2.0 access token
      final accessToken = await accessTokenManager.getAccessToken();

      // Send the notification
      final response = await http
          .post(
              Uri.parse(
                  'https://fcm.googleapis.com/v1/projects/ride-b1bd8/messages:send'),
              headers: <String, String>{
                'Content-Type': 'application/json',
                'Authorization': 'Bearer $accessToken',
              },
              body: jsonEncode({
                'notification': <String, dynamic>{
                  'title': title,
                  'body': body,
                  'sound': 'ding.wav'
                },
                'priority': 'high',
                'data': <String, dynamic>{
                  'click_action': 'FLUTTER_NOTIFICATION_CLICK',
                  'id': '1',
                  'status': 'done'
                },
                'to': tokens[i],
              }))
          .whenComplete(() {})
          .catchError((e) {});
    }
  }

  //   for (var i = 0; i < tokens.length; i++) {
  //     http
  //         .post(Uri.parse('https://fcm.googleapis.com/fcm/send'),
  //             headers: <String, String>{
  //               'Content-Type': 'application/json',
  //               'Authorization': 'key=${storage.read(key: BoxName.serverAPI}'
  //             },
  //             body: jsonEncode({
  //               'notification': <String, dynamic>{
  //                 'title': title,
  //                 'body': body,
  //                 'sound': 'true'
  //               },
  //               'priority': 'high',
  //               'data': <String, dynamic>{
  //                 'click_action': 'FLUTTER_NOTIFICATION_CLICK',
  //                 'id': '1',
  //                 'status': 'done'
  //               },
  //               'to': tokens[i],
  //             }))
  //         .whenComplete(() {})
  //         .catchError((e) {
  //     });
  //   }
  // }
//android/app/src/main/res/raw/iphone_ringtone.wav

  late String serviceAccountKeyJson;
  void sendNotificationToAnyWithoutData(
      String title, String body, String token, String tone) async {
    try {
      var encryptedKey = Env.privateKeyFCM;
      // Log.print('encryptedKey: ${encryptedKey}');
      serviceAccountKeyJson =
          EncryptionHelper.instance.decryptData(encryptedKey);
// As defined above

      // Initialize AccessTokenManager
      final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);

      // Obtain an OAuth 2.0 access token
      final accessToken = await accessTokenManager.getAccessToken();
      // Log.print('accessToken: ${accessToken}');

      // Send the notification
      final response = await http.post(
        Uri.parse(
            'https://fcm.googleapis.com/v1/projects/intaleq-d48a7/messages:send'),
        headers: <String, String>{
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $accessToken',
        },
        body: jsonEncode({
          'message': {
            'token': token,
            'notification': {
              'title': title,
              'body': body,
            },
            'android': {
              'notification': {
                'sound': tone,
              },
            },
            'apns': {
              'payload': {
                'aps': {
                  'sound': tone,
                },
              },
            },
          },
        }),
      );

      if (response.statusCode == 200) {
        SnackBar(content: Text('${response.statusCode}'));
        print(
            'Notification sent successfully. Status code: ${response.statusCode}');
        print('Response body: ${response.body}');
      } else {
        print(
            'Failed to send notification. Status code: ${response.statusCode}');
        print('Response body: ${response.body}');
      }
    } catch (e) {
      print('Error sending notification: $e');
    }
  }
}
