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 Notifier { late SearchRepository _repository; Timer? _debounce; @override SearchState build() { _repository = ref.watch(searchRepositoryProvider); ref.onDispose(() => _debounce?.cancel()); Future.microtask(_loadHistory); return const SearchState(); } Future _loadHistory() async { final history = await _repository.getRecentSearches(); 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 (state.query == query) { state = state.copyWith(results: results, isLoading: false); } } catch (e) { 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(); } } final searchProvider = NotifierProvider.autoDispose( SearchNotifier.new, );