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:siro_admin/constant/info.dart';
import 'package:siro_admin/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 'notification_service.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,
  //       ));
  // }

  //   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

  void sendNotificationAll(String title, body) async {
    // Deprecated: Admin panel notifications are sent via NotificationService.
  }

  void sendNotificationToAnyWithoutData(
      String title, String body, String token, String tone) async {
    await NotificationService.sendNotification(
      target: token,
      title: title,
      body: body,
      category: 'fromAdmin',
      tone: tone,
    );
  }
}
