import 'dart:async';
import 'dart:convert';
import 'dart:math' as math;
import 'dart:math' show cos;
import 'package:SEFER/constant/table_names.dart';
import 'package:SEFER/controller/home/captin/home_captain_controller.dart';
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_polyline_algorithm/google_polyline_algorithm.dart';
import 'package:SEFER/constant/style.dart';
import 'package:SEFER/views/widgets/elevated_btn.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../../constant/api_key.dart';
import '../../../constant/box_name.dart';
import '../../../constant/colors.dart';
import '../../../constant/links.dart';
import '../../../main.dart';
import '../../../views/Rate/rate_passenger.dart';
import '../../../views/home/Captin/home_captain/home_captin.dart';
import '../../firebase/firbase_messge.dart';
import '../../functions/crud.dart';
import '../../functions/location_controller.dart';

class MapDriverController extends GetxController {
  bool isLoading = true;
  final formKey1 = GlobalKey<FormState>();
  final sosEmergincyNumberCotroller = TextEditingController();
  List data = [];
  List dataDestination = [];
  LatLngBounds? boundsData;
  BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker;
  BitmapDescriptor passengerIcon = BitmapDescriptor.defaultMarker;
  BitmapDescriptor startIcon = BitmapDescriptor.defaultMarker;
  BitmapDescriptor endIcon = BitmapDescriptor.defaultMarker;
  final List<LatLng> polylineCoordinates = [];
  final List<LatLng> polylineCoordinatesDestination = [];
  List<Polyline> polyLines = [];
  List<Polyline> polyLinesDestination = [];
  Set<Marker> markers = {};
  late String passengerLocation;
  late String passengerDestination;
  late String step0;
  late String step1;
  late String step2;
  late String step3;
  late String step4;
  late String passengerWalletBurc;
  late String timeOfOrder;
  late String duration;
  late String totalCost;
  late String distance;
  late String passengerName;
  late String passengerEmail;
  late String totalPassenger;
  late String passengerPhone;
  late String rideId;
  late String isHaveSteps;
  late String paymentAmount;
  late String paymentMethod;
  late String passengerId;
  late String driverId;
  late String tokenPassenger;
  late String durationToPassenger;
  late String walletChecked;
  late String direction;
  late String durationOfRideValue;
  late String status;
  int timeWaitingPassenger = 5; //5 miniute
  bool isPassengerInfoWindow = false;
  bool isBtnRideBegin = false;
  bool isArrivedSend = true;
  bool isdriverWaitTimeEnd = false;
  bool isRideFinished = false;
  bool isRideStarted = false;
  bool isPriceWindow = false;
  double passengerInfoWindowHeight = Get.height * .35;
  double driverEndPage = 100;
  double progress = 0;
  double progressToPassenger = 0;
  double progressInPassengerLocationFromDriver = 0;
  bool isRideBegin = false;
  int progressTimerToShowPassengerInfoWindowFromDriver = 25;
  int remainingTimeToShowPassengerInfoWindowFromDriver = 25;
  int remainingTimeToPassenger = 60;
  int remainingTimeInPassengerLocatioWait = 60;
  bool isDriverNearPassengerStart = false;
  GoogleMapController? mapController;
  late LatLng myLocation;
  int remainingTimeTimerRideBegin = 60;
  String stringRemainingTimeRideBegin = '';
  String stringRemainingTimeRideBegin1 = '';
  double progressTimerRideBegin = 0;
  late Timer timer;
  String? mapAPIKEY;
  final zones = <Zone>[];
  String canelString = 'yet';
  late LatLng latLngpassengerLocation;
  late LatLng latLngPassengerDestination;

  void onMapCreated(GoogleMapController controller) async {
    myLocation = Get.find<LocationController>().location as LatLng;
    myLocation = myLocation;
    mapController = controller;
    controller.getVisibleRegion();
    controller.animateCamera(
      CameraUpdate.newLatLng(Get.find<LocationController>().myLocation),
    );
    update();
    // Set up a timer or interval to trigger the marker update every 3 seconds.
    timer = Timer.periodic(const Duration(seconds: 1), (_) {
      updateMarker();
    });
  }

