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:ride/constant/colors.dart';
import 'package:ride/constant/style.dart';
import 'package:ride/controller/functions/crud.dart';
import 'package:ride/controller/functions/launch.dart';
import 'package:ride/controller/home/captin/map_driver_controller.dart';
import 'package:ride/controller/home/map_passenger_controller.dart';
import 'package:ride/views/home/profile/promos_passenger_page.dart';
import 'package:ride/views/widgets/elevated_btn.dart';

import '../../constant/box_name.dart';
import '../../constant/credential.dart';
import '../../constant/links.dart';
import '../../main.dart';
import '../../views/orderCaptin/order_request_page.dart';

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

  List<String> tokens = [];
  List dataTokens = [];
  late String driverID;
  late String driverToken;
  NotificationSettings? notificationSettings;

  Future<void> getNotificationSettings() async {
    // Get the current notification settings
    NotificationSettings? notificationSettings =
        await FirebaseMessaging.instance.getNotificationSettings();
    print(
        '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,
      );
      print('User granted permission: ${settings.authorizationStatus}');
      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(AppCredintials.basicAuthCredentials))}',
      },
      body: {},
    );
    // print(res.body);
    var jsonResponse = jsonDecode(res.body);
    // print(jsonResponse);
    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);
      print(box.read(BoxName.tokens));
    } 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);
      }
      print(token);
    });

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      if (message.data.isNotEmpty) {
        if (message.notification!.title!.contains('Order')) {
          var myListString = message.data['DriverList'];
          print(myListString);
          print('9999999999999myListString999999999999999');
          var myList = jsonDecode(myListString) as List<dynamic>;
          driverToken = myList[14].toString();
          update();
          print('driverToken==============' + driverToken.toString());
          Get.to(() => OrderRequestPage(), arguments: {
            'myListString': myListString,
            'DriverList': myList,
            'body': message.notification!.body
          });
        } else if (message.notification!.title!.contains('Apply Ride')) {
          var passengerList = message.data['passengerList'];
          print(passengerList);
          print('9999999999999my Apply Ride 999999999999999');
          var myList = jsonDecode(passengerList) as List<dynamic>;
          driverID = myList[2].toString();

          Get.snackbar(
            'Captin Applied the Ride for You'.tr,
            'message',
            colorText: AppColor.greenColor,
            duration: const Duration(seconds: 11),
            instantInit: true,
            snackPosition: SnackPosition.TOP,
            titleText: Text(
              'Applied'.tr,
              style: const TextStyle(color: AppColor.redColor),
            ),
            messageText: Text(
              'Captin Applied the Ride for You'.tr,
              style: AppStyle.title,
            ),
            icon: const Icon(Icons.approval),
            shouldIconPulse: true,
            maxWidth: double.infinity,
            margin: const EdgeInsets.all(16),
            padding: const EdgeInsets.all(16),
            borderRadius: 8,
            borderColor: AppColor.primaryColor,
            borderWidth: 2,
            backgroundColor: AppColor.secondaryColor,
            leftBarIndicatorColor: AppColor.greenColor,
            boxShadows: [
              BoxShadow(
                color: Colors.black.withOpacity(0.25),
                blurRadius: 4,
                spreadRadius: 2,
                offset: const Offset(0, 4),
              ),
            ],
            backgroundGradient: const LinearGradient(
              colors: [AppColor.greenColor, AppColor.accentColor],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
            ),
            onTap: (GetSnackBar snackBar) {
              // Do something when the snackbar is tapped.
              // MapController().rideConfirm = false;
              // update();
            },
            isDismissible: true,
            showProgressIndicator: false,
            dismissDirection: DismissDirection.up,
            progressIndicatorController: null,
            progressIndicatorBackgroundColor: Colors.transparent,
            progressIndicatorValueColor: null,
            snackStyle: SnackStyle.GROUNDED,
            forwardAnimationCurve: Curves.easeInToLinear,
            reverseAnimationCurve: Curves.easeInOut,
            animationDuration: const Duration(milliseconds: 4000),
            barBlur: 8,
            overlayBlur: 0,
            snackbarStatus: null,
            overlayColor: AppColor.primaryColor.withOpacity(0.5),
            userInputForm: null,
          );
        } else if (message.notification!.title!.contains('Promo')) {
          Get.to(const PromosPassengerPage());
        } else if (message.notification!.title!
            .contains('DriverIsGoingToPassenger')) {
          Get.snackbar('Driver is Going To Passenger', '',
              backgroundColor: AppColor.greenColor);
        } else if (message.notification!.title!.contains('RideIsBegin')) {
          // MapPassengerController mapController = Get.put(MapPassengerController());
          Get.snackbar('RideIsBegin', '', backgroundColor: AppColor.greenColor);
          // mapController.driverArrivePassenger();
          update();
        } else if (message.notification!.title!.contains('isRideFinished')) {
          MapPassengerController mapController =
              Get.find<MapPassengerController>();
          Get.snackbar('Ride Finished'.tr, '',
              backgroundColor: AppColor.greenColor);
          mapController.isRideFinished = true;
          update();
        }
      }
    });

    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print(
          'onMessageOpenedApp: ${message.notification!.title} ${message.notification!.body}');
      RemoteNotification? notification = message.notification;
      if (message.data.isNotEmpty) {
        if (message.notification!.title!.contains('Order')) {
          var myListString = message.data['myList'];
          var myList = jsonDecode(myListString) as List<dynamic>;
          Get.defaultDialog(
              barrierDismissible: true,
              title: message.notification!.title.toString(),
              content: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // Text(message.notification!.body.toString()),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: TextButton.icon(
                        onPressed: () {
                          String mapUrl =
                              'https://www.google.com/maps/dir/${myList[0]}/${myList[1]}/';
                          print(mapUrl);
                          launchUrl1(mapUrl);
                        },
                        icon: const Icon(Icons.map),
                        label: Text('Rouats of Trip'.tr)),
                  ),

                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      'Tatal From Passenger is '.tr +
                          double.parse(myList[2]).toStringAsFixed(2),
                      style: AppStyle.title,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      'Tatal For You is '.tr +
                          double.parse(myList[3]).toStringAsFixed(2),
                      style: AppStyle.title,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      'Distance is '.tr + myList[5].toString() + ' KM'.tr,
                      style: AppStyle.title,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      'Duration of Trip is '.tr +
                          myList[4].toString() +
                          ' Minutes'.tr,
                      style: AppStyle.title,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        MyElevatedButton(
                          title: 'Apply Order'.tr,
                          onPressed: () async {
                            await CRUD().postFromDialogue(
                                link: AppLink.addDriverOrder,
                                payload: {
                                  'driver_id': myList[6].toString(),
                                  // box.read(BoxName.driverID).toString(),
                                  'order_id':
                                      message.notification!.body.toString(),
                                  'status': 'Apply'
                                });
                          },
                        ),
                        MyElevatedButton(
                          title: 'Refuse Order'.tr,
                          onPressed: () async {
                            await CRUD().postFromDialogue(
                                link: AppLink.addDriverOrder,
                                payload: {
                                  'driver_id': myList[6].toString(),
                                  // box.read(BoxName.driverID).toString(),
                                  'order_id':
                                      message.notification!.body.toString(),
                                  'status': 'Refused'
                                });
                          },
                          kolor: AppColor.redColor,
                        ),
                      ],
                    ),
                  )
                ],
              ));
        }
      } else if (message.notification!.title!.contains('Apply Ride')) {
        // MapController().rideConfirm = true;
        var passengerList = message.data['passengerList'];
        print(passengerList);
        print('9999999999999my Apply Ride 999999999999999');
        MapPassengerController mapController =
            Get.find<MapPassengerController>();
        mapController.rideConfirm = false;
        update();
        print('-----------------------------rideConfirm===' +
            mapController.rideConfirm.toString());

        var myList = jsonDecode(passengerList) as List<dynamic>;
        driverID = myList[2].toString();
        Get.snackbar(
          'Captin Applied the Ride for You'.tr,
          'message',
          colorText: AppColor.greenColor,
          duration: const Duration(seconds: 11),
          instantInit: true,
          snackPosition: SnackPosition.TOP,
          titleText: Text(
            'Applied'.tr,
            style: const TextStyle(color: AppColor.redColor),
          ),
          messageText: Text(
            'Captin Applied the Ride for You'.tr,
            style: AppStyle.title,
          ),
          icon: const Icon(Icons.approval),
          shouldIconPulse: true,
          maxWidth: double.infinity,
          margin: const EdgeInsets.all(16),
          padding: const EdgeInsets.all(16),
          borderRadius: 8,
          borderColor: AppColor.primaryColor,
          borderWidth: 2,
          backgroundColor: AppColor.secondaryColor,
          leftBarIndicatorColor: AppColor.greenColor,
          boxShadows: [
            BoxShadow(
              color: Colors.black.withOpacity(0.25),
              blurRadius: 4,
              spreadRadius: 2,
              offset: const Offset(0, 4),
            ),
          ],
          backgroundGradient: const LinearGradient(
            colors: [AppColor.greenColor, AppColor.accentColor],
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
          ),
          onTap: (GetSnackBar snackBar) {
            // Do something when the snackbar is tapped.
            // MapController().rideConfirm = false;
            // update();
          },
          isDismissible: true,
          showProgressIndicator: false,
          dismissDirection: DismissDirection.up,
          progressIndicatorController: null,
          progressIndicatorBackgroundColor: Colors.transparent,
          progressIndicatorValueColor: null,
          snackStyle: SnackStyle.GROUNDED,
          forwardAnimationCurve: Curves.easeInToLinear,
          reverseAnimationCurve: Curves.easeInOut,
          animationDuration: const Duration(milliseconds: 4000),
          barBlur: 8,
          overlayBlur: 0,
          snackbarStatus: null,
          overlayColor: AppColor.primaryColor.withOpacity(0.5),
          userInputForm: null,
        );
      } else if (message.notification!.title!.contains('Promo')) {
        Get.to(const PromosPassengerPage());
      } else if (message.notification!.title!.contains('RideIsBegin')) {
        // MapDirection mapDirection = Get.find<MapDirection>();
        // mapDirection.clearPolyline();
        print('jjjjjjjjjjjjjjjjjjjjjjjjjjj');
        Get.defaultDialog(
          title: 'The Ride is Begin'.tr,
          backgroundColor: AppColor.greenColor,
        );
        MapDriverController().clearPolyline();
      }
    });
  }

  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);
    // print(tokens);
    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=${AppCredintials.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) {
        print('sendNotification() error: $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=${AppCredintials.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) {
  //       print('sendNotification() error: $e');
  //     });
  //   }
  // }

  void sendNotificationToPassengerToken(
      String title, body, token, List<String> map) async {
    try {
      final response = await http.post(
        Uri.parse('https://fcm.googleapis.com/fcm/send'),
        headers: <String, String>{
          'Content-Type': 'application/json',
          'Authorization': 'key=${AppCredintials.serverAPI}'
        },
        body: jsonEncode({
          'notification': <String, dynamic>{
            'title': title,
            'body': body,
            'sound': 'true'
          },
          'data': {
            'passengerList': map,
          },
          'priority': 'high',
          'to': token,
        }),
      );

      if (response.statusCode == 200) {
        // Notification sent successfully
        print('Notification sent successfully');
      } else {
        // Handle error response
        print(
            'Failed to send notification. Status code: ${response.statusCode}');
      }
    } catch (e) {
      // Handle other exceptions
      print('sendNotification() error: $e');
    }
  }

  void sendNotificationToAnyWithoutData(
      String title, String body, String token) async {
    try {
      final response = await http.post(
        Uri.parse('https://fcm.googleapis.com/fcm/send'),
        headers: <String, String>{
          'Content-Type': 'application/json',
          'Authorization': 'key=${AppCredintials.serverAPI}'
        },
        body: jsonEncode({
          'notification': <String, dynamic>{
            'title': title,
            'body': body,
            'sound': 'true'
          },
          'data': <String, dynamic>{
            'click_action': 'FLUTTER_NOTIFICATION_CLICK',
            'id': '1',
            'status': 'done'
          },
          'priority': 'high',
          'to': token,
        }),
      );

      if (response.statusCode == 200) {
        // Notification sent successfully
        print('Notification sent successfully');
      } else {
        // Handle error response
        print(
            'Failed to send notification. Status code: ${response.statusCode}');
      }
    } catch (e) {
      // Handle other exceptions
      print('sendNotification() error: $e');
    }
  }

  void sendNotificationToDriverMAP(
      String title, String body, String token, List<String> data) async {
    try {
      final response = await http.post(
        Uri.parse('https://fcm.googleapis.com/fcm/send'),
        headers: <String, String>{
          'Content-Type': 'application/json',
          'Authorization': 'key=${AppCredintials.serverAPI}'
        },
        body: jsonEncode({
          'notification': <String, dynamic>{
            'title': title,
            'body': body,
            'sound': 'true'
          },
          'data': {
            'DriverList': data,
          },
          'priority': 'high',
          'to': token,
        }),
      );

      if (response.statusCode == 200) {
        // Notification sent successfully
        print('Notification sent successfully');
      } else {
        // Handle error response
        print(
            'Failed to send notification. Status code: ${response.statusCode}');
      }
    } catch (e) {
      // Handle other exceptions
      print('sendNotification() error: $e');
    }
  }
}
