import 'dart:convert'; import 'package:autos/data/models/user_model.dart'; import 'package:autos/data/repositories/user_repository_impl.dart'; import 'package:autos/data/sources/remote/api_service.dart'; import 'package:autos/domain/entities/user.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/legacy.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // Provide a single ApiService instance across the app final apiServiceProvider = Provider((ref) => ApiService()); // Provide repository that depends on ApiService final userRepositoryProvider = Provider( (ref) => UserRepositoryImpl(ref.read(apiServiceProvider)), ); // Manage user state final loginProvider = StateNotifierProvider>(( ref, ) { final repo = ref.read(userRepositoryProvider); return UserNotifier(repo); }); final signupProvider = StateNotifierProvider>(( ref, ) { final repo = ref.read(userRepositoryProvider); return UserNotifier(repo); }); final userProvider = StateNotifierProvider>(( ref, ) { final repo = ref.read(userRepositoryProvider); return UserNotifier(repo); }); final userDetailsProvider = FutureProvider((ref) async { final userAsync = ref.watch(userProvider); // Waiting for login provider to finish if (userAsync.isLoading) return null; final user = userAsync.value; if (user == null) return null; // Fetch Full Details final repo = ref.read(userRepositoryProvider); return await repo.getUserDetails(user.id); }); enum AuthAction { idle, login, signup } class UserNotifier extends StateNotifier> { final UserRepositoryImpl repository; final _storage = const FlutterSecureStorage(); static const _userKey = 'logged_in_user'; AuthAction lastAction = AuthAction.idle; UserNotifier(this.repository) : super(const AsyncValue.data(null)); ///Load saved user from storage (auto-login) Future loadUserFromStorage() async { final jsonString = await _storage.read(key: _userKey); if (jsonString != null) { debugPrint("RESULT: $jsonString"); final jsonData = jsonDecode(jsonString); final user = UserModel.fromJson(jsonData); await Future.microtask(() {}); state = AsyncValue.data(user); } } ///Login Future login(String email, String password) async { lastAction = AuthAction.login; state = const AsyncValue.loading(); try { final user = await repository.login(email, password); // ✅ Save user to secure storage if (user is UserModel) { await _storage.write(key: _userKey, value: user.toRawJson()); } state = AsyncValue.data(user); } catch (e, st) { state = AsyncValue.error(e, st); } } /// Logout Future logout() async { await _storage.delete(key: _userKey); state = const AsyncValue.data(null); } ///Sign up Future signup( String name, String email, String password, String phone, ) async { lastAction = AuthAction.signup; state = const AsyncValue.loading(); try { final user = await repository.signup(name, email, password, phone); state = AsyncValue.data(user); } catch (e, st) { state = AsyncValue.error(e, st); } } ///Reset password Future sendPasswordResetLink(String email) async { state = const AsyncValue.loading(); try { await repository.sendPasswordResetLink(email); state = const AsyncValue.data(null); } catch (e, st) { state = AsyncValue.error(e, st); } } /// Fetch user details from backend Future getUserDetails(String userId) async { state = const AsyncValue.loading(); try { final user = await repository.getUserDetails(userId); // Save full details separately await saveUserDetails(user); state = AsyncValue.data(user); } catch (e, st) { state = AsyncValue.error(e, st); } } /// Save full user details separately Future saveUserDetails(UserModel user) async { await _storage.write( key: 'logged_in_user_details', value: user.toRawJson(), ); } }