  void changeStatusDriver() {
    status = 'On';
    update();
  }

  void changeDriverEndPage() {
    remainingTimeTimerRideBegin < 60 ? driverEndPage = 160 : 100;
    update();
  }

  takeSnapMap() {
    mapController!.takeSnapshot();
  }

  @override
  void dispose() {
    mapController!.dispose();
    super.dispose();
  }

  Future openGoogleMapFromDriverToPassenger() async {
    var endLat = latLngpassengerLocation.latitude;
    var endLng = latLngpassengerLocation.longitude;

    var startLat = Get.find<LocationController>().myLocation.latitude;
    var startLng = Get.find<LocationController>().myLocation.longitude;

    String url =
        'https://www.google.com/maps/dir/$startLat,$startLng/$endLat,$endLng/&directionsmode=driving';
    if (await canLaunchUrl(Uri.parse(url))) {
      await launchUrl(Uri.parse(url));
    } else {
      throw 'Could not launch google maps';
    }
  }

  void clearPolyline() {
    polyLines = [];
    polyLinesDestination = [];
    polylineCoordinates.clear();
    polylineCoordinatesDestination.clear();
    update();
  }

  void changeRideToBeginToPassenger() {
    isRideBegin = true;
    passengerInfoWindowHeight = Get.height * .22;
    update();
  }

  void startTimerToShowPassengerInfoWindowFromDriver() async {
    isPassengerInfoWindow = true;
    for (int i = 0; i <= int.parse(durationToPassenger); i++) {
      await Future.delayed(const Duration(seconds: 1));
      progressToPassenger = i / int.parse(durationToPassenger);
      remainingTimeToPassenger = int.parse(durationToPassenger) - i;
      if (remainingTimeToPassenger == 0) {
        isBtnRideBegin = true;
        print(isBtnRideBegin);
        update();
      }
      print(isBtnRideBegin);
      print(remainingTimeToPassenger);

      int minutes = (remainingTimeToPassenger / 60).floor();
      int seconds = remainingTimeToPassenger % 60;
      stringRemainingTimeToPassenger =
          '$minutes:${seconds.toString().padLeft(2, '0')}';

      update();
    }
    // update();
    // startTimerToShowDriverToPassengerDuration();
  }

  String stringRemainingTimeToPassenger = '';

  String stringRemainingTimeWaitingPassenger = '';

  void startTimerToShowDriverWaitPassengerDuration() async {
    for (int i = 0; i <= timeWaitingPassenger * 60; i++) {
      await Future.delayed(const Duration(seconds: 1));
      progressInPassengerLocationFromDriver = i / (timeWaitingPassenger * 60);
      remainingTimeInPassengerLocatioWait = (timeWaitingPassenger * 60) - i;
      if (isRideBegin == true) {
        remainingTimeInPassengerLocatioWait = 0;
        update();
      }
      if (remainingTimeInPassengerLocatioWait == 0) {
        isdriverWaitTimeEnd = true;
        print(isdriverWaitTimeEnd);
        update();
      }
      print(isdriverWaitTimeEnd);
      print(
          'remainingTimeInPassengerLocatioWait $remainingTimeInPassengerLocatioWait');

      int minutes = (remainingTimeInPassengerLocatioWait / 60).floor();
      int seconds = remainingTimeInPassengerLocatioWait % 60;
      stringRemainingTimeWaitingPassenger =
          '$minutes:${seconds.toString().padLeft(2, '0')}';

      update();
    }
  }

  void driverGoToPassenger() async {
    changeRideToBeginToPassenger();
    await CRUD().post(link: AppLink.updateRides, payload: {
      'id': rideId,
      'driverGoToPassengerTime': DateTime.now().toString(),
      'status': 'Applied'
    });
    FirebaseMessagesController().sendNotificationToAnyWithoutData(
        'DriverIsGoingToPassenger',
        box.read(BoxName.name).toString(),
        tokenPassenger);
    if (box.read(BoxName.googlaMapApp) == true) {
      await openGoogleMapFromDriverToPassenger();
    }
  }

  bool isSocialPressed = false;
  driverCallPassenger() async {
    String scam = await getDriverScam();
    if (scam != 'failure') {
      if (int.parse(scam) > 3) {
        box.write(BoxName.statusDriverLocation, 'on');
        Get.find<LocationController>().stopLocationUpdates();
        await CRUD().post(link: AppLink.addNotificationCaptain, payload: {
          'driverID': box.read(BoxName.driverID),
          'title': 'scams operations'.tr,
          'body':
              'you have connect to passengers and let them cancel the order'.tr,
        });
      } else if (isSocialPressed == true) {
        box.write(BoxName.statusDriverLocation, 'off');
        await CRUD().post(link: AppLink.adddriverScam, payload: {
          'driverID': box.read(BoxName.driverID),
          'passengerID': passengerId,
          'rideID': rideId,
          'isDriverCalledPassenger': '$isSocialPressed'
        });
      }
    }
  }

  Future<String> getDriverScam() async {
    var res = await CRUD().post(link: AppLink.getdriverScam, payload: {
      'driverID': box.read(BoxName.driverID),
    });
    if (res == 'failure') {
      print('Scam is failure');
      box.write(BoxName.statusDriverLocation, 'off');
      return '0';
    }
    var d = jsonDecode(res);
    print('Scam is ');
    print(d['message'][0]['count']);
    return d['message'][0]['count'];
  }

  Position? currentPosition;

  startRideFromDriver() async {
    double _distance =
        await calculateDistanceBetweenDriverAndPassengerLocation();

    if (_distance < 50) {
      changeRideToBeginToPassenger();
      isPassengerInfoWindow = false;
      isRideStarted = true;
      isRideFinished = false;
      remainingTimeInPassengerLocatioWait = 0;
      timeWaitingPassenger = 0;
      box.write(BoxName.statusDriverLocation, 'on');

      update();
      await CRUD().post(link: AppLink.updateRides, payload: {
        'id': rideId,
        'rideTimeStart': DateTime.now().toString(),
        'status': 'Begin',
      });

      FirebaseMessagesController().sendNotificationToAnyWithoutData(
          'RideIsBegin', box.read(BoxName.name).toString(), tokenPassenger);
      rideIsBeginPassengerTimer();

      // var d = jsonDecode(res);

      update();
      // Start updating location and moving camera
      // updateLocation();
    } else {
      Get.defaultDialog(
        barrierDismissible: false,
        title: 'Your are far from passenger location'.tr,
        middleText:
            'go to your passenger location before\nPassenger cancel trip'.tr,
        confirm: MyElevatedButton(
            title: 'Ok',
            onPressed: () {
              Get.back();
            }),
      );
    }
  }

  calculateDistanceInMeter(LatLng prev, LatLng current) async {
    double distance2 = Geolocator.distanceBetween(
      prev.latitude,
      prev.longitude,
      current.latitude,
      current.longitude,
    );
    return distance2;
  }

  double speedoMeter = 0;
  void updateLocation() async {
    try {
      for (var i = 0; i < remainingTimeTimerRideBegin; i++) {
        await Future.delayed(const Duration(seconds: 1));

        mapController!.animateCamera(
          CameraUpdate.newCameraPosition(
            CameraPosition(
              target: myLocation,
              zoom: 17, // Adjust zoom level as needed
            ),
          ),
        );
        // });
        update();
      }

      // Stop listening after ride finishes
      if (!isRideBegin) {}
    } catch (error) {
      debugPrint('Error listening to GPS: $error');
      // Handle GPS errors gracefully
    }

    // Periodically call updateLocation again
    await Future.delayed(const Duration(seconds: 1));
    updateLocation();
  }

  calculateDistanceBetweenDriverAndPassengerLocation() {
    double distance2 = Geolocator.distanceBetween(
      latLngpassengerLocation.latitude,
      latLngpassengerLocation.longitude,
      Get.find<LocationController>().myLocation.latitude,
      Get.find<LocationController>().myLocation.longitude,
    );
    return distance2;
  }

  addWaitingTimeCostFromPassengerToDriverWallet() async {
    double distance2 = calculateDistanceBetweenDriverAndPassengerLocation();

    if (distance2 > 40) {
      Get.defaultDialog(
          title: 'Your are far from passenger location'.tr,
          middleText:
              'go to your passenger location before\nPassenger cancel trip'.tr,
          confirm: MyElevatedButton(
              title: 'Ok',
              onPressed: () {
                Get.back();
              }));
    } else {
      double costOfWaiting5Minute =
          (distanceBetweenDriverAndPassengerWhenConfirm * .08) +
              (5 * 1); //for Eygpt other like jordan .06 per minute
      var res = await CRUD().post(link: AppLink.addDriverpayment, payload: {
        'rideId': rideId,
        'amount': costOfWaiting5Minute.toString(),
        'payment_method': 'wait-cancel',
        'passengerID': passengerId,
        'driverID': box.read(BoxName.driverID).toString(),
      });
      if (res != 'failure') {
        Get.snackbar(
          'You will get cost of your work for this trip'.tr,
          '${'you gain'.tr} $costOfWaiting5Minute \$${' in your wallet'.tr}',
          backgroundColor: AppColor.deepPurpleAccent,
        );
      }
      await CRUD().post(link: AppLink.addPassengersWallet, payload: {
        'passenger_id': passengerId,
        'balance': (costOfWaiting5Minute * -1).toString()
      });
      box.write(BoxName.statusDriverLocation, 'off');
      Get.offAll(HomeCaptain());
    }
  }

  void finishRideFromDriver() {
    Get.defaultDialog(
        title: 'Are you sure to exit ride ?'.tr,
        titleStyle: AppStyle.title,
        middleText: '',
        confirm: MyElevatedButton(
            title: 'Ok'.tr,
            kolor: AppColor.greenColor,
            onPressed: () {
              Get.back();
              finishRideFromDriver1();
            }),
        cancel: MyElevatedButton(
            title: 'Cancel'.tr,
            kolor: Colors.red,
            onPressed: () {
              Get.back();
            }));
  }

  void finishRideFromDriver1() async {
    double distanceToDestination = Geolocator.distanceBetween(
      latLngPassengerDestination.latitude,
      latLngPassengerDestination.longitude,
      Get.find<LocationController>().myLocation.latitude,
      Get.find<LocationController>().myLocation.longitude,
    );
    // if (carType != 'Comfort' || carType != 'Free Ride') {
    // if (distanceToDestination < 50) {
    isRideFinished = true;
    isRideStarted = false;
    isPriceWindow = false;
    totalCost = carType != 'Comfort' || carType != 'Mashwari'
        ? totalPassenger
        : price < double.parse(totalPassenger)
            ? totalPassenger
            : price.toStringAsFixed(2);
    paymentAmount = totalCost;
    box.write(BoxName.statusDriverLocation, 'off');
    // changeRideToBeginToPassenger();
    await CRUD().post(link: AppLink.updateRides, payload: {
      'id': rideId,
      'rideTimeFinish': DateTime.now().toString(),
      'status': 'Finished',
      'price': totalCost,
    });
    print('walletChecked is   $walletChecked');
    if (walletChecked == 'true') {
      await CRUD().post(link: AppLink.addPassengersWallet, payload: {
        'passenger_id': passengerId,
        'balance': ((-1) * double.parse(paymentAmount)).toString()
      });
    }
    await CRUD().post(link: AppLink.addDriverpayment, payload: {
      'rideId': rideId,
      'amount': paymentAmount,
      'payment_method': paymentMethod,
      'passengerID': passengerId,
      'driverID': box.read(BoxName.driverID).toString(),
    });
    print('passengerWalletBurc bef   ${double.parse(passengerWalletBurc)}');
    if (double.parse(passengerWalletBurc) < 0) {
      await CRUD().post(link: AppLink.addPassengersWallet, payload: {
        'passenger_id': passengerId,
        'balance': ((-1) * double.parse(passengerWalletBurc)).toString()
      });
      print('passengerWalletBurc  aft  ${double.parse(passengerWalletBurc)}');
    }

    double pointsSubstraction = 0;
    pointsSubstraction = double.parse(paymentAmount) *
        (-1) *
        double.parse(kazan) /
        100; // for eygpt /100
    var res = await CRUD().post(link: AppLink.addDriversWalletPoints, payload: {
      'paymentID': 'rideId$rideId',
      'amount': (pointsSubstraction).toStringAsFixed(0),
      'paymentMethod': paymentMethod,
      'driverID': box.read(BoxName.driverID).toString(),
    });
    print(res);
    Future.delayed(const Duration(milliseconds: 300));
    FirebaseMessagesController().sendNotificationToPassengerToken(
      'Driver Finish Trip',
      '${'you will pay to Driver'.tr} $paymentAmount \$',
      tokenPassenger,
      [
        box.read(BoxName.driverID),
        rideId,
        box.read(BoxName.tokenDriver),
        // carType == 'Comfort' || carType == 'Mashwari'
        //     ? price.toStringAsFixed(2)
        //     : totalPassenger
        paymentAmount.toString()
      ],
    );
    Get.to(() => RatePassenger(), arguments: {
      'passengerId': passengerId,
      'rideId': rideId,
      'price': price.toString(),
    });
    // Get.back();
  }

  void cancelCheckRideFromPassenger() async {
    var res = await CRUD().get(link: AppLink.getOrderCancelStatus, payload: {
      'order_id': rideId,
    }); //.then((value) {
    print('Cancel fetch--------------------');
    var response = jsonDecode(res);
    canelString = response['data']['status'];
    print('cancel is $canelString');
    update();
    if (canelString == 'Cancel') {
      remainingTimeTimerRideBegin = 0;
      remainingTimeToShowPassengerInfoWindowFromDriver = 0;
      remainingTimeToPassenger = 0;
      isRideStarted = false;
      isRideFinished = false;
      isPassengerInfoWindow = false;
      clearPolyline();
      update();
      Get.defaultDialog(
        title: 'Order Cancelled'.tr,
        titleStyle: AppStyle.title,
        middleText: 'Order Cancelled by Passenger'.tr,
        middleTextStyle: AppStyle.title,
        confirm: MyElevatedButton(
          title: 'Ok'.tr,
          onPressed: () {
            Get.offAll(HomeCaptain());
          },
        ),
      );
    }
  }

  int rideTimerFromBegin = 0;
  double price = 0;
  void rideIsBeginPassengerTimer() async {
    // print('mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm');
    // print(durationOfRideValue);
    int durationOfRide = int.parse(durationOfRideValue);
    update();
    int infinity = 40000;
    if (carType == 'Comfort' || carType == 'Mashwari') {
      durationOfRide = infinity;
      update();
    }
    for (int i = 0; i <= durationOfRide; i++) {
      await Future.delayed(const Duration(seconds: 1));
      recentDistanceToDash = Get.find<LocationController>().totalDistance;
      rideTimerFromBegin = i;
      price = carType == 'Comfort' // || carType == 'Free Ride'
          ? (i ~/ 60) +
              (recentDistanceToDash *
                  Get.find<HomeCaptainController>().comfortPrice)
          : carType == 'Speed'
              ? (i ~/ 60) +
                  (recentDistanceToDash *
                      Get.find<HomeCaptainController>().speedPrice)
              : carType == 'Mashwari'
                  ? (i ~/ 60) +
                      (recentDistanceToDash *
                          Get.find<HomeCaptainController>().deliveryPrice)
                  : (i ~/ 60) +
                      (recentDistanceToDash *
                          Get.find<HomeCaptainController>()
                              .mashwariPrice); // $1 for each minute + $4 for each km
      price = (price * .10) + price; // Add 10% tax
      speed = Get.find<LocationController>().speed * 3.6;
      progressTimerRideBegin = i / durationOfRide;
      remainingTimeTimerRideBegin = durationOfRide - i;
      remainingTimeTimerRideBegin < 60 ? driverEndPage = 160 : 100;
      updateMarker();
      if (remainingTimeTimerRideBegin < 120) {
        // to make driver available on last 2 minute in his trip
        box.write(BoxName.statusDriverLocation, 'off');
      }
      int minutes = (remainingTimeTimerRideBegin / 60).floor();
      int seconds = remainingTimeTimerRideBegin % 60;
      stringRemainingTimeRideBegin =
          '$minutes:${seconds.toString().padLeft(2, '0')}';
      int minutes1 = (i / 60).floor();
      int seconds1 = i % 60;
      stringRemainingTimeRideBegin1 =
          '$minutes1:${seconds1.toString().padLeft(2, '0')}';
      update();
    }
  }

  double recentDistanceToDash = 0;
  double recentAngelToMarker = 0;
  double speed = 0;
  void updateMarker() async {
    // Remove the existing marker with the ID `MyLocation`.
    markers.remove(MarkerId('MyLocation'));

    // Add a new marker with the ID `MyLocation` at the current location of the user.
    LocationController locationController = Get.find<LocationController>();
    myLocation = locationController.myLocation;

    markers.add(
      Marker(
        markerId: MarkerId('MyLocation'.tr),
        position: myLocation,
        draggable: true,
        icon: carIcon,
        rotation: locationController.heading,
        // infoWindow: const InfoWindow(
        //   title: 'Time',
        // ),
      ),
    );

    // Animate camera only once after updating the marker
    // mapController!.animateCamera(
    //   CameraUpdate.newLatLng(myLocation),
    // );
    update();
  }

  void addCustomCarIcon() {
    ImageConfiguration config = ImageConfiguration(
        size: const Size(30, 30), devicePixelRatio: Get.pixelRatio
        // scale: 1.0,
        );
    BitmapDescriptor.fromAssetImage(config, 'assets/images/car.png',
            mipmaps: false)
        .then((value) {
      carIcon = value;
      update();
    });
  }

  void addCustomStartIcon() async {
// Create the marker with the resized image

    ImageConfiguration config = ImageConfiguration(
        size: const Size(30, 30), devicePixelRatio: Get.pixelRatio);
    BitmapDescriptor.fromAssetImage(config, 'assets/images/A.png',
            mipmaps: false)
        .then((value) {
      startIcon = value;
      update();
    });
  }

  void addCustomEndIcon() {
    ImageConfiguration config = ImageConfiguration(
        size: const Size(25, 25), devicePixelRatio: Get.pixelRatio);
    BitmapDescriptor.fromAssetImage(config, 'assets/images/b.png',
            mipmaps: false)
        .then((value) {
      endIcon = value;
      update();
    });
  }

  void addCustomPassengerIcon() {
    ImageConfiguration config = ImageConfiguration(
        size: const Size(30, 30), devicePixelRatio: Get.pixelRatio
        // scale: 1.0,
        );
    BitmapDescriptor.fromAssetImage(config, 'assets/images/picker.png',
            mipmaps: false)
        .then((value) {
      passengerIcon = value;
      update();
    });
  }

  double distanceBetweenDriverAndPassengerWhenConfirm = 0;
  getMap(String origin, destination) async {
    isLoading = false;

    update();

    var url =
        ('${AppLink.googleMapsLink}directions/json?&language=${box.read(BoxName.lang)}&avoid=tolls|ferries&destination=$destination&origin=$origin&key=${AK.mapAPIKEY}');

    var response = await CRUD().getGoogleApi(link: url, payload: {});
    data = response['routes'][0]['legs'];
    print(data);
    distanceBetweenDriverAndPassengerWhenConfirm =
        (data[0]['distance']['value']) / 1000;
    final points =
        decodePolyline(response["routes"][0]["overview_polyline"]["points"]);
    for (int i = 0; i < points.length; i++) {
      double lat = points[i][0].toDouble();
      double lng = points[i][1].toDouble();
      polylineCoordinates.add(LatLng(lat, lng));
    }
    if (polyLines.isNotEmpty) {
      clearPolyline();
      var polyline = Polyline(
        polylineId: PolylineId(response["routes"][0]["summary"]),
        points: polylineCoordinates,
        width: 10,
        color: AppColor.blueColor,
      );
      polyLines.add(polyline);
      // rideConfirm = false;
      update();
    } else {
      var polyline = Polyline(
        polylineId: PolylineId(response["routes"][0]["summary"]),
        points: polylineCoordinates,
        width: 10,
        color: AppColor.blueColor,
      );
      // final dataBounds = response["routes"][0]["bounds"];

      // updateCameraFromBoundsAfterGetMap(dataBounds);

// Fit the camera to the bounds

      polyLines.add(polyline);
      // rideConfirm = false;
      //  Define the northeast and southwest coordinates
      final bounds = response["routes"][0]["bounds"];
      LatLng northeast =
          LatLng(bounds['northeast']['lat'], bounds['northeast']['lng']);
      LatLng southwest =
          LatLng(bounds['southwest']['lat'], bounds['southwest']['lng']);

// Create the LatLngBounds object
      LatLngBounds boundsData =
          LatLngBounds(northeast: northeast, southwest: southwest);

// Fit the camera to the bounds
      var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData, 140);
      mapController!.animateCamera(cameraUpdate);
      update();
    }
  }

  getMapDestination(String origin, destination) async {
    var url =
        ('${AppLink.googleMapsLink}directions/json?&language=${box.read(BoxName.lang)}&avoid=tolls|ferries&destination=$destination&origin=$origin&key=${AK.mapAPIKEY}');

    var response = await CRUD().getGoogleApi(link: url, payload: {});
    dataDestination = response['routes'][0]['legs'];
    // print(data);
    final points =
        decodePolyline(response["routes"][0]["overview_polyline"]["points"]);
    for (int i = 0; i < points.length; i++) {
      double lat = points[i][0].toDouble();
      double lng = points[i][1].toDouble();
      polylineCoordinatesDestination.add(LatLng(lat, lng));
    }
    if (polyLinesDestination.isNotEmpty) {
      // clearPolyline();
      var polyline = Polyline(
        polylineId: PolylineId(response["routes"][0]["summary"]),
        points: polylineCoordinatesDestination,
        width: 10,
        color: AppColor.redColor,
      );
      polyLinesDestination.add(polyline);
      // rideConfirm = false;
      update();
    } else {
      var polyline = Polyline(
        polylineId: PolylineId(response["routes"][0]["summary"]),
        points: polylineCoordinatesDestination,
        width: 10,
        color: AppColor.redColor,
      );
      // final dataBounds = response["routes"][0]["bounds"];

      // updateCameraFromBoundsAfterGetMap(dataBounds);
      // polyLinesDestination.add(polyline);
      // rideConfirm = false;
      //  Define the northeast and southwest coordinates

      update();
    }
  }

  void updateCameraFromBoundsAfterGetMap(dynamic response) {
    final bounds = response["routes"][0]["bounds"];
    LatLng northeast =
        LatLng(bounds['northeast']['lat'], bounds['northeast']['lng']);
    LatLng southwest =
        LatLng(bounds['southwest']['lat'], bounds['southwest']['lng']);

// Create the LatLngBounds object
    LatLngBounds boundsData =
        LatLngBounds(northeast: northeast, southwest: southwest);

// Fit the camera to the bounds
    var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData, 140);
    mapController!.animateCamera(cameraUpdate);
  }

  void changePassengerInfoWindow() {
    isPassengerInfoWindow = !isPassengerInfoWindow;
    passengerInfoWindowHeight = isPassengerInfoWindow == true ? 200 : 0;
    update();
  }

  double mpg = 0;
  calculateConsumptionFuel() {
    mpg = Get.find<HomeCaptainController>().fuelPrice /
        12; //todo in register car add mpg in box
    update();
  }

  late Duration durationToAdd;
  int hours = 0;
  int minutes = 0;
  late String carType;
  late String kazan;
  @override
  void onInit() async {
    mapAPIKEY = await storage.read(key: BoxName.mapAPIKEY);
    // Get the passenger location from the arguments.
    passengerLocation = Get.arguments['passengerLocation'];
    passengerDestination = Get.arguments['passengerDestination'];
    duration = Get.arguments['Duration'];
    totalCost = Get.arguments['totalCost'];
    passengerId = Get.arguments['passengerId'];
    driverId = Get.arguments['driverId'];
    distance = Get.arguments['Distance'];
    passengerName = Get.arguments['name'];
    passengerEmail = Get.arguments['email'];
    totalPassenger = Get.arguments['totalPassenger'];
    passengerPhone = Get.arguments['phone'];
    walletChecked = Get.arguments['WalletChecked'];
    tokenPassenger = Get.arguments['tokenPassenger'];
    direction = Get.arguments['direction'];
    durationToPassenger = Get.arguments['DurationToPassenger'];
    rideId = Get.arguments['rideId'];
    durationOfRideValue = Get.arguments['durationOfRideValue'];
    paymentAmount = Get.arguments['paymentAmount'];
    paymentMethod = Get.arguments['paymentMethod'];
    isHaveSteps = Get.arguments['isHaveSteps'];
    step0 = Get.arguments['step0'];
    step1 = Get.arguments['step1'];
    step2 = Get.arguments['step2'];
    step3 = Get.arguments['step3'];
    step4 = Get.arguments['step4'];
    passengerWalletBurc = Get.arguments['passengerWalletBurc'];
    timeOfOrder = Get.arguments['timeOfOrder'];
    carType = Get.arguments['carType'];
    kazan = Get.arguments['kazan'];

    var coords = passengerLocation.split(',');
    var coordDestination = passengerDestination.split(',');

// Parse to double
    double latPassengerLocation = double.parse(coords[0]);
    double lngPassengerLocation = double.parse(coords[1]);
    double latPassengerDestination = double.parse(coordDestination[0]);
    double lngPassengerDestination = double.parse(coordDestination[1]);
    latLngpassengerLocation =
        LatLng(latPassengerLocation, lngPassengerLocation);
    latLngPassengerDestination =
        LatLng(latPassengerDestination, lngPassengerDestination);
    String lat = Get.find<LocationController>().myLocation.latitude.toString();
    String lng = Get.find<LocationController>().myLocation.longitude.toString();
    String origin = '$lat,$lng';
    // Set the origin and destination coordinates for the Google Maps directions request.
    getMap(origin, passengerLocation);
    isHaveSteps == 'haveSteps'
        ? (
            await getMapDestination(step0, step1),
            await getMapDestination(step1, step2),
            step3 == '' ? await getMapDestination(step2, step3) : () {},
            step4 == '' ? await getMapDestination(step3, step4) : () {},
          )
        : await getMapDestination(passengerLocation, passengerDestination);
    addCustomCarIcon();
    addCustomPassengerIcon();
    addCustomStartIcon();
    addCustomEndIcon();
    // updateMarker();
    // updateLocation();
    startTimerToShowPassengerInfoWindowFromDriver();
    durationToAdd = Duration(seconds: int.parse(duration));
    hours = durationToAdd.inHours;
    minutes = (durationToAdd.inMinutes % 60).round();
    calculateConsumptionFuel();
    // cancelCheckRidefromPassenger();
    // checkIsDriverNearPassenger();
    super.onInit();
  }
}
