import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'api/api_client.dart'; import 'models/recipe.dart'; import 'storage/secure_storage_service.dart'; final secureStorageProvider = Provider((ref) { return SecureStorageService(); }); final apiClientProvider = Provider((ref) { final storage = ref.watch(secureStorageProvider); return ApiClient(storage); }); // Authentication State Notifier class AuthState { final bool isAuthenticated; final bool isLoading; final String? errorMessage; final Map? user; const AuthState({ required this.isAuthenticated, this.isLoading = false, this.errorMessage, this.user, }); factory AuthState.initial() => const AuthState(isAuthenticated: false); factory AuthState.loading() => const AuthState(isAuthenticated: false, isLoading: true); factory AuthState.authenticated(Map user) => AuthState(isAuthenticated: true, user: user); factory AuthState.unauthenticated([String? error]) => AuthState(isAuthenticated: false, errorMessage: error); } class AuthNotifier extends StateNotifier { final ApiClient _api; final SecureStorageService _storage; AuthNotifier(this._api, this._storage) : super(AuthState.initial()) { checkInitialAuth(); } Future checkInitialAuth() async { final isValid = await _storage.hasValidSession(); if (isValid) { final user = await _storage.getUser(); state = AuthState.authenticated(user ?? {'username': 'Chef'}); } else { state = AuthState.unauthenticated(); } } Future login({ required String serverUrl, required String username, required String password, required String deviceName, }) async { state = AuthState.loading(); try { final res = await _api.login( serverUrl: serverUrl, username: username, password: password, deviceName: deviceName, ); final user = res['user'] as Map; state = AuthState.authenticated(user); return true; } catch (e) { state = AuthState.unauthenticated(e.toString()); return false; } } Future logout() async { await _api.logout(); state = AuthState.unauthenticated(); } } final authProvider = StateNotifierProvider((ref) { final api = ref.watch(apiClientProvider); final storage = ref.watch(secureStorageProvider); return AuthNotifier(api, storage); }); // Recipe List State Notifier class RecipeListNotifier extends StateNotifier>> { final ApiClient _api; RecipeListNotifier(this._api) : super(const AsyncValue.loading()) { loadRecipes(); } Future loadRecipes() async { state = const AsyncValue.loading(); try { final recipes = await _api.fetchRecipes(); state = AsyncValue.data(recipes); } catch (e, st) { state = AsyncValue.error(e, st); } } Future addOrUpdate(Recipe recipe) async { try { final saved = await _api.saveRecipe(recipe); final current = state.value ?? []; final idx = current.indexWhere((r) => r.id == saved.id); if (idx >= 0) { current[idx] = saved; state = AsyncValue.data([...current]); } else { state = AsyncValue.data([saved, ...current]); } } catch (e) { rethrow; } } Future remove(String id) async { await _api.deleteRecipe(id); final current = state.value ?? []; state = AsyncValue.data(current.where((r) => r.id != id).toList()); } } final recipeListProvider = StateNotifierProvider>>((ref) { final api = ref.watch(apiClientProvider); return RecipeListNotifier(api); });