import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_google_places_sdk/flutter_google_places_sdk.dart'; import 'package:wheres_my_sign/common/functions.dart'; class GooglePlacesHelper { final FlutterGooglePlacesSdk _places; bool _isHandlingSelection = false; GooglePlacesHelper(String apiKey) : _places = FlutterGooglePlacesSdk(apiKey); void attachAddressListener({ required TextEditingController controller, required FocusNode focusNode, required void Function(List) onPredictions, required VoidCallback onOverlayHide, required Debouncer debouncer, }) { controller.addListener(() { _onAddressChanged( controller: controller, debouncer: debouncer, onPredictions: onPredictions, onOverlayHide: onOverlayHide, ); }); focusNode.addListener(() { if (!focusNode.hasFocus) { Future.delayed(const Duration(milliseconds: 100), onOverlayHide); } }); } Future _onAddressChanged({ required TextEditingController controller, required Debouncer debouncer, required void Function(List) onPredictions, required VoidCallback onOverlayHide, }) async { if (_isHandlingSelection || controller.text.length < 3) return; debouncer.run(() async { try { final result = await _places.findAutocompletePredictions( controller.text, countries: ['us'], ); if (result.predictions.isNotEmpty) { onPredictions(result.predictions); } else { onOverlayHide(); } } catch (e) { debugPrint('Prediction error: $e'); onOverlayHide(); } }); } Future handlePlaceSelection({ required AutocompletePrediction prediction, required TextEditingController addressController, required void Function(double? lat, double? lng) onLatLngRetrieved, required VoidCallback onOverlayHide, }) async { try { _isHandlingSelection = true; onOverlayHide(); final result = await _places.fetchPlace( prediction.placeId, fields: [PlaceField.Address, PlaceField.Location], ); final place = result.place; if (place != null) { addressController.text = place.address ?? prediction.fullText; onLatLngRetrieved(place.latLng?.lat, place.latLng?.lng); } } catch (e) { debugPrint('Place fetch error: $e'); } finally { _isHandlingSelection = false; } } }