2025-11-29 22:28:02 +05:30

187 lines
5.6 KiB
Dart

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';
/// ------------------------------------------------------------
/// API SERVICE
/// ------------------------------------------------------------
final apiServiceProvider = Provider<ApiService>((ref) => ApiService());
/// ------------------------------------------------------------
/// USER REPOSITORY
/// ------------------------------------------------------------
final userRepositoryProvider = Provider<UserRepositoryImpl>(
(ref) => UserRepositoryImpl(ref.read(apiServiceProvider)),
);
/// ------------------------------------------------------------
/// LOGIN PROVIDER ✅ (UNCHANGED NAME)
/// ------------------------------------------------------------
final loginProvider =
StateNotifierProvider<UserNotifier, AsyncValue<User?>>((ref) {
final repo = ref.read(userRepositoryProvider);
return UserNotifier(repo);
});
/// ------------------------------------------------------------
/// SIGNUP PROVIDER ✅ (UNCHANGED NAME)
/// ------------------------------------------------------------
final signupProvider =
StateNotifierProvider<UserNotifier, AsyncValue<User?>>((ref) {
final repo = ref.read(userRepositoryProvider);
return UserNotifier(repo);
});
/// ------------------------------------------------------------
/// MAIN USER PROVIDER ✅ (UNCHANGED NAME)
/// AUTO LOADS FROM STORAGE
/// ------------------------------------------------------------
final userProvider =
StateNotifierProvider<UserNotifier, AsyncValue<User?>>((ref) {
final repo = ref.read(userRepositoryProvider);
final notifier = UserNotifier(repo);
/// ✅ AUTO RESTORE SESSION ON APP START
notifier.loadUserFromStorage();
return notifier;
});
/// ------------------------------------------------------------
/// USER DETAILS PROVIDER ✅ (UNCHANGED NAME)
/// ------------------------------------------------------------
final userDetailsProvider = FutureProvider<UserModel?>((ref) async {
final userAsync = ref.watch(userProvider);
if (userAsync.isLoading) return null;
final user = userAsync.value;
if (user == null) return null;
final repo = ref.read(userRepositoryProvider);
return await repo.getUserDetails(user.id);
});
/// ------------------------------------------------------------
/// AUTH STATE
/// ------------------------------------------------------------
enum AuthAction { idle, login, signup }
/// ------------------------------------------------------------
/// USER NOTIFIER ✅
/// ------------------------------------------------------------
class UserNotifier extends StateNotifier<AsyncValue<User?>> {
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 USER FROM STORAGE (FIXED)
Future<void> loadUserFromStorage() async {
try {
final jsonString = await _storage.read(key: _userKey);
if (jsonString == null) {
debugPrint("🟡 No user found in storage");
return;
}
final jsonData = jsonDecode(jsonString);
final user = UserModel.fromJson(jsonData);
state = AsyncValue.data(user);
debugPrint("✅ USER RESTORED → ID: ${user.id}");
} catch (e) {
debugPrint("❌ Storage restore failed: $e");
state = const AsyncValue.data(null);
}
}
/// ✅ LOGIN
Future<void> login(String email, String password) async {
lastAction = AuthAction.login;
state = const AsyncValue.loading();
try {
final user = await repository.login(email, password);
if (user is UserModel) {
await _storage.write(key: _userKey, value: user.toRawJson());
debugPrint("✅ USER SAVED → ID: ${user.id}");
}
state = AsyncValue.data(user);
} catch (e, st) {
state = AsyncValue.error(e, st);
}
}
/// ✅ LOGOUT
Future<void> logout() async {
await _storage.delete(key: _userKey);
state = const AsyncValue.data(null);
}
/// ✅ SIGNUP
Future<void> 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<void> 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 FULL USER DETAILS
Future<void> getUserDetails(String userId) async {
state = const AsyncValue.loading();
try {
final user = await repository.getUserDetails(userId);
await saveUserDetails(user);
state = AsyncValue.data(user);
} catch (e, st) {
state = AsyncValue.error(e, st);
}
}
/// ✅ SAVE FULL DETAILS
Future<void> saveUserDetails(UserModel user) async {
await _storage.write(
key: 'logged_in_user_details',
value: user.toRawJson(),
);
}
}