import 'dart:convert'; import 'package:http/http.dart' as http; import '/core/constants.dart'; import '/data/models/contact_model.dart'; import '/domain/services/api_service.dart'; import 'package:flutter_http_cache/flutter_http_cache.dart'; class ContactRepository { late final CachedHttpClient _client; bool _isCacheInitialized = false; final ApiService _apiService = ApiService(); ContactRepository() { _initCachedClient(); } // Единая инициализация кэша для всех запросов репозитория void _initCachedClient() { final cache = _apiService.cache; _client = CachedHttpClient( cache: cache, defaultCachePolicy: CachePolicy.networkFirst, ); } Future _ensureCacheReady() async { if (!_isCacheInitialized) { await _apiService.cache.initialize(); _isCacheInitialized = true; } } Future> fetchChatContacts({bool forceRefresh = false}) async { final token = await _apiService.getAccessToken(); DateTime now = DateTime.now(); Duration offset = now.timeZoneOffset; final Map requestHeaders = { 'Authorization': 'Bearer $token', 'Content-Type': 'application/json', }; if (forceRefresh) { requestHeaders['Cache-Control'] = 'no-cache'; } await _ensureCacheReady(); try { final response = await _client.get( Uri.parse('${AppConstants.baseUrl}/users/chats'), headers: requestHeaders, ); if (response.statusCode == 200) { final List data = jsonDecode(utf8.decode(response.bodyBytes)); print(data); return data.map((json) { final contact = Contact.fromJson(json); print(contact.lastMessageType); if (contact.lastMessageTime != null) { return contact.copyWith( lastMessageTime: contact.lastMessageTime!.add(offset), ); } return contact; }).toList(); } else { throw Exception('Failed to load contacts'); } } catch (e) { print( '⚠️ Ошибка сети при загрузке контактов: $e. Пробуем строгий кэш...', ); // FALLBACK: Если сеть упала, принудительно создаем запрос с политикой cacheOnly final offlineClient = CachedHttpClient( cache: _apiService.cache, defaultCachePolicy: CachePolicy.cacheOnly, // Читаем строго из кэша ); try { final response = await offlineClient.get( Uri.parse('${AppConstants.baseUrl}/users/chats'), headers: requestHeaders, ); final List data = jsonDecode(utf8.decode(response.bodyBytes)); return data.map((json) => Contact.fromJson(json)).toList(); } catch (cacheError) { throw Exception('Нет доступа к сети. Проверте подключение к интернету.'); } } } Future> fetchAllUsers({bool forceRefresh = false}) async { final token = await _apiService.getAccessToken(); DateTime now = DateTime.now(); Duration offset = now.timeZoneOffset; if (token == null) { throw Exception('No access token'); } final Map requestHeaders = { 'Authorization': 'Bearer $token', 'Content-Type': 'application/json', }; if (forceRefresh) { requestHeaders['Cache-Control'] = 'no-cache'; } await _ensureCacheReady(); final response = await _client.get( Uri.parse('${AppConstants.baseUrl}/users/all'), headers: requestHeaders, ); if (response.statusCode == 200) { final List data = jsonDecode(utf8.decode(response.bodyBytes)); return data.map((json) { final contact = Contact.fromJson(json); if (contact.lastMessageTime != null) { return contact.copyWith( lastMessageTime: contact.lastMessageTime!.add(offset), ); } return contact; }).toList(); } else { throw Exception('Failed to load contacts'); } } Future fetchContactById( int userId, { bool forceRefresh = false, }) async { final token = await _apiService.getAccessToken(); final Map requestHeaders = { 'Authorization': 'Bearer $token', 'Content-Type': 'application/json', }; if (forceRefresh) { requestHeaders['Cache-Control'] = 'no-cache'; } await _ensureCacheReady(); final response = await _client.get( Uri.parse('${AppConstants.baseUrl}/users/$userId'), headers: requestHeaders, ); if (response.statusCode == 200) { final data = jsonDecode(utf8.decode(response.bodyBytes)); return Contact.fromJson(data); } else { throw Exception('Не удалось загрузить данные контакта'); } } Future>> getLastMessagesForContact( int contactId, { int limit = 2, bool forceRefresh = false, }) async { final token = await _apiService.getAccessToken(); if (token == null) { throw Exception('No access token'); } final Map requestHeaders = { 'Authorization': 'Bearer $token', 'Content-Type': 'application/json', }; if (forceRefresh) { requestHeaders['Cache-Control'] = 'no-cache'; } await _ensureCacheReady(); final response = await _client.get( Uri.parse( '${AppConstants.baseUrl}/messages/last?contact_id=$contactId&limit=$limit', ), headers: requestHeaders, ); if (response.statusCode == 200) { final List data = jsonDecode(utf8.decode(response.bodyBytes)); return data.map((item) => item as Map).toList(); } else { throw Exception('Failed to load last messages'); } } }