import 'package:country_currency_pickers/country.dart';
import 'package:country_currency_pickers/utils/utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart' hide Response;

import 'package:rounded_loading_button_plus/rounded_loading_button.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../../../../Data/Repository/Applocation/Applocationrepository.dart';
import '../../../../Data/Repository/Location/Addlocation/Addlocationrepository.dart';
import '../../../../Data/Repository/Location/Updatelocation/Updatelocationrepository.dart';
import '../../../../Globalwidgets/Googleplaces/Googleplaces.dart';
import '../../../../Helper/Constants/Apiconstants.dart';
import '../../../../Helper/Constants/Colorconstants.dart';
import '../../../../Helper/Locationservice/Locationservice.dart';
import '../../../../Helper/location_service.dart';
import '../../../../Helper/toast.dart';
import '../../../../Model/Request/Location/Addlocation/Addlocationrequest.dart';
import '../../../../Model/Request/Location/Updatelocation/Updatelocationrequest.dart';
import '../../../../Model/Response/Applocations/Applocationresponse.dart';
import '../../../../Model/Response/Location/Addlocation/Addlocationresponse.dart';
import '../../../../Model/Response/Location/Updatelocation/Updatelocationresponse.dart';
import '../../../../Model/Response/Tenantlocation/Getlocationbyidresponse.dart';
import '../../../../View/More/Locations/Locationview.dart';

class AddLocationController extends GetxController{

  String? dialCode;
  String? googleApiKey;
  String? initialCountry;
  String? addressField;
  String? latitude;
  String? longitude;
  String? city;
  String? state;
  String? suburb;
  String appLocationName = '';


  String? min1Label;
  String? min2Label;
  String? min3Label;

  String describeAddLocationUrl = '${ApiConstants.describeUrl}/9/en_us';


  int deliveryMin = 30;
  int cancellationSec = 20;

  int appLocationId = 0;
  int? moduleId;
  int? locationId;


  bool sec1 = true;
  bool sec2 = false;
  bool sec3 = false;

  bool min1 = true;
  bool min2 = false;
  bool min3 = false;

  bool editMode = false;
  bool shimmer = true;
  bool isEnterAddress = false;
  bool progress = false;


  List<AppLocationDetails> locations = [];

  Position? resultPosition;

  Country selectedDialogCountry = CountryPickerUtils.getCountryByIsoCode('IN');

  final RoundedLoadingButtonController btnController = RoundedLoadingButtonController();


  TenantLocationDetails? locationInfo;


  var describeValue;

  final searchText = ''.obs;
  final predictions = <Map<String, dynamic>>[].obs;
  final selectedPlace = {}.obs;

  final GooglePlacesService placesService = GooglePlacesService();

  LocationService locationService = LocationService();


  AppLocationRepository appLocationRepository = AppLocationRepository();

  final GlobalKey<State> _keyLoader = new GlobalKey<State>();


  TextEditingController nameController = TextEditingController();
  TextEditingController emailController = TextEditingController();
  TextEditingController addressController = TextEditingController();
  TextEditingController phoneNoController = TextEditingController();
  TextEditingController postalCodeController = TextEditingController();
  TextEditingController stateController = new TextEditingController();
  TextEditingController cityController = new TextEditingController();
  TextEditingController suburbController = new TextEditingController();

  UpdateLocationRepository updateLocationRepository = UpdateLocationRepository();
  AddLocationRepository addLocationRepository = AddLocationRepository();



