import 'dart:convert';

import 'package:http/http.dart' as http;

/// Geocoding de moradas via Nominatim (OpenStreetMap) — converte texto
/// livre em coordenadas. Serviço gratuito e público; a política de uso da
/// Nominatim exige no máximo ~1 pedido/segundo e um `User-Agent`
/// identificável, por isso só chamamos isto quando o utilizador guarda a
/// morada (nunca em cada abertura de ecrã).
class GeocodingService {
  const GeocodingService._();

  static const String _endpoint = 'https://nominatim.openstreetmap.org/search';
  static const String _userAgent = 'CheckTeethKids/1.0 (caducorreia740@gmail.com)';

  /// Devolve as coordenadas da morada, ou `null` se a Nominatim não
  /// encontrar nenhum resultado, a ligação falhar ou expirar o tempo
  /// limite — quem chama decide como reagir (ex.: mostrar erro no campo).
  static Future<({double lat, double lon})?> geocodeAddress(
    String address,
  ) async {
    final uri = Uri.parse(_endpoint).replace(
      queryParameters: {
        'q': address,
        'format': 'jsonv2',
        'limit': '1',
      },
    );

    try {
      final response = await http
          .get(uri, headers: {'User-Agent': _userAgent})
          .timeout(const Duration(seconds: 12));

      if (response.statusCode != 200) return null;

      final results = jsonDecode(response.body);
      if (results is! List || results.isEmpty) return null;

      final first = results.first;
      if (first is! Map) return null;

      final lat = double.tryParse('${first['lat']}');
      final lon = double.tryParse('${first['lon']}');
      if (lat == null || lon == null) return null;

      return (lat: lat, lon: lon);
    } catch (_) {
      return null;
    }
  }
}
