import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/api/api_client.dart'; import '../../../core/database/app_database.dart'; /// A single search result parsed from GeoJSON. class SearchResult { final int osmId; final String osmType; final String name; final String? street; final String? housenumber; final String? postcode; final String? city; final String? state; final String? country; final String? countryCode; final String type; final double latitude; final double longitude; final List? extent; SearchResult({ required this.osmId, required this.osmType, required this.name, this.street, this.housenumber, this.postcode, this.city, this.state, this.country, this.countryCode, required this.type, required this.latitude, required this.longitude, this.extent, }); String get displayAddress { final parts = []; if (street != null) { parts.add(housenumber != null ? '$street $housenumber' : street!); } if (city != null) parts.add(city!); if (country != null) parts.add(country!); return parts.join(', '); } factory SearchResult.fromGeoJsonFeature(Map feature) { final geometry = feature['geometry'] as Map; final coords = geometry['coordinates'] as List; final props = feature['properties'] as Map; return SearchResult( osmId: props['osm_id'] as int, osmType: props['osm_type'] as String, name: props['name'] as String? ?? '', street: props['street'] as String?, housenumber: props['housenumber'] as String?, postcode: props['postcode'] as String?, city: props['city'] as String?, state: props['state'] as String?, country: props['country'] as String?, countryCode: props['country_code'] as String?, type: props['type'] as String? ?? 'unknown', longitude: (coords[0] as num).toDouble(), latitude: (coords[1] as num).toDouble(), extent: (props['extent'] as List?) ?.map((e) => (e as num).toDouble()) .toList(), ); } } class SearchRepository { final ApiClient _apiClient; final AppDatabase _db; SearchRepository(this._apiClient, this._db); /// Forward search via GET /api/search. Future> search( String query, { double? lat, double? lon, int limit = 10, }) async { final params = { 'q': query, 'limit': limit, }; if (lat != null && lon != null) { params['lat'] = lat; params['lon'] = lon; } final data = await _apiClient.get('/api/search', queryParameters: params); final features = (data['features'] as List?) ?? []; return features .map((f) => SearchResult.fromGeoJsonFeature(f as Map)) .toList(); } /// Save a query to search history. Future saveToHistory(String query, {double? lat, double? lon}) { return _db.addSearch(query, lat: lat, lon: lon); } /// Get recent search history. Future> getRecentSearches() { return _db.getRecentSearches(); } /// Watch recent search history. Stream> watchRecentSearches() { return _db.watchRecentSearches(); } /// Delete a single search history entry. Future deleteHistoryEntry(int id) { return _db.deleteSearchEntry(id); } /// Clear all search history. Future clearHistory() { return _db.clearSearchHistory(); } } final searchRepositoryProvider = Provider((ref) { return SearchRepository( ref.watch(apiClientProvider), ref.watch(appDatabaseProvider), ); });