import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; const _kAccessToken = 'access_token'; const _kRefreshToken = 'refresh_token'; const _kUsername = 'username'; const _kRealName = 'real_name'; const _kHotelNo = 'hotel_no'; const _kHotelId = 'hotel_id'; class AuthUser { final String accessToken; final String refreshToken; final String username; final String realName; final String hotelNo; final int hotelId; const AuthUser({ required this.accessToken, required this.refreshToken, required this.username, required this.realName, required this.hotelNo, required this.hotelId, }); // Kept for ApiClient compatibility String get token => accessToken; } class AuthState { final AuthUser? user; final bool initialized; const AuthState({this.user, this.initialized = false}); bool get isLoggedIn => user != null; } class AuthNotifier extends StateNotifier { AuthNotifier() : super(const AuthState()); /// Called at app startup to restore persisted session. Future restore() async { try { final prefs = await SharedPreferences.getInstance(); final accessToken = prefs.getString(_kAccessToken); final refreshToken = prefs.getString(_kRefreshToken); final username = prefs.getString(_kUsername); final realName = prefs.getString(_kRealName); final hotelNo = prefs.getString(_kHotelNo); final hotelIdStr = prefs.getString(_kHotelId); if (accessToken != null && refreshToken != null && username != null) { state = AuthState( initialized: true, user: AuthUser( accessToken: accessToken, refreshToken: refreshToken, username: username, realName: realName ?? username, hotelNo: hotelNo ?? '', hotelId: int.tryParse(hotelIdStr ?? '') ?? 0, ), ); return; } } catch (_) { // Storage unavailable — fall through to logged-out state } state = const AuthState(initialized: true); } Future login(AuthUser user) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(_kAccessToken, user.accessToken); await prefs.setString(_kRefreshToken, user.refreshToken); await prefs.setString(_kUsername, user.username); await prefs.setString(_kRealName, user.realName); await prefs.setString(_kHotelNo, user.hotelNo); await prefs.setString(_kHotelId, user.hotelId.toString()); state = AuthState(initialized: true, user: user); } void updateAccessToken(String newToken) { if (state.user == null) return; SharedPreferences.getInstance() .then((prefs) => prefs.setString(_kAccessToken, newToken)); state = AuthState( initialized: true, user: AuthUser( accessToken: newToken, refreshToken: state.user!.refreshToken, username: state.user!.username, realName: state.user!.realName, hotelNo: state.user!.hotelNo, hotelId: state.user!.hotelId, ), ); } Future logout() async { final prefs = await SharedPreferences.getInstance(); await prefs.remove(_kAccessToken); await prefs.remove(_kRefreshToken); await prefs.remove(_kUsername); await prefs.remove(_kRealName); await prefs.remove(_kHotelNo); await prefs.remove(_kHotelId); state = const AuthState(initialized: true); } } final authStateProvider = StateNotifierProvider( (ref) => AuthNotifier(), );