// import 'dart:async'; // import 'dart:io'; // import 'dart:ui' as ui; // // import 'package:flutter/cupertino.dart'; // import 'package:flutter/foundation.dart'; // import 'package:flutter/material.dart'; // import 'package:flutter/services.dart'; // import 'package:generp/Notifiers/HomeScreenNotifier.dart'; // import 'package:generp/screens/crm/LeadDetailsByMode.dart'; // import 'package:generp/screens/genTracker/GeneratorDetails.dart'; // import 'package:generp/services/api_calling.dart'; // import 'package:geolocator/geolocator.dart'; // import 'package:google_maps_flutter/google_maps_flutter.dart'; // import 'package:image_picker/image_picker.dart'; // import 'package:geocoding/geocoding.dart' as geocoding; // import 'package:location/location.dart' as Location; // import 'package:permission_handler/permission_handler.dart'; // import 'package:provider/provider.dart'; // // import '../../Models/crmModels/NearbyOpenLeadsResponse.dart'; // import '../../Utils/commonServices.dart'; // // class crmNearbyOpenLeadsProvider extends ChangeNotifier { // // // List _leadslist = []; // TextEditingController _locationController = TextEditingController(); // String _googleApikey = "AIzaSyBGzvgMMKwPBAANTwaoRsAnrCpiWCj8wVs"; // GoogleMapController? _mapController; // CameraPosition? _cameraPosition; // LatLng _startLocation = const LatLng(17.439112226708446, 78.43292499146135); // String _latlongs = ""; // List _markers = []; // List _addresses = []; // Location.LocationData? _currentLocation; // bool _isLocationEnabled = false; // bool _hasLocationPermission = false; // Timer? _timer; // File? _image; // bool _isLoading = true; // double _currentValue = 1.0; // Timer? _debounceTimer; // // // List get leadsList => _leadslist; // TextEditingController get LocationController => _locationController; // String get googleAPIKey => _googleApikey; // GoogleMapController? get mapController => _mapController; // CameraPosition? get cameraPosition => _cameraPosition; // LatLng get startLocation => _startLocation; // String get latlongs => _latlongs; // List get markers => _markers; // List get addresses => _addresses; // Location.LocationData? get currentLocation => _currentLocation; // bool get isLocationEnabled => _isLocationEnabled; // bool get hasLocationPermission => _hasLocationPermission; // bool get isLoading => _isLoading; // Timer? get timer => _timer; // File? get image => _image; // double get currentValue => _currentValue; // // set currentValue(value){ // _currentValue = value; // notifyListeners(); // } // // // set markers(List value){ // _markers = value; // notifyListeners(); // } // set mapController(value){ // _mapController = value; // notifyListeners(); // } // // void resetAll(){ // _currentValue = 1.0; // _markers= []; // _addresses = []; // } // // Future getLocationPermission(context) async { // // Check if location services are enabled // _isLocationEnabled = await Geolocator.isLocationServiceEnabled(); // // // Check if the app has been granted location permission // LocationPermission permission = await Geolocator.checkPermission(); // _hasLocationPermission = // permission == LocationPermission.always || // permission == LocationPermission.whileInUse; // // final Location.Location location = Location.Location(); // bool serviceEnabled; // Location.PermissionStatus permissionGranted; // serviceEnabled = await location.serviceEnabled(); // if (!serviceEnabled) { // serviceEnabled = await location.requestService(); // if (!serviceEnabled) { // return; // } // } // _isLoading = false; // permissionGranted = (await location.hasPermission()); // if (permissionGranted == PermissionStatus) { // permissionGranted = (await location.requestPermission()); // if (permissionGranted != PermissionStatus) { // return; // } // } // final Location.LocationData locData = await location.getLocation(); // // _currentLocation = locData; // // if (_currentLocation != null) { // _mapController?.animateCamera( // CameraUpdate.newLatLng( // LatLng(_currentLocation!.latitude!, _currentLocation!.longitude!), // ), // ); // final lat = _currentLocation!.latitude; // final lang = _currentLocation!.longitude!; // _latlongs = '$lat,$lang'; // LoadNearbyOpenLeadsAPI(context,_currentValue); // } // } // // void onCameraMove(context, CameraPosition position) { // _timer?.cancel(); // Cancel any previous timer // _timer = Timer(Duration(seconds: 1), () { // getLocationPermission(context); // }); // } // void debounce(VoidCallback callback, Duration duration) { // _debounceTimer?.cancel(); // _debounceTimer = Timer(duration, callback); // } // // // Future LoadNearbyOpenLeadsAPI(BuildContext context,radius) async { // if (_latlongs.isEmpty || _currentValue <= 0) { // print("Invalid parameters: latlongs=$_latlongs, currentValue=$_currentValue"); // return; // } // try { // var provider = Provider.of(context, listen: false); // final data = await ApiCalling.loadNearbyOpenLeadsAPI( // provider.empId, // provider.session, // _latlongs, // radius // ); // // if (data != null) { // if (data.error == 0) { // _leadslist = data.leadList!; // // await updateMarkersFromApiResponse(context, data.leadList!); // _isLoading = false; // notifyListeners(); // } else if(data.error==1){ // toast(context, data.message); // } // // } else { // toast(context, "Something went wrong, Please try again."); // } // } on Exception catch (e) { // print("$e"); // } // } // // Future updateMarkersFromApiResponse( // BuildContext context, // List leadsList, // ) async { // _markers = await createMarkersFromApiResponse(context, leadsList); // _addresses.clear(); // await Future.forEach(leadsList, (store) async { // String address = await _getAddressFromLatLng(store.loc); // _addresses.add(address); // // }); // notifyListeners(); // // for (int i = 0; i < _addresses.length; i++) { // // //print('List of Addresses:' "${addresses[i]}"); // // // print('List of Addresses:' "${addresses[1]}" ); // // } // } // // Future> createMarkersFromApiResponse( // BuildContext context, // List leadsList, // ) async { // List markers = []; // // // print("Hello Nutsby!"); // ByteData data = await rootBundle.load("assets/images/leads_ic.png"); // Uint8List bytes = data.buffer.asUint8List(); // // await Future.forEach(leadsList, (leads) async { // ui.Codec codec = await ui.instantiateImageCodec( // bytes, // ); // ui.FrameInfo fi = await codec.getNextFrame(); // Uint8List resizedBytes = // (await fi.image.toByteData( // format: ui.ImageByteFormat.png, // ))!.buffer.asUint8List(); // // markers.add( // Marker( // markerId: MarkerId(leads.id.toString()), // // position: _parseLatLng(leads.loc), // icon: BitmapDescriptor.fromBytes(resizedBytes), // infoWindow: InfoWindow( // // onTap:() { // // onMarkerTap(context, leads.id); // Navigator.push( // context, // Use the widget's BuildContext, which is valid here // MaterialPageRoute( // builder: (context) => LeadDetailsByMode( // mode: "", // pageTitleName: "Lead Details", // leadId:leads.id , // // ), // ), // ); // }, // anchor: Offset(0, 0), // title: "${leads.name}", // snippet: "${leads.address}", // // ), // zIndex: 100, // // onTap: () { // int index = leadsList.indexWhere( // (techResponse) => // techResponse.id == leads.id, // ); // // onMarkerTap( // // context, // // leads.id, // // ); // // print("index:${index}"); // // Navigator.push( // // context, // // MaterialPageRoute( // // builder: // // (context) => Generatordetails( // // activityName: "NearByGenerators", // // genLocation: generator.loc, // // generatorId: generator.generatorId, // // ), // // ), // // ); // // }, // ), // ); // }); // return markers; // } // Future onMarkerTap(context, leadID) async { // ///uncomment with screen navigation // Navigator.push( // context, // Use the widget's BuildContext, which is valid here // MaterialPageRoute( // builder: (context) => LeadDetailsByMode( // mode: "", // pageTitleName: "Lead Details", // leadId:leadID , // // ), // ), // ); // // _markers = markers; // notifyListeners(); // // } // // LatLng _parseLatLng(String? location) { // if (location != null) { // List parts = location.split(','); // if (parts.length == 2) { // double lat = double.tryParse(parts[0]) ?? 0.0; // double lng = double.tryParse(parts[1]) ?? 0.0; // return LatLng(lat, lng); // } // } // return const LatLng(0.0, 0.0); // } // // Future _getAddressFromLatLng(String? location) async { // if (location != null) { // List parts = location.split(','); // if (parts.length == 2) { // double lat = double.tryParse(parts[0]) ?? 0.0; // double lng = double.tryParse(parts[1]) ?? 0.0; // // List placemarks = await geocoding // .placemarkFromCoordinates(lat, lng); // // if (placemarks.isNotEmpty) { // final placemark = placemarks.first; // String address = // '${placemark.street ?? ''}, ' // '${placemark.thoroughfare ?? ''} ' // // '${placemark.subThoroughfare ?? ''}, ' // // '${placemark.name ?? ''}, ' // '${placemark.subLocality ?? ''}, ' // '${placemark.locality ?? ''}, ' // '${placemark.administrativeArea ?? ''}, ' // '${placemark.subAdministrativeArea ?? ''} ' // '${placemark.postalCode ?? ''}, ' // '${placemark.country ?? ''}'; // return address.trim(); // } // } // } // return "Address not found"; // } // // } import 'dart:async'; import 'dart:io'; import 'dart:ui' as ui; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:generp/Notifiers/HomeScreenNotifier.dart'; import 'package:generp/screens/crm/LeadDetailsByMode.dart'; import 'package:generp/services/api_calling.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:image_picker/image_picker.dart'; import 'package:geocoding/geocoding.dart' as geocoding; import 'package:location/location.dart' as Location; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import '../../Models/crmModels/NearbyOpenLeadsResponse.dart'; import '../../Utils/commonServices.dart'; class crmNearbyOpenLeadsProvider extends ChangeNotifier { List _leadslist = []; TextEditingController _locationController = TextEditingController(); String _googleApikey = "AIzaSyBGzvgMMKwPBAANTwaoRsAnrCpiWCj8wVs"; GoogleMapController? _mapController; CameraPosition? _cameraPosition; LatLng _startLocation = const LatLng(17.439112226708446, 78.43292499146135); String _latlongs = ""; List _markers = []; List _addresses = []; Location.LocationData? _currentLocation; bool _isLocationEnabled = false; bool _hasLocationPermission = false; Timer? _timer; File? _image; bool _isLoading = true; double _currentValue = 1.0; Timer? _debounceTimer; LatLng? _mapCenter; bool _isFilterApplied = false; // Track if filter has been applied List get leadsList => _leadslist; TextEditingController get LocationController => _locationController; String get googleAPIKey => _googleApikey; GoogleMapController? get mapController => _mapController; CameraPosition? get cameraPosition => _cameraPosition; LatLng get startLocation => _startLocation; String get latlongs => _latlongs; List get markers => _markers; List get addresses => _addresses; Location.LocationData? get currentLocation => _currentLocation; bool get isLocationEnabled => _isLocationEnabled; bool get hasLocationPermission => _hasLocationPermission; bool get isLoading => _isLoading; Timer? get timer => _timer; File? get image => _image; double get currentValue => _currentValue; bool get isFilterApplied => _isFilterApplied; set currentValue(double value) { _currentValue = value; notifyListeners(); } set markers(List value) { _markers = value; if (value.isNotEmpty) { _isLoading = false; // Mark screen as loaded when markers are added } notifyListeners(); } set mapController(GoogleMapController? value) { _mapController = value; notifyListeners(); } set mapCenter(LatLng? value) { _mapCenter = value; _latlongs = value != null ? '${value.latitude},${value.longitude}' : ''; notifyListeners(); } set isLoading(bool value) { _isLoading = value; notifyListeners(); } void resetAll() { _currentValue = 1.0; _markers = []; _addresses = []; _mapCenter = null; _latlongs = ''; _isFilterApplied = false; _isLoading = true; notifyListeners(); } Future getLocationPermission(BuildContext context) async { _isLocationEnabled = await Geolocator.isLocationServiceEnabled(); LocationPermission permission = await Geolocator.checkPermission(); _hasLocationPermission = permission == LocationPermission.always || permission == LocationPermission.whileInUse; final Location.Location location = Location.Location(); bool serviceEnabled; Location.PermissionStatus permissionGranted; serviceEnabled = await location.serviceEnabled(); if (!serviceEnabled) { serviceEnabled = await location.requestService(); if (!serviceEnabled) { toast(context, 'Location services are disabled.'); _isLoading = false; return; } } permissionGranted = await location.hasPermission(); if (permissionGranted == Location.PermissionStatus.denied) { permissionGranted = await location.requestPermission(); if (permissionGranted != Location.PermissionStatus.granted) { toast(context, 'Location permission denied.'); _isLoading = false; return; } } final Location.LocationData locData = await location.getLocation(); _currentLocation = locData; if (_currentLocation != null && _mapCenter == null) { _mapCenter = LatLng(_currentLocation!.latitude!, _currentLocation!.longitude!); _latlongs = '${_currentLocation!.latitude},${_currentLocation!.longitude}'; _mapController?.animateCamera( CameraUpdate.newLatLng(_mapCenter!), ); await LoadNearbyOpenLeadsAPI(context, _currentValue); } notifyListeners(); } void onCameraMove(BuildContext context, CameraPosition position) { _timer?.cancel(); _mapCenter = position.target; _latlongs = '${_mapCenter!.latitude},${_mapCenter!.longitude}'; _timer = Timer(Duration(seconds: 1), () { LoadNearbyOpenLeadsAPI(context, _currentValue); }); notifyListeners(); } void debounce(VoidCallback callback, Duration duration) { _debounceTimer?.cancel(); _debounceTimer = Timer(duration, callback); } Future applyFilter(BuildContext context, double radius) async { _isLoading = true; _isFilterApplied = true; notifyListeners(); await LoadNearbyOpenLeadsAPI(context, radius); } Future LoadNearbyOpenLeadsAPI(BuildContext context, double radius) async { if (_latlongs.isEmpty || radius <= 0) { print("Invalid parameters: latlongs=$_latlongs, radius=$radius"); toast(context, 'Invalid location or radius.'); _isLoading = false; notifyListeners(); return; } try { var provider = Provider.of(context, listen: false); final data = await ApiCalling.loadNearbyOpenLeadsAPI( provider.empId, provider.session, _latlongs, radius, ); if (data != null) { if (data.error == 0) { _isLoading = false; _leadslist = data.leadList?.where((lead) => lead != null).toList() ?? []; await updateMarkersFromApiResponse(context, _leadslist); if (_leadslist.isEmpty) { toast(context, 'No leads found within the selected radius.'); } } else { toast(context, data.message ?? 'Failed to load leads.'); _isLoading = false; notifyListeners(); } } else { toast(context, "Something went wrong, please try again."); _isLoading = false; notifyListeners(); } } on Exception catch (e, s) { print("LoadNearbyOpenLeadsAPI error: $e, stack: $s"); toast(context, 'An error occurred while loading leads.'); _isLoading = false; notifyListeners(); } } Future updateMarkersFromApiResponse( BuildContext context, List leadsList, ) async { _markers = await createMarkersFromApiResponse(context, leadsList); _addresses.clear(); await Future.forEach(leadsList, (store) async { String address = await _getAddressFromLatLng(store.loc); _addresses.add(address); }); notifyListeners(); } Future> createMarkersFromApiResponse( BuildContext context, List leadsList, ) async { List markers = []; ByteData data = await rootBundle.load("assets/images/maps_ic.png"); Uint8List bytes = data.buffer.asUint8List(); await Future.forEach(leadsList, (leads) async { if (leads.loc == null || leads.id == null || leads.name == null) { print('Skipping invalid lead: id=${leads.id}, name=${leads.name}, loc=${leads.loc}'); return; } ui.Codec codec = await ui.instantiateImageCodec(bytes); ui.FrameInfo fi = await codec.getNextFrame(); Uint8List resizedBytes = (await fi.image.toByteData( format: ui.ImageByteFormat.png, ))!.buffer.asUint8List(); markers.add( Marker( markerId: MarkerId(leads.id.toString()), position: _parseLatLng(leads.loc), icon: BitmapDescriptor.fromBytes(resizedBytes), infoWindow: InfoWindow( title: leads.name ?? 'Unknown Lead', snippet: leads.address ?? 'No address available', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => LeadDetailsByMode( mode: "", pageTitleName: "Lead Details", leadId: leads.id, ), ), ); }, anchor: const Offset(0.5, 1.0), ), zIndex: 100, onTap: () { _mapController?.showMarkerInfoWindow(MarkerId(leads.id.toString())); print('Marker tapped: id=${leads.id}, name=${leads.name}'); }, ), ); }); return markers; } Future onMarkerTap(BuildContext context, String leadID) async { Navigator.push( context, MaterialPageRoute( builder: (context) => LeadDetailsByMode( mode: "", pageTitleName: "Lead Details", leadId: leadID, ), ), ); notifyListeners(); } LatLng _parseLatLng(String? location) { if (location != null) { List parts = location.split(','); if (parts.length == 2) { double lat = double.tryParse(parts[0]) ?? 0.0; double lng = double.tryParse(parts[1]) ?? 0.0; if (lat != 0.0 && lng != 0.0) { return LatLng(lat, lng); } } } print('Invalid location string: $location'); return const LatLng(0.0, 0.0); } Future _getAddressFromLatLng(String? location) async { if (location != null) { List parts = location.split(','); if (parts.length == 2) { double lat = double.tryParse(parts[0]) ?? 0.0; double lng = double.tryParse(parts[1]) ?? 0.0; if (lat != 0.0 && lng != 0.0) { try { List placemarks = await geocoding.placemarkFromCoordinates(lat, lng); if (placemarks.isNotEmpty) { final placemark = placemarks.first; String address = '${placemark.street ?? ''}, ' '${placemark.thoroughfare ?? ''} ' '${placemark.subLocality ?? ''}, ' '${placemark.locality ?? ''}, ' '${placemark.administrativeArea ?? ''}, ' '${placemark.subAdministrativeArea ?? ''} ' '${placemark.postalCode ?? ''}, ' '${placemark.country ?? ''}'; return address.trim(); } } catch (e) { print('Geocoding error for location $location: $e'); } } } } return "Address not found"; } }