import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:awesome_dialog/awesome_dialog.dart';
import 'package:flutter_expanded_tile/flutter_expanded_tile.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart'hide Response;
import 'package:flutter/material.dart' hide Notification;
import 'package:get/get.dart';
import 'package:gmaps_by_road_distance_calculator/gmaps_by_road_distance_calculator.dart';
import 'package:intl/intl.dart';

import 'package:rounded_loading_button_plus/rounded_loading_button.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../Data/Repository/Admintoken/Getadmintokenrepository.dart';
import '../../Data/Repository/CreateOrder/CreateOrderRepository.dart';
import '../../Data/Repository/Notification/Notificationrepository.dart';
import '../../Data/Repository/Tenantlocation/Getlocationrepository.dart';
import '../../Data/Repository/Tenantmodulecategory/Categoryrepository.dart';
import '../../Data/Repository/Tenantpricing/Tenantchargesrepository.dart';
import '../../Data/Repository/Tenants/Tenantsrepository.dart';
import '../../Globalwidgets/Googleplaces/Googleplaces.dart';
import '../../Helper/Constants/Colorconstants.dart';
import '../../Helper/Locationservice/app_config_service.dart';
import '../../Helper/Logger.dart';
import '../../Helper/customDio.dart';
import '../../Helper/location_service.dart';
import '../../Helper/toast.dart';
import '../../Model/Request/Createorder/Createorderrequest.dart';
import '../../Model/Request/Notification/Notificationrequest.dart';
import '../../Model/Response/Admintoken/Admintokenresponse.dart';
import '../../Model/Response/Appcategory/Appcategoryresponse.dart';
import '../../Model/Response/Createorder/CreateOrderResponsemodel.dart';
import '../../Model/Response/Notification/Notificationresponse.dart';
import '../../Model/Response/Tenantlocation/Getlocationbyidresponse.dart';
import '../../Model/Response/Tenantlocation/Locationbyid/Locationidresponse.dart';
import '../../Model/Response/Tenantpricing/Tenantpricingresponse.dart';
import '../../Model/Response/Tenants/Tenantinforesponse.dart';
import '../../View/Createorder/Createorderview.dart';
import '../../View/Createorder/Ordersuccess/Ordersuccessview.dart';
import '../../View/Home/Homeview.dart';
import '../Dashboard/Pickup/Tabs/Pickupcustomertabscontroller.dart';
import '../Tenantlocation/Tenantlocationcontroller.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
import '../../../Data/Repository/Location/GetLocation/getlocationrepository.dart' as TenantLocation;


class CreateOrderController extends GetxController{

  String? businessName;

  String tenantLocationName = "";
  // String? tLatitude;
  // String? tLongitude;
  // String? tAddress;

  String? tenantToken;
  String? notificationDate;


  String? subcategoryName = "";
  String? subCatName;


  String? pickUpCustomerName;
  String? pickUpCustomerContactNo;
  String? pickUpLandMark;
  String? pickUpDoorNo;

  String? pickUpCustomerContactNoCheck;
  String? dropCustomerContactNoCheck;


  FocusNode pickupFocusNode = FocusNode();


  String? dropCustomerName;
  String? dropCustomerContactNo;
  String? dropLandMark;
  String? dropDoorNo;

  TenantLocationDetails? selectedValue;




  List<String> adminToken = [];
  String? openTime;
  String? closeTime;

  String? fromAddress;
  String? toAddress;

  String? fromLatitude;
  String? fromLongitude;

  String? toLatitude;
  String? toLongitude;

  String? city;

  int? tenantId;
  int? moduleId;
  int? locationId;
  int? roleId;
  int? partnerId;
  int? appLocationId;
  int? configId;
  int? userId;
  int? appRadius;

  int? subCatId;
  int? subcategoryId;

  int? paymentType;

  int? pickupCustomerId;
  int? dropCustomerId;

  int? pickupLocationId;
  int? dropLocationId;

  int? pickupTenantLocationId;
  int? dropTenantLocationId;

  int catSelectedIndex = 0;

  int timeSelectIndex = -1;

  int paymentSelectedIndex = -1;

  int weightSelectedIndex = -1;

  int scheduleIndex = -1;

  bool pickupSaveAddress = false;
  bool dropSaveAddress = false;

  bool pikUpSaveChecking =false;
  bool dropSaveChecking =false;


  List <Applocationadmins> adminDetails = [];

  List<TenantLocationDetails> tenantLocations = [];

  List<String> timeSlots = [];
  List<String> timeSlotsnew = [];

  // List<AppCategoryDetails> subCategoryLists  = [];

  ByRoadDistanceCalculator byRoadDistanceCalculator = ByRoadDistanceCalculator();


  OrderResponseDetails deliveryDetails = OrderResponseDetails();

  PhoneNumber number = PhoneNumber(isoCode: 'IN',);


  final List weightRange = [
    {"weight":"1 - 10 Kg"},
    {"weight":"11 - 20 Kg"},
    {"weight":"21 - 30 Kg"},
  ];

  final List schedule = [
    {"scheduleType": "Now"},
    {"scheduleType": "Scheduled"}
  ];

  final List paymentMethod = [
    // {"Paymentmethod":"Pay now","icon":Icon(Icons.mobile_friendly,size: 35,color: ColorConstants.secondaryColor,)},
    {"Paymentmethod":"Pay on delivery","icon":Icon(Icons.currency_rupee,size: 35,color: ColorConstants.secondaryColor,)},
    {"Paymentmethod":"Pay later","icon":Icon(Icons.wallet,size: 35,color: ColorConstants.secondaryColor,)},
  ];

  TextEditingController tecNotes = TextEditingController();

  TextEditingController pickupContactNameController = TextEditingController();
  TextEditingController pickupContactNoController = TextEditingController();
  TextEditingController pickupDoorNoController = TextEditingController();
  TextEditingController pickupLandMarkController = TextEditingController();
  TextEditingController pickupAddressController =  TextEditingController();
  TextEditingController pickupStateController =  TextEditingController();
  TextEditingController pickupCityController =  TextEditingController();
  TextEditingController pickupSuburbController =  TextEditingController();
  TextEditingController pickupPostcodeController =  TextEditingController();


  TextEditingController dropContactNameController = TextEditingController();
  TextEditingController dropContactNoController = TextEditingController();
  TextEditingController dropLandMarkController = TextEditingController();
  TextEditingController dropDoorNoController = TextEditingController();
  TextEditingController dropAddressController =  TextEditingController();
  TextEditingController dropStateController =  TextEditingController();
  TextEditingController dropCityController =  TextEditingController();
  TextEditingController dropSuburbController =  TextEditingController();
  TextEditingController dropPostcodeController =  TextEditingController();


  TenantDetails tenantInfo = TenantDetails();


  bool loader = true;
  bool isNotes = false;
  bool smsSelected = false;




  double totalDeliveryAmount = 0.0;

  RxDouble distance = 0.0.obs;


  CustomDio mCustomDio = CustomDio();


  late Timer timer;


  var currentTime = DateTime.now().obs;
  var amPm = ''.obs;

  DateTime selectedDate = DateTime.now();
  DateTime datetime = DateTime.now();
  TimeOfDay selectedTime = TimeOfDay.now();

  DateTime? now;

  var orderId;

  var pickUpData;
  var dropData;

  var weight;
  var payment;


  var distanceKm;
  RxDouble distanceKms = 0.0.obs;

  var minKm;
  var basePrice;
  var pricePerKm;


  var scheduleType;

  //Current Location

  Position? resultPosition;

  var currentLat;
  var currentLong;

  var timers;

  //Autocomplete

  final pickupSearchText = ''.obs;
  final dropSearchText = ''.obs;
  final pickupPredictions = <Map<String, dynamic>>[].obs;
  final pickupSelectedPlace = {}.obs;
  final dropPredictions = <Map<String, dynamic>>[].obs;
  final dropSelectedPlace = {}.obs;
  final GooglePlacesService placesService = GooglePlacesService();

  final TextEditingController textEditingController = TextEditingController();



  final RoundedLoadingButtonController btnController = RoundedLoadingButtonController();
  final RoundedLoadingButtonController createBtnController = RoundedLoadingButtonController();


  GetLocationsRepository getLocationsRepository= GetLocationsRepository();
  TenantLocation.GetLocationsRepository getTenantLocationsRepository= TenantLocation.GetLocationsRepository();
  TenantRepository tenantInfoRepository = TenantRepository();
  GetTenantCategoriesRepository getTenantCategoriesRepository=  GetTenantCategoriesRepository();
  GetAdminTokenRepository getAdminTokenRepository = GetAdminTokenRepository();
  TenantPricingRepository tenantPricingRepository= TenantPricingRepository();
  CreateOrderRepository createOrderRepository = CreateOrderRepository();
  NotificationRepository notificationRepository = NotificationRepository();
  AppConfigurationService appConfigurationService = AppConfigurationService();


  ExpandedTileController pickupExpandedTileController = ExpandedTileController();
  ExpandedTileController dropExpandedTileController = ExpandedTileController();


  TenantLocationController tenantLocationController = Get.put(TenantLocationController());
  PickupCustomerTabController pickupCustomerTabController = Get.put(PickupCustomerTabController());

  get subCategoryLists => null;
  // PickupCustomerAddressController pickupCustomerAddressController = Get.put(PickupCustomerAddressController());


