import 'dart:convert'; import '../constants/api_constants.dart'; import 'http_service.dart'; import 'auth_service.dart'; import 'cache_service.dart'; class UserService { static bool _pollingStarted = false; /// Get current user with caching - returns cached data if available and fresh static Future> getCurrentUser({bool forceRefresh = false}) async { // Return cached data if available and not forcing refresh if (!forceRefresh) { final cached = CacheService.getCached>(CacheService.userProfileKey); if (cached != null && !CacheService.isCacheExpired(CacheService.userProfileKey, CacheService.userCacheDuration)) { return { 'success': true, 'message': 'Loaded from cache', 'data': cached, }; } // Return stale data while fetching fresh data in background final stale = CacheService.getCachedStale>(CacheService.userProfileKey); if (stale != null && !forceRefresh) { // Trigger background refresh _fetchAndCacheUser(); return { 'success': true, 'message': 'Loaded from cache (refreshing in background)', 'data': stale, }; } // Also check AuthService cache for backward compatibility final authCachedData = await AuthService.getCachedUserData(); if (authCachedData != null) { // Update our cache with auth service data CacheService.setCached(CacheService.userProfileKey, authCachedData); return {'success': true, 'data': authCachedData}; } } // Fetch fresh data return await _fetchAndCacheUser(); } static Future> _fetchAndCacheUser([bool fromPolling = false]) async { try { final response = await HttpService.get(ApiConstants.getUserEndpoint); if (response.statusCode == 200) { final data = jsonDecode(response.body); // Only cache when not called from polling to prevent conflicts if (!fromPolling) { CacheService.setCached(CacheService.userProfileKey, data); } // Also save to AuthService for backward compatibility await AuthService.saveUserData(data); return { 'success': true, 'data': data, 'message': '', }; } else if (response.statusCode == 401 || response.statusCode == 403) { await AuthService.handleAuthenticationError(); return { 'success': false, 'message': 'Session expired. Please login again.', 'data': null, }; } else { return { 'success': false, 'message': 'Server error (${response.statusCode})', 'data': null, }; } } catch (e) { print('Error fetching user: $e'); return { 'success': false, 'message': 'Network error. Please check your connection.', 'data': null, }; } } /// Start background polling for user profile static void startPolling() { _pollingStarted = true; CacheService.startPolling( CacheService.userProfileKey, () => _fetchAndCacheUser(true), // Mark as from polling CacheService.userPollingInterval, CacheService.userCacheDuration, ); } /// Stop background polling for user profile static void stopPolling() { CacheService.stopPolling(CacheService.userProfileKey); _pollingStarted = false; } /// Get user profile stream for real-time updates static Stream> getUserStream() { return CacheService.getStream>(CacheService.userProfileKey); } /// Check if polling is active static bool get isPollingActive => _pollingStarted; /// Invalidate user cache (useful after updating profile) static void invalidateCache() { CacheService.clearCache(CacheService.userProfileKey); } static Future> updateFCMToken(String fcmToken) async { try { final response = await HttpService.post(ApiConstants.updateUserEndpoint, { 'fcmToken': fcmToken, }); if (response.statusCode == 200) { return {'success': true}; } else if (response.statusCode == 401) { return { 'success': false, 'message': 'Session expired. Please login again.', }; } else if (response.statusCode == 403) { return { 'success': false, 'message': 'Access denied. Invalid credentials.', }; } else { return { 'success': false, 'message': 'Server error (${response.statusCode})', }; } } catch (e) { print('Error updating FCM token: $e'); return { 'success': false, 'message': 'Network error. Please check your connection.', }; } } static Future> createUser({ required String email, required String password, required String displayName, }) async { try { final response = await HttpService.post('/admin/createUser', { 'email': email, 'password': password, 'displayName': displayName, }); final responseData = jsonDecode(response.body); if (response.statusCode == 200 || response.statusCode == 201) { return { 'success': responseData['status'] ?? false, 'message': responseData['message'] ?? 'User created successfully', 'data': responseData['data'], }; } else { return { 'success': false, 'message': responseData['message'] ?? 'Failed to create user', }; } } catch (e) { print('Error creating user: $e'); return { 'success': false, 'message': 'Network error. Please check your connection.', }; } } }