import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/constants.dart'; import '../../../core/database/app_database.dart'; import '../data/search_repository.dart'; class SearchState { final String query; final List results; final List recentSearches; final bool isLoading; final String? error; const SearchState({ this.query = '', this.results = const [], this.recentSearches = const [], this.isLoading = false, this.error, }); SearchState copyWith({ String? query, List? results, List? recentSearches, bool? isLoading, String? error, bool clearError = false, }) { return SearchState( query: query ?? this.query, results: results ?? this.results, recentSearches: recentSearches ?? this.recentSearches, isLoading: isLoading ?? this.isLoading, error: clearError ? null : (error ?? this.error), ); } } class SearchNotifier extends StateNotifier { final SearchRepository _repository; Timer? _debounce; SearchNotifier(this._repository) : super(const SearchState()) { _loadHistory(); } Future _loadHistory() async { final history = await _repository.getRecentSearches(); if (mounted) { state = state.copyWith(recentSearches: history); } } void updateQuery(String query) { state = state.copyWith(query: query, clearError: true); _debounce?.cancel(); if (query.trim().isEmpty) { state = state.copyWith(results: [], isLoading: false); return; } state = state.copyWith(isLoading: true); _debounce = Timer( const Duration(milliseconds: AppConstants.searchDebounceMs), () => _performSearch(query), ); } Future _performSearch(String query) async { try { final results = await _repository.search(query); if (mounted && state.query == query) { state = state.copyWith(results: results, isLoading: false); } } catch (e) { if (mounted) { state = state.copyWith( isLoading: false, error: 'Search failed. Please try again.', ); } } } Future selectResult(SearchResult result) async { await _repository.saveToHistory( result.name, lat: result.latitude, lon: result.longitude, ); await _loadHistory(); } Future deleteHistoryEntry(int id) async { await _repository.deleteHistoryEntry(id); await _loadHistory(); } Future clearHistory() async { await _repository.clearHistory(); await _loadHistory(); } @override void dispose() { _debounce?.cancel(); super.dispose(); } } final searchProvider = StateNotifierProvider.autoDispose((ref) { return SearchNotifier(ref.watch(searchRepositoryProvider)); });