import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import '../core/preferences.dart';

class GeocodingService {
  /// Reverse geocode using Nominatim API (OpenStreetMap)
  static Future<String?> reverseGeocode(double lat, double lon) async {
    try {
      final url = Uri.parse(
        'https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=$lat&lon=$lon&zoom=18',
      );
      final response = await http.get(
        url,
        headers: {
          'User-Agent': 'LiveVacationMemoriesApp/1.0 (info@coolcode.cz)',
        },
      );
      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        
        if (data['name'] != null && data['name'].toString().isNotEmpty) {
          return data['name'].toString();
        }
        
        final address = data['address'];
        if (address != null) {
          final poi = address['tourism'] ??
              address['historic'] ??
              address['attraction'] ??
              address['museum'] ??
              address['monument'] ??
              address['castle'] ??
              address['fortress'] ??
              address['archaeological'] ??
              address['amenity'] ??
              address['leisure'] ??
              address['natural'] ??
              address['shop'] ??
              address['place'];
          if (poi != null) return poi.toString();

          if (address['road'] != null) {
            if (address['house_number'] != null) {
              return '${address['road']} ${address['house_number']}';
            }
            return address['road'].toString();
          }

          final place = address['city'] ??
              address['town'] ??
              address['village'] ??
              address['hamlet'] ??
              address['suburb'];
          if (place != null) return place.toString();
        }

        if (data['display_name'] != null) {
          return data['display_name'].toString().split(',')[0].trim();
        }
      }
    } catch (e) {
      debugPrint('Nominatim Geocoding Error: $e');
    }
    return null;
  }

  /// Search Wikipedia for nearby articles and return the clean description
  static Future<Map<String, String>?> getWikipediaInfo(double lat, double lon) async {
    try {
      final lang = AppPreferences.language;
      final geosearchUrl = Uri.parse(
        'https://$lang.wikipedia.org/w/api.php?action=query&list=geosearch&gscoord=$lat|$lon&gsradius=5000&gslimit=5&format=json',
      );
      final geoResponse = await http.get(geosearchUrl);
      if (geoResponse.statusCode == 200) {
        final geoData = json.decode(geoResponse.body);
        final results = geoData['query']?['geosearch'] as List?;
        if (results != null && results.isNotEmpty) {
          final first = results.first;
          final title = first['title'] as String?;
          if (title != null && title.isNotEmpty) {
            final extractUrl = Uri.parse(
              'https://$lang.wikipedia.org/w/api.php?action=query&prop=extracts&exintro&explaintext&titles=${Uri.encodeComponent(title)}&format=json',
            );
            final extResponse = await http.get(extractUrl);
            if (extResponse.statusCode == 200) {
              final extData = json.decode(extResponse.body);
              final pages = extData['query']?['pages'] as Map?;
              if (pages != null && pages.isNotEmpty) {
                final pageData = pages.values.first;
                final extract = pageData['extract'] as String?;
                if (extract != null && extract.trim().isNotEmpty) {
                  return {
                    'title': title,
                    'description': extract.trim(),
                  };
                }
              }
            }
          }
        }
      }
    } catch (e) {
      debugPrint('Wikipedia Geosearch Error: $e');
    }
    return null;
  }
}
