import 'dart:async';
import 'dart:js_interop';
import 'package:web/web.dart' as web;
@JS('globalThis.google')
external JSAny? get _google;
const googleMapsApiKey = String.fromEnvironment(
'MEINWEIMAR_GOOGLE_MAPS_API_KEY',
);
/// Web activation is intentionally key-gated. A web build that contains the
/// Google key is the explicit product choice; a build without one stays on
/// the safe external-map fallback and never invents a provider.
const googleMapsEnabled = true;
bool _googleMapsScriptLoaded = false;
Future<bool> ensureGoogleMapsWebReady() async {
if (!googleMapsEnabled || googleMapsApiKey.isEmpty) return false;
if (_googleMapsScriptLoaded) return true;
// The release build injects the loader with our data attribute. The broader
// selector also handles an already-served local preview whose index.html
// was generated before that attribute existed, without adding a second
// Google Maps loader to the document.
final existing = web.document.querySelector(
'script[data-meinweimar-google-maps="true"], '
'script[src*="maps.googleapis.com/maps/api/js"]',
);
if (existing != null && _googleMapsIsLoaded()) return true;
final script = existing == null
? (web.HTMLScriptElement()
..dataset['meinweimarGoogleMaps'] = 'true'
..async = true
..defer = true
..src =
'https://maps.googleapis.com/maps/api/js?key=${Uri.encodeQueryComponent(googleMapsApiKey)}&loading=async&libraries=marker,geometry')
: existing as web.HTMLScriptElement;
if (_googleMapsIsLoaded()) return true;
final completer = Completer<bool>();
late StreamSubscription<web.Event> loadSubscription;
late StreamSubscription<web.Event> errorSubscription;
void finish(bool value) {
if (!completer.isCompleted) completer.complete(value);
loadSubscription.cancel();
errorSubscription.cancel();
}
loadSubscription = script.onLoad.listen((_) {
_googleMapsScriptLoaded = true;
// The script load event is the stable readiness signal. Reading the
// nested `google.maps` namespace through JS interop is not reliable in
// every Flutter web renderer even though the namespace is already usable
// by google_maps_flutter_web.
finish(true);
});
errorSubscription = script.onError.listen((_) => finish(false));
// Register both listeners before insertion. The Maps script can finish
// loading before the next event-loop turn on a warm local preview.
if (existing == null) {
web.document.head?.append(script);
}
return completer.future.timeout(
const Duration(seconds: 12),
onTimeout: () {
finish(false);
return false;
},
);
}
bool _googleMapsIsLoaded() => _google != null;