  getDetails()async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    locationId = prefs.getInt('locationId');
    print('getDetailslocationId $locationId');
  }

  void startTimer() {
    timer = Timer.periodic(Duration(seconds: 1), (_) {
      currentTime.value = DateTime.now();
      updateAmPm();
      update();
    });
  }

  void updateAmPm() {
    if (currentTime.value.hour >= 12) {
      amPm.value = 'PM';
    } else {
      amPm.value = 'AM';
    }
  }

  void main() {
    var min = 30;
    var currentDate =  selectedDate;
    String fromdate = DateFormat('yyyy-MM-dd').format(currentDate);
    print('fromdatesssssssss$fromdate');
    timeSlots.clear();
    var format = DateFormat("yyyy-MM-dd HH:mm:ss");
    var start = format.parse("$fromdate $openTime");
    var end = format.parse("$fromdate $closeTime");
    print('starttimesssssssssss$start');
    print('endtimesssssssssss$end');
    Duration step = Duration(minutes: int.parse(min.toString()));

    while(start.isBefore(end)) {
      var timeIncrement = start.add(step);
      timeSlots.add(DateFormat("yyyy-MM-dd HH:mm:ss").format(timeIncrement));
      start = timeIncrement;
    }

    timeSlotsnew.clear();
    for(int i=0;i<timeSlots.length;i++){
      var start1 = format.parse(timeSlots[i]);
      String endtime = DateFormat("yyyy-MM-dd HH:mm:ss").format(DateTime.now());
      var end1 = format.parse(endtime);
      if(start1.isAfter(end1)){
        timeSlotsnew.add(timeSlots[i]);
      }else{

      }
    }
    // timecal();
    print('timeSlots................ $timeSlots');
    print('timeSlots................ $timeSlots');
  }


  getLocation()async {
    // GetLocationById? result = await getLocationsRepository.getLocationById();
    SharedPreferences prefs = await SharedPreferences.getInstance();
    GetLocationByLocaionId? result = await getLocationsRepository.getLocationById();

    if (result?.code == 200) {
      print('tLatitudeinappbarcontrt${result?.details?.locationlatitude}');

      businessName =result?.details?.locationname;
      roleId = prefs.getInt('roleId');
      // openTime = result?.details?.opentime;
      // closeTime = result?.details?.closetime;
      // tLatitude = roleId == 1?tenantLocationController.latitude:result?.details?.locationlatitude;
      // tLongitude = roleId == 1?tenantLocationController.longitude:result?.details?.locationlong;
      // tAddress = roleId == 1?tenantLocationController.address:result?.details?.locationaddress;


      print('openTimessssssssssss$openTime');
      print('closeTimessssssssssss$closeTime');
    }
    print('resultgetLocation${result?.toJson()}');
  }




  //Get Current Location

  onSearchPickupTextChanged(String text) async {


    pickupSearchText.value = text;
    if (text.length > 2) {
      try {
        final places = await placesService.getPlacesPredictions(text);
        pickupPredictions.assignAll(places);
        update();

      } catch (e) {
        print('Error fetching predictions: $e');
      }
    } else {
      pickupPredictions.clear();
      update();

    }
  }



  onSearchDropTextChanged(String text) async {
    dropSearchText.value = text;
    if (text.length > 2) {
      try {
        final places = await placesService.getPlacesPredictions(text);
        // final places = await autocompletePlaces(text);
        dropPredictions.assignAll(places);
        update();

      } catch (e) {
        print('Error fetching predictions: $e');
      }
    } else {
      dropPredictions.clear();
      update();

    }
  }

  getPickupPlaceDetails(String placeId,locationAddress) async {
    try {
      final details = await placesService.getPlaceDetails(placeId);
      pickupSelectedPlace.value = details;
      print('getPlaceDetailslatitude ${pickupSelectedPlace['geometry']['location']['lat']}');
      print('getPlaceDetailslongitude ${pickupSelectedPlace['geometry']['location']['lng']}');
      getPickupAddressFromLatLng(pickupSelectedPlace['geometry']['location']['lat'],pickupSelectedPlace['geometry']['location']['lng'],locationAddress);
    } catch (e) {
      print('Error fetching place details: $e');
    }
  }

  getPickupAddressFromLatLng(double latitudes, double longitudes,locationAddress) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await placemarkFromCoordinates(latitudes, longitudes).then((List<Placemark> placemarks) {
      Placemark place = placemarks[0];
      pickupCityController.text = '${place.locality}' ?? '';
      pickupStateController.text = '${place.administrativeArea}' ?? '';
      pickupSuburbController.text = '${place.subLocality!.isNotEmpty?place.subLocality:place.street}';
      pickupPostcodeController.text ='${place.postalCode}' ?? '';
      pickupAddressController.text = locationAddress ?? '';
      fromAddress = pickupAddressController.text;
      fromLatitude = double.parse(latitudes.toString()).toString();
      fromLongitude = double.parse(longitudes.toString()).toString();
      pickupPredictions.clear();

      if(fromLatitude!= null&&fromLongitude!= null&&toLatitude!= null&&toLongitude != null){

        var distanceInMeters = calculateDistance(
          double.parse(toLatitude.toString()),
          double.parse(toLongitude.toString()),
          double.parse(fromLatitude.toString()),
          double.parse(fromLongitude.toString()),
        );

        distanceKm = distanceInMeters.round();

        print('distanceKmInPickupAppRadius $distanceKm');

        appRadius = prefs.getInt('appRadius')??0;
        logger.i(appRadius);
        if(appRadius != null &&distanceKm != null) {
          try {
            int appRadiusInt = int.parse(appRadius.toString());
            int distanceKmInt = int.parse(distanceKm);

            if(appRadiusInt <= distanceKmInt) {
              AwesomeDialog(
                context: Get.context!,
                dialogType: DialogType.warning,
               // animType: AnimType.BOTTOMSLIDE,
                descTextStyle: const TextStyle(fontSize: 16,),
                desc: 'Service not available at this location.',
                dismissOnTouchOutside: false,
                btnOkText: 'Ok',
                // btnCancelOnPress: () {
                //   Get.to(OrderDetails(data: data));
                // },
                btnOkOnPress: () async{
                  Get.to(()=>CreateOrderView(isDashboard: false,));
                },
              ).show();
            }
          } catch (e) {
            print("Error parsing integers: $e");
          }
        } else {
          print("One or both of the values are null.");
        }
      }

      update();


      print('latitude $fromLatitude');
      print('longitude $fromLongitude');

    }).catchError((e) {
      debugPrint(e);
    });
  }


  getDropPlaceDetails(String placeId,locationAddress) async {
    try {
      final details = await placesService.getPlaceDetails(placeId);
      dropSelectedPlace.value = details;
      print('getDropPlaceDetailslatitude ${dropSelectedPlace['geometry']['location']['lat']}');
      print('getDropPlaceDetailslongitude ${dropSelectedPlace['geometry']['location']['lng']}');
      getDropAddressFromLatLng(dropSelectedPlace['geometry']['location']['lat'],dropSelectedPlace['geometry']['location']['lng'],locationAddress);
    } catch (e) {
      print('Error fetching place details: $e');
    }
  }

  getDropAddressFromLatLng(double latitudes, double longitudes,locationAddress) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await placemarkFromCoordinates(latitudes, longitudes).then((List<Placemark> placemarks) {
      Placemark place = placemarks[0];
      dropCityController.text = '${place.locality}' ?? '';
      dropStateController.text = '${place.administrativeArea}' ?? '';
      dropSuburbController.text = '${place.subLocality!.isNotEmpty?place.subLocality:place.street}';
      dropPostcodeController.text ='${place.postalCode}' ?? '';
      dropAddressController.text = locationAddress ?? '';
      toAddress = dropAddressController.text;
      toLatitude = double.parse(latitudes.toString()).toString();
      toLongitude = double.parse(longitudes.toString()).toString();
      dropPredictions.clear();
      if(fromLatitude!= null&&fromLongitude!= null&&toLatitude!= null&&toLongitude != null){

        var distanceInMeters = calculateDistance(
          double.parse(toLatitude.toString()),
          double.parse(toLongitude.toString()),
          double.parse(fromLatitude.toString()),
          double.parse(fromLongitude.toString()),
        );

        distanceKm = distanceInMeters.round();

        print('distanceKmInAppRadius $distanceKm');


        appRadius = prefs.getInt('appRadius')??0;
        logger.i(appRadius);
        if(appRadius != 0 &&distanceKm != null) {
          try {
            int appRadiusInt = int.parse(appRadius.toString());
            int distanceKmInt = int.parse(distanceKm.toString());

            if(appRadiusInt <= distanceKmInt) {
              AwesomeDialog(
                context: Get.context!,
                dialogType: DialogType.warning,
               // animType: AnimType.BOTTOMSLIDE,
                descTextStyle: const TextStyle(fontSize: 16,),
                desc: 'Service not available at this location.',
                dismissOnTouchOutside: false,
                btnOkText: 'Ok',
                // btnCancelOnPress: () {
                //   Get.to(OrderDetails(data: data));
                // },
                btnOkOnPress: () async{
                  Get.to(()=>CreateOrderView(isDashboard: false,));
                },
              ).show();
            }
          } catch (e) {
            print("Error parsing integers: $e");
          }
        } else {
          print('appRadiusindrop $appRadius');
          print('distanceKmindrop $distanceKm');
          print("One or both of the values are null.");
        }

      }


      update();


      print('latitude $fromLatitude');
      print('longitude $fromLongitude');

    }).catchError((e) {
      debugPrint(e);
    });
  }

  getCurrentLocation()async{
    resultPosition = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    currentLat = resultPosition?.latitude.toString();
    currentLong = resultPosition?.longitude.toString();
    print('currentLatinlocation $currentLat');
    print('currentLonglocation $currentLong');
    getAddressFromLatLongs(double.parse(currentLat),double.parse(currentLong));
  }

  Future<void> getAddressFromLatLongs(double latitudes, double longitudes) async {
    print('getCurrentLocationAddressssssss');

    await placemarkFromCoordinates(
        latitudes, longitudes)
        .then((List<Placemark> placemarks) {
      Placemark place = placemarks[0];
      pickupCityController.text = place.locality ?? '';
      pickupStateController.text = place.administrativeArea ?? '';
      pickupSuburbController.text = '${place.subLocality??place.street}' ;
      pickupPostcodeController.text = place.postalCode ?? '';
      fromLatitude = double.parse(latitudes.toString()).toString();
      fromLongitude = double.parse(longitudes.toString()).toString();
      print('latitudegetAddressFromLatLng$fromLatitude');
      print('longitudegetAddressFromLatLng$fromLongitude');
      pickupAddressController.text  = '${place.street}, ${place.subLocality},${place.locality},${place.administrativeArea} ${place.subAdministrativeArea},${place.country},${place.postalCode}.';
      update();

    }).catchError((e) {
      debugPrint(e);
    });
  }



  getTenantInfo() async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    TenantInfo? result = await tenantInfoRepository.getTenantInfo();
    tenantInfo = result?.details??tenantInfo;
    subcategoryName = result?.details?.subcategoryname;
    subcategoryId = result?.details?.subcategoryid;
    paymentType = result?.details?.paymenttype;
    print('subcategoryNamegetTenantInfo $subcategoryName');
    print('paymentTypegetTenantInfo $paymentType');
    prefs.setInt('locationId', result?.details?.locationid ?? 0);
    loader = false;
    update();
    print('getTenantInfotenantInfo${tenantInfo.toString()}');
    print('getTenantInforesults${result?.toJson()}');

  }

  getTenantLocation() async{
    GetLocationByTenantId? result = await getTenantLocationsRepository.getLocationById();
    if(result?.status == true){
      tenantLocations = result?.details??[];
    }
  }

  // getTenantSubCategories() async{
  //   AppCategory? result = await getTenantCategoriesRepository.getTenantCategory();
  //   if(result?.status == true) {
  //     subCategoryLists = result?.details ?? [];
  //     update();
  //     print('subCategoryListssssssss${result?.details}');
  //
  //   }
  // }

  closeHandler() {
    Future.delayed(const Duration(milliseconds: 100), () {
      if (tecNotes.text.isEmpty)
        isNotes = true;
      else
        isNotes = false;
      Get.back();
      update();
    });
  }




  distanceCalculation()async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    double tenantLat = double.parse(fromLatitude.toString());
    double tenantLong = double.parse( fromLongitude.toString());
    print('tenantLatsssssss $tenantLat');
    print('tenantLongsssss $tenantLong');
    print('customerlatss $toLatitude');
    print('custometLongsss $toLongitude');
    // var distanceInMeters = calculateDistance(
    //     double.parse(toLatitude.toString()),
    //     double.parse(toLongitude.toString()),
    //     tenantLat,
    //     tenantLong
    // );
    // distanceKm = distanceInMeters.round();
    final pickupLat = double.tryParse(fromLatitude.toString());
    final pickupLong = double.tryParse(fromLongitude.toString());
    final dropLat = double.tryParse(toLatitude.toString());
    final dropLong = double.tryParse(toLongitude.toString());
    if (pickupLat != null && pickupLong != null && dropLat != null && dropLong != null) {
      calculateDistanceMatrix(pickupLat, pickupLong, dropLat, dropLong);
    } else {
      // Handle invalid input
      print('Invalid input');
    }

    // (double.parse(distanceInMeters.toInt().toStringAsFixed(0)) / 1000).round();
    print('distanceKmssssssssssssss $distanceKms');
    update();
  }

  void calculateDistanceMatrix(double pickupLat, double pickupLong, double dropLat, double dropLong) async {
    try {
      final distanceValue = await placesService.getDistance(pickupLat, pickupLong, dropLat, dropLong);
     var distanceMatrix = distanceValue.toStringAsFixed(1);
      distanceKms.value = double.parse(distanceMatrix.toString());
      print('distancecalculateDistanceMatrix $distanceKms');

    } catch (e) {
      print(e);
    }
  }


  double calculateDistance(double startLat, double startLon, double endLat, double endLon) {
    const double earthRadius = 6371; // Radius of the Earth in kilometers

    // Convert degrees to radians
    startLat = degreesToRadians(startLat);
    startLon = degreesToRadians(startLon);
    endLat = degreesToRadians(endLat);
    endLon = degreesToRadians(endLon);

    // Haversine formula
    final double dLat = endLat - startLat;
    final double dLon = endLon - startLon;
    final double a = pow(sin(dLat / 2), 2) +
        cos(startLat) * cos(endLat) * pow(sin(dLon / 2), 2);
    final double c = 2 * atan2(sqrt(a), sqrt(1 - a));

    // Calculate the distance
    final double distance = earthRadius * c;
    print('distanceinHaversine$distance');

    return distance;
  }

  double degreesToRadians(double degrees) {
    return degrees * (pi / 180);
  }


  getAdminToken()async{
    SharedPreferences prefs = await SharedPreferences.getInstance();

    GetAdminToken? result = await getAdminTokenRepository.getAdminToken();
    openTime = result?.details?.opentime;
    closeTime = result?.details?.closetime;

    prefs.setString('appLatitude', result?.details?.latitude ?? '');
    prefs.setString('appLongitude', result?.details?.longitude ?? '');
    prefs.setString('appLocation', result?.details?.locationname ?? '');
    prefs.setInt('appRadius', result?.details?.radius ?? 0);

    if(result?.status == true) {
      adminDetails = result?.details?.applocationadmins??[];
      adminToken.clear();
      for (var adminDetail in adminDetails) {
        adminToken.add(adminDetail.userfcmtokem??'');

      }


    }

    main();
    // List<String> parts = adminToken.split(', ');
    // List<String> wrappedParts = adminToken.map((part) => '["$part"]').toList();
    // String results = wrappedParts.join(', ');
    print('adminTokenssssssssssscreateorder $adminToken');

    print('applocationadminssssssssssss ${adminToken.length}');
    print('openTimesssssssssss $openTime');
    print('closeTimessssssssss $closeTime');
  }


  getTenantPricing()async{
    GetTenantPricing? result = await tenantPricingRepository.getTenantPricing();
    print('getthirdPartyChargesresult${result?.toJson()}');
    getTenantPricingResult(result!);
    update();
  }

  getTenantPricingResult(GetTenantPricing data){
    if(data.code == 200){
      basePrice = data.details?.baseprice??0;
      pricePerKm = data.details?.priceperkm??0;
      minKm = data.details?.minkm??0;
      // calculateCharges();
      update();
      print('tenantpricingpriceperkm$pricePerKm');
      print('tenantpricingbaseprice$basePrice');
      print('tenantpricingminKm $minKm');
    }
  }

  calculateCharges()async{
    double tenantLat = double.parse(fromLatitude.toString());
    double tenantLong = double.parse( fromLongitude.toString());
    print('tenantLongsssssss $tenantLong');
    // var distanceInMeters =  calculateDistance(
    //     double.parse(toLatitude.toString()),
    //     double.parse(toLongitude.toString()),
    //     tenantLat,
    //     tenantLong
    // );

    final pickupLat = double.tryParse(fromLatitude.toString());
    final pickupLong = double.tryParse(fromLongitude.toString());
    final dropLat = double.tryParse(toLatitude.toString());
    final dropLong = double.tryParse(toLongitude.toString());
    final distanceValue = await placesService.getDistance(pickupLat??0.0, pickupLong??0.0, dropLat??0.0, dropLong??0.0);
    var distanceMatrix = distanceValue.toStringAsFixed(1);
    distanceKms.value = double.parse(distanceMatrix.toString());

    // (double.parse(distanceInMeters.toInt().toStringAsFixed(0)) / 1000).round();

    // var dis = (double.parse(distanceInMeters.toInt().toStringAsFixed(0)));
    // var distance = distanceInMeters.round();
    print('distancessssssssssssss ${distanceKms.value}');
    print('minKmssssssssssssss$minKm');

    // thirdPartyCharges.forEach((element) {
    //    print('forEachthirdPartyCharges');
    //    print(element.priceperkm);});
    if (distanceKms < minKm) {
      // double distokm = double.parse(thirdPartyCharges[0].baseprice.toString());
      double distokm = double.parse(basePrice.toString());
      totalDeliveryAmount = double.parse(distokm.round().toString());
      update();
      print("asdfasdfasdfdsaf==0_________$totalDeliveryAmount");
    } else {
      double totaldistance = distanceKms.value - double.parse(minKm.toString());
      double distokm = totaldistance *
          // double.parse(thirdPartyCharges[0].priceperkm.toString())+
          // double.parse(thirdPartyCharges[0].baseprice.toString());
          double.parse(pricePerKm.toString())+
          double.parse(basePrice.toString());
      totalDeliveryAmount =  double.parse(distokm.round().toString());
      update();
      print("oskdoksodksodksokdoskdoskdoskd $totalDeliveryAmount");
    }
  }


  describeValidation() async{
    print('scheduleTypedescribeValidation $scheduleType');
    print('describeValidationlocationId $locationId');

    if(pickupAddressController.text.isEmpty){
      btnController.reset();
      Toast.showToast('Pickup address should not be empty');
    }
    else if(pickupContactNameController.text.isEmpty){
      btnController.reset();
      Toast.showToast('Pickup customer name should not be empty');
    }
    // else if(pickupContactNameController.text.length!=3){
    //   btnController.reset();
    //   Toast.showToast('Pickup customer name should be minimum 3 characters required');
    // }
    else if(pickupContactNoController.text.isEmpty){
      btnController.reset();
      Toast.showToast('Pickup customer no should not be empty');
    }
    else if(pickupContactNoController.text.length!=10){
      btnController.reset();
      Toast.showToast('Please enter correct pickup customer no');
    }
    else if(dropAddressController.text.isEmpty){
      btnController.reset();
      Toast.showToast('Drop address should not be empty');
    }
    else if(dropContactNameController.text.isEmpty){
      btnController.reset();
      Toast.showToast('Drop customer name should not be empty');
    }
    // else if(dropContactNameController.text.length!=3){
    //   btnController.reset();
    //   Toast.showToast('Drop customer name should be minimum 3 characters required');
    // }
    else if(dropContactNoController.text.isEmpty){
      btnController.reset();
      Toast.showToast('Drop customer no should not be empty');
    }
    else if(dropContactNoController.text.length!=10){
      btnController.reset();
      Toast.showToast('Please enter correct drop customer no');
    }

    else if(scheduleType == null){
      btnController.reset();
      Toast.showToast('Pickup time should not be empty');
    }
    else if(weight==null){
      btnController.reset();
      // print('eeeeeeeeeeeeee');
      Toast.showToast('Please add weight');
    }
    else if(locationId == null){
      btnController.reset();
      Toast.showToast('Please select business location');
    }
    // else if(subCatId==null){
    //   Toast.showToast('Item should not be empty ');
    // }
    // else if(payment==null){
    //   btnController.reset();
    //   Toast.showToast('Please select payment method');
    // }


    else {
      print("OrderSuccessView else");
      btnController.reset();

      if(fromLatitude!= null&&fromLongitude!= null&&toLatitude!= null&&toLongitude != null){

        SharedPreferences prefs = await SharedPreferences.getInstance();

        var distanceInMeters = calculateDistance(
          double.parse(toLatitude.toString()),
          double.parse(toLongitude.toString()),
          double.parse(fromLatitude.toString()),
          double.parse(fromLongitude.toString()),
        );

        distanceKm = distanceInMeters.round();

        print('distanceKmInCreateOrder $distanceKm');


        appRadius = prefs.getInt('appRadius')??0;
        logger.i(appRadius);
        if(appRadius != 0 &&distanceKm != null) {
          try {
            int appRadiusInt = int.parse(appRadius.toString());
            int distanceKmInt = int.parse(distanceKm.toString());

            if(appRadiusInt <= distanceKmInt) {
              AwesomeDialog(
                context: Get.context!,
                dialogType: DialogType.warning,
                // animType: AnimType.BOTTOMSLIDE,
                descTextStyle: const TextStyle(fontSize: 16,),
                desc: 'Service not available at this location',
                dismissOnTouchOutside: false,
                btnOkText: 'Ok',
                // btnCancelOnPress: () {
                //   Get.to(OrderDetails(data: data));
                // },
                btnOkOnPress: () async{
                  Get.to(()=>CreateOrderView(isDashboard: false,));
                },
              ).show();
            }
            else{
              var orderdate = DateFormat("yyyy-MM-dd HH:mm:ss").format(
                  DateFormat("yyyy-MM-dd HH:mm:ss").parse(datetime.toString()));

              deliveryDetails =
                  OrderResponseDetails(
                    pickuplat: "$fromLatitude",
                    pickuplong: "$fromLongitude",
                    deliverylat: "$toLatitude",
                    deliverylong: "$toLongitude",
                    orderdate: "$orderdate",
                    deliverydate: "$orderdate",
                    pickupcustomer: "$pickUpCustomerName",
                    pickupsuburb: "${pickupSuburbController.text}",
                    deliverycustomer: "$dropCustomerName",
                    deliverysuburb: "${dropSuburbController.text}",
                  );
              btnController.success();
              Get.to(OrderSuccessView(orderResponseDetails: deliveryDetails,));
              btnController.reset();


              // createOrder();
            }

          } catch (e) {
            print("Error parsing integers: $e");
          }
        } else {
          print('appRadiusindrop $appRadius');
          print('distanceKmindrop $distanceKm');
          print("One or both of the values are null.");
        }
        print("location distance");
        btnController.reset();
      }



      // createOrder();

    }
  }

  orderCreateDescribeValidation(){
    if(paymentType !=0) {
      if (payment == null) {
        createBtnController.reset();
        Toast.showToast('Please select payment method');
      }
      else {
        createOrder();
      }
    }
    else {
      createOrder();
    }
  }

  createOrder()async{
    // var orderdate = DateFormat("yyyy-MM-dd HH:mm:ss").format(DateTime.now());
    // var deliverydate = DateFormat("yyyy-MM-dd HH:mm:ss").format(DateTime.now());
    var orderdate =  DateFormat("yyyy-MM-dd HH:mm:ss").format(DateFormat("yyyy-MM-dd HH:mm:ss").parse(datetime.toString()));
    var deliverytime =  DateFormat("yyyy-MM-dd HH:mm:ss").format(DateFormat("yyyy-MM-dd HH:mm:ss").parse(datetime.toString()));
    print('createOrderorderdate$orderdate');
    print('createOrderdeliverydate$deliverytime');
    print('createOrderdatetime$datetime');
    SharedPreferences prefs = await SharedPreferences.getInstance();
    tenantId = prefs.getInt('tenantId');
    moduleId = prefs.getInt('moduleId');
    roleId = prefs.getInt('roleId');
    partnerId = prefs.getInt('partnerId');
    appLocationId = prefs.getInt('appLocationId');
    configId = prefs.getInt('configId');
    userId = prefs.getInt('userId');

    print('moduleIdcreateOrder $moduleId');
    print('userIdcreateOrder $userId');
    print('distanceKmssssscreateOrder ${ distanceKm.toString()}');
    print('deviceTypetabIndex ${pickupCustomerTabController.tabIndex}');

    create(
      CreateOrder(
        orders:Orders(
            orderheaderid: 0,
            tenantid: tenantId,
            applocationid: appLocationId,
            locationid: locationId??0,
            // locationid: pickupTenantLocationId==0?dropTenantLocationId??0:pickupTenantLocationId??0,
            moduleid: moduleId,
            categoryid: 6,
            subcategoryid: subcategoryId,
            configid: configId,
            orderid: "",
            orderdate: "$orderdate",
            deliverytime: "$deliverytime",
            deliverytype:"${pickupTenantLocationId!=0 || dropTenantLocationId != 0 ?'B':'C'}",
            orderstatus: "created",
            pending: "",
            processing: "",
            ready: "",
            delivered: "",
            cancellled: "",
            customerid: pikUpSaveChecking?0:pickupCustomerId??0,
            pickupcustomer: "${pickupContactNameController.text}",
            pickupcontactno: "${pickupContactNoController.text}",
            pickuplandmark: "${pickupLandMarkController.text}",
            pickuplocation: "${pickupSuburbController.text}",
            pickupcity: "${pickupCityController.text}",
            pickuplocationid: pickupLocationId??0,
            pickupaddress: "${pickupAddressController.text}",
            pickuplat: "$fromLatitude",
            pickuplong: "$fromLongitude",
            deliveryid: dropSaveChecking?0:dropCustomerId??0,
            deliverycustomer: "${dropContactNameController.text}",
            deliverycontactno: "${dropContactNoController.text}",
            deliverylocationid: dropLocationId??0,
            deliverylat: "$toLatitude",
            deliverylong: "$toLongitude",
            deliveryaddress: "${dropAddressController.text}",
            deliverylandmark: "${dropLandMarkController.text}",
            deliverylocation: "${dropSuburbController.text}",
            deliverycity: "${dropCityController.text}",
            orderamount: totalDeliveryAmount,
            taxamount: 0.0,
            ordercharges: 0.0,
            ordervalue: totalDeliveryAmount,
            itemcount: 1,
            paymenttype: paymentSelectedIndex==0?43:64,
            paymentstatus: paymentSelectedIndex==0?0:2,
            deliverycharge: totalDeliveryAmount,
            ordernotes: dropDoorNoController.text.isNotEmpty?"${dropDoorNoController.text} ${tecNotes.text}":tecNotes.text,
            kms:distanceKms.toString(),
            smsdelivery: smsSelected == true?1:0,
            remarks: "",
            tenantuserid: userId,
            partneruserid: 0,
            partnerid: partnerId
        ),
        pickup: Pickup(
            customerid: pikUpSaveChecking?0:pickupCustomerId??0,
            configid: configId,
            locationid: pickupLocationId??0,
            firstname: "${pickupContactNameController.text}",
            applocationid: appLocationId,
            profileimage: "",
            dialcode: "+91",
            contactno: "${pickupContactNoController.text}",
            devicetype: "",
            deviceid: "",
            customertoken: "",
            address: "${pickupAddressController.text}",
            suburb: "${pickupSuburbController.text}",
            city: "${pickupCityController.text}",
            state: "${pickupStateController.text}",
            postcode: "${pickupPostcodeController.text}",
            landmark: "${pickupLandMarkController.text}",
            doorno: "${pickupDoorNoController.text}",
            latitude: "$fromLatitude",
            longitude: "$fromLongitude",
            tenantid: tenantId,
            email: "",
            primaryaddress: pickupCustomerId==0?1:0
        ),
        drop: Drop(
            customerid: dropSaveChecking?0:dropCustomerId??0,
            configid: configId,
            locationid: dropLocationId??0,
            firstname: "${dropContactNameController.text}",
            applocationid: appLocationId,
            profileimage: "",
            dialcode: "+91",
            contactno: "${dropContactNoController.text}",
            devicetype: "",
            deviceid: "",
            customertoken: "",
            address: "${dropAddressController.text}",
            suburb: "${dropSuburbController.text}",
            city: "${dropCityController.text}",
            state: "${dropStateController.text}",
            postcode: "${dropPostcodeController.text}",
            landmark: "${dropLandMarkController.text}",
            doorno: "${dropDoorNoController.text}",
            latitude: "$toLatitude",
            longitude: "$toLongitude",
            tenantid: tenantId,
            email: "",
            primaryaddress: dropCustomerId==0?1:0
        ),
      ),
    );
  }

  create(CreateOrder data) async {
    CreateOrderResponse? result = await createOrderRepository.createOrder(data);
    print('CreateOrderresultincontroller${result?.toJson()}');
    SharedPreferences prefs = await SharedPreferences.getInstance();
    // orderId = result.details?.orderid;
    // prefs.setString('orderId',result?.details?.orderid??'');
    // print('orderIdincreate${prefs.getString('orderId')}');
    // orderId = result?.details?.orderid;
    print("paymentSelectedIndex$paymentSelectedIndex");

    // if(paymentSelectedIndex ==0){
    //   print("paynow.............");
    //   paymentSelectedIndex = -1;
    //   timeSelectIndex = -1;
    //   btnController.reset();
    //   razorPayOrder(result!);
    //
    // }else{
    if(result?.status == true){
      print("cod..............");
      weightSelectedIndex = -1;
      paymentSelectedIndex = -1;
      timeSelectIndex = -1;
      smsSelected = false;
      pickupContactNameController.clear();
      pickupContactNoController.clear();
      pickupAddressController.clear();
      pickupSuburbController.clear();
      pickupLandMarkController.clear();
      pickupCityController.clear();
      pickupStateController.clear();
      pickupPostcodeController.clear();
      pickupDoorNoController.clear();
      pikUpSaveChecking = false;

      dropContactNameController.clear();
      dropContactNoController.clear();
      dropAddressController.clear();
      dropSuburbController.clear();
      dropLandMarkController.clear();
      dropCityController.clear();
      dropStateController.clear();
      dropPostcodeController.clear();
      dropDoorNoController.clear();
      tenantLocationName = '';
      locationId = null;
      pickupCustomerId = null;
      dropCustomerId = null;
      dropSaveChecking = false;

      btnController.reset();
      Get.to(()=>HomeView(selectedIndex: 0));
      // Get.to(OrderSuccessView(orderResponseDetails: result!.details!,));
    }
    else{
      Toast.showToast('${result?.message}');
      btnController.reset();
    }


    // }

    createOrderNotification(result!);

    weight = null;
    // datetime = "";
    // subCatName = null;
    tecNotes.clear();
    payment =null;
    // dashboardController.getCustomerByTenantId();
    update();
  }

  createOrderNotification(CreateOrderResponse datas) async {
    print('createOrderNotificationordersssssss');
    print('adminTokencreateOrderNotification$adminToken');
    SharedPreferences prefs = await SharedPreferences.getInstance();
    tenantToken = prefs.getString('tenantToken');
    now = DateTime.now();


    createOrderNotificationResult(
      NotificationRequest(
          data: Data(
            accessid: 'AAAAILMpCEU:APA91bEavuOllBI6sFgYtxXAgNmAVwNA-MnCMHLGlR4_t7UqpLajAkdn3T0CZr_zaLBknLyim9ytFLMZgbeXmKqTad_PKCbqlYjHpaizVrLXtecxqyEy4UktIacK2UvHVUATHL-7VQQk',
          ),
          priority: "high",
          registrationIds:adminToken,
          // sender: 'Nearlexpress Business',
          notification: Notification(
              title:"Nearlexpress Business",
              body:"An order has been created. kindly process the delivery.",
              sound:"ring"
          )
      ),
    );
  }

  createOrderNotificationResult(NotificationRequest data)async{
    NotificationResponse? result = await notificationRepository.createNotification(data);
    if(result?.status == true){
    }
  }


  @override
  void onInit() {
    pickupExpandedTileController = ExpandedTileController(isExpanded:pickupPredictions.isNotEmpty?false:true);
    dropExpandedTileController = ExpandedTileController(isExpanded:false);

    // TODO: implement onInit
    super.onInit();
  }
  @override
  void dispose() {
    textEditingController.dispose();
    super.dispose();
  }

}