  onSearchTextChanged(String text) async {
    searchText.value = text;
    if (text.length > 2) {
      try {
        final places = await placesService.getPlacesPredictions(text);
        predictions.assignAll(places);
        update();

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

    }
  }

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

  getAddressFromLatLng(double latitudes, double longitudes,locationAddress) async {
    await placemarkFromCoordinates(latitudes, longitudes).then((List<Placemark> placemarks) {
      Placemark place = placemarks[0];
      latitude = double.parse(latitudes.toString()).toString();
      longitude = double.parse(longitudes.toString()).toString();
      city  = '${place.locality}';
      cityController.text  = '${place.locality}';
      stateController.text    = '${place.administrativeArea}';
      state  = '${place.administrativeArea}';
      suburbController.text = "${place.subLocality!.isNotEmpty?place.subLocality:place.street}" ;
      suburb  = place.subLocality!.isNotEmpty?place.subLocality:place.street;
      postalCodeController.text  = '${place.postalCode}';
      addressController.text = locationAddress??'${place.street}, ${place.subLocality},${place.locality},${place.administrativeArea} ${place.subAdministrativeArea},${place.country},${place.postalCode}.';
      isEnterAddress = true;

      // address = locationAddress??'${place.street}, ${place.subLocality},${place.locality},${place.administrativeArea} ${place.subAdministrativeArea},${place.country},${place.postalCode}.';
      predictions.clear();
      update();



      print('latitude $latitude');
      print('longitude $longitude');
      print('currentLocationSuburb $suburb');
      print('city $city');
      print('state $state');
      print('postalCode ${postalCodeController.text}');
    }).catchError((e) {
      debugPrint(e);
    });
  }


  getAppLocations() async{
    GetAppLocations? result = await appLocationRepository.getAppLocations();
    if(result?.code == 200){
      locations = result?.details??[];
      shimmer = false;
      setValues();
      update();
    }
    else{
      Toast.showToast("${result?.message}");

    }

  }

  setValues() {
    print('setValueseditMode $editMode');
    // print('addlocationnamesssssss${locationInfo['locationName']}');
    if (editMode) {
      locationInfo = locationInfo;

      // print(locationInfo);
      locationId = locationInfo?.locationid;
      nameController.text = locationInfo?.locationname??'';
      emailController.text = locationInfo?.locationemail??'';
      addressController.text = locationInfo?.locationaddress??'';
      postalCodeController.text = locationInfo?.locationpostcode??'';
      suburb = locationInfo?.locationsuburb??'';
      suburbController.text = locationInfo?.locationsuburb??'';
      cityController.text = locationInfo?.locationcity??'';
      city = locationInfo?.locationcity??'';
      // print('${locationInfo['openingtime'].toString()}open time');

      state = locationInfo?.locationstate??'';
      stateController.text = locationInfo?.locationstate??'';
      latitude = locationInfo?.locationlatitude??'';
      longitude = locationInfo?.locationlong??'';

      // countryCode = locationInfo['countrycode'];

      phoneNoController.text = locationInfo?.locationcontact??'';
      // delivery = locationInfo['delivery'];
      // deliveryCharges = locationInfo['deliverycharges'] ?? [];
      cancellationSec = locationInfo?.cancelsecs??0;
      deliveryMin = locationInfo?.deliverymins??0;
      // deliveryType = locationInfo['deliverytype'];


      if (deliveryMin == 30) {
        min1 = true;
        min2 = false;
        min3 = false;
      } else if (deliveryMin == 60) {
        min1 = false;
        min2 = true;
        min3 = false;
      } else if (deliveryMin == 120) {
        min1 = false;
        min2 = false;
        min3 = true;
      }

      if (cancellationSec == 20) {
        sec1 = true;
        sec2 = false;
        sec3 = false;
      } else if (cancellationSec == 30) {
        sec1 = false;
        sec2 = true;
        sec3 = false;
      } else if (cancellationSec == 40) {
        sec1 = false;
        sec2 = false;
        sec3 = true;
      }
      appLocationId = locationInfo?.applocationid??0;
      for (var loc in locations) {
        if (loc.applocationid == appLocationId) {
          appLocationName = loc.city??'';
          return;
        }
      }
      update();

    }
  }


  describeValidation() {
    if (nameController.text.isEmpty) {
      btnController.reset();
      Toast.showToast("Please enter location name");
    } else if (emailController.text.isEmpty) {
      btnController.reset();
      // Toast.showToast("Please enter email");
      Toast.showToast("Please enter email");
    } else if (RegExp(
        r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
        .hasMatch(emailController.text) ==
        false) {
      btnController.reset();
      // Toast.showToast("Enter valid email");
      Toast.showToast("Enter valid email");
    } else if (phoneNoController.text.isEmpty) {
      btnController.reset();
      Toast.showToast("Please enter contact no");
    }
    else if (phoneNoController.text.length !=10) {
      btnController.reset();
      Toast.showToast("Incorrect contact no");
    }
    // else if (appLocationId == 0) {
    //   Toast.showToast("Please select your location");
    //   progress = true;
    //   update();
    //
    // }
    else if (addressController.text.isEmpty) {
      btnController.reset();
      Toast.showToast("Please enter your location");
    } else if (suburbController.text.isEmpty) {
      btnController.reset();
      isEnterAddress = true;
      update();
      Toast.showToast("Please enter suburb");
    } else if (cityController.text.isEmpty) {
      btnController.reset();
      isEnterAddress = true;
      update();
      Toast.showToast("Please enter city");
    }
    // else if (city.toString().toLowerCase() !=
    //     appLocationName.toString().toLowerCase()) {
    //
    //   setState(() {
    //     isEnterAddress = true;
    //   });
    //   Toast.showToast(
    //       "Entered address and selected location varies please enter correct location");
    // }
    else if (stateController.text.isEmpty) {
      isEnterAddress = true;
      update();
      Toast.showToast("Please enter state");
    } else if (postalCodeController.text.isEmpty) {
      Toast.showToast("Please enter postcode");
    }
    // else if (deliveryMin == 0) {
    //   Toast.showToast("Please select delivery mins ");
    // }
    else {
      if (editMode == false) {
        progress = true;
        update();
        addLocation();
      }
      else {
        updateLocation();
      }
    }
  }

  Future<void> showLoader(BuildContext context, GlobalKey key) async {
    return showDialog<void>(

      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return SimpleDialog(
            backgroundColor: Colors.white,

            key: key,
            // title: Text('Warning'),
            children: [
              Center(
                child: Column(children: [
                  CircularProgressIndicator(color: ColorConstants.primaryColor),
                  SizedBox(
                    height: 10,
                  ),
                  Text(
                    "Please wait....",
                    style: TextStyle(color: ColorConstants.primaryColor),
                  )
                ]),
              )
            ]);
      },
    );
  }

  addLocation()async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var tenantId = prefs.getInt('tenantId');
    var moduleId = prefs.getInt('moduleId');
    var appLocationId = prefs.getInt('appLocationId');
    var partnerId = prefs.getInt('partnerId');
    addLocationResult(
        AddLocation(
            locationid:0,
            tenantid:tenantId,
            moduleid:moduleId,
            applocationid:appLocationId,
            locationname:"${nameController.text}",
            email:"${emailController.text}",
            contactno:"${phoneNoController.text}",
            address:"${addressController.text}",
            suburb:"${suburbController.text}",
            state:"${stateController.text}",
            city:"${cityController.text}",
            postcode:"${postalCodeController.text}",
            latitude:"$latitude",
            longitude:"$longitude",
            partnerid:partnerId,
            opentime:"9:00",
            closetime:"21:00",
            deliverytype:0,
            deliverymins:60,
            cancelsecs:20
        )
    );


  }
  addLocationResult(AddLocation data)async{
    AddLocationResponse? result = await addLocationRepository.addLocation(data);
    if(result?.status == true){
      locationId = 0;
      nameController.clear();
      emailController.clear();
      addressController.clear();
      postalCodeController.clear();
      suburb = '';
      suburbController.clear();
      cityController.clear();
      city = '';
      state = '';
      stateController.clear();
      latitude = '';
      longitude = '';
      phoneNoController.clear();
      isEnterAddress = false;
      Get.to(()=>LocationView());
    }
    else{
      Toast.showToast('Something went wrong');
    }

  }


  updateLocation()async{
    updateLocationResult(
        UpdateLocation(
            locationid:locationInfo?.locationid??0,
            tenantid:locationInfo?.tenantid??0,
            moduleid:locationInfo?.moduleid??0,
            applocationid:locationInfo?.applocationid??0,
            locationname:"${nameController.text}",
            email:"${emailController.text}",
            contactno:"${phoneNoController.text}",
            address:"${addressController.text}",
            suburb:"${suburbController.text}",
            state:"${stateController.text}",
            city:"${cityController.text}",
            postcode:"${postalCodeController.text}",
            latitude:"$latitude",
            longitude:"$longitude",
            partnerid:locationInfo?.partnerid??0,
            opentime:"9:00",
            closetime:"21:00",
            deliverytype:0,
            deliverymins:60,
            cancelsecs:20
        )

    );
  }
  updateLocationResult(UpdateLocation data)async{
    UpdateLocationResponse? result = await updateLocationRepository.updateLocation(data);
    if(result?.status == true){
      Get.to(()=>LocationView());

    }

  }

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