import 'package:flutter/material.dart'; import '/data/models/contact_model.dart'; import '/data/repositories/contact_repository.dart'; import '/data/datasources/local_db_service.dart'; import '/domain/services/crypto_service.dart'; class ContactProvider extends ChangeNotifier { final ContactRepository _repository = ContactRepository(); final LocalDbService _localDbService = LocalDbService(); final CryptoService _cryptoService = CryptoService(); List _contacts = []; List _allContacts = []; bool _isLoading = false; bool _isFirstLoad = true; String? _error; int? _currentUserId; List get contacts => _contacts; List get allContacts => _allContacts; bool get isLoading => _isLoading; String? get error => _error; void setCurrentUserId(int? id) { _currentUserId = id; notifyListeners(); } int? getCurrentUserId() { return _currentUserId; } Future loadContacts() async { if (_isFirstLoad) { _isFirstLoad = false; _isLoading = true; } _error = null; notifyListeners(); try { final allContacts = await _repository.fetchChatContacts(); // Фильтруем: исключаем себя (для основного списка - только чаты) _contacts = allContacts .where((contact) => contact.id != _currentUserId) .toList(); _allContacts = _contacts; _isLoading = false; notifyListeners(); // Обогащаем превью последним сообщением из локальной БД, не блокируя UI. _enrichContactsWithLastMessages(); } catch (e) { _error = e.toString(); } finally { // Если ошибка — выходим из состояния загрузки тут. // Если всё ок — `_isLoading` уже сброшен выше, чтобы показать список быстрее. if (_error != null) { _isLoading = false; } notifyListeners(); } } // Метод для получения всех контактов (исключая себя) для нового чата Future loadAllContactsForNewChat() async { _isLoading = true; _error = null; notifyListeners(); try { final allContacts = await _repository.fetchAllUsers(); // Фильтруем только исключение самого себя _allContacts = allContacts .where((contact) => contact.id != _currentUserId) .toList(); } catch (e) { _error = e.toString(); } finally { _isLoading = false; notifyListeners(); } } Future _enrichContactsWithLastMessages() async { print("Начинаем обогащать контакты последними сообщениями из локальной БД... Для текущего пользователя ID: $_currentUserId"); final myId = _currentUserId; if (myId == null) return; print("Текущий пользователь ID: $myId"); final myPrivKey = await _cryptoService.getPrivateKey(); final List updated = List.from(_contacts); for (int i = 0; i < updated.length; i++) { final contact = updated[i]; // 1) Если сервер уже прислал lastMessage — попробуем расшифровать превью. print(contact.lastMessage); if (contact.lastMessage != null && contact.lastMessage!.isNotEmpty && myPrivKey != null && contact.publicKey != null) { try { final sharedSecret = await _cryptoService.deriveSharedSecret( myPrivKey, contact.publicKey!, ); final decrypted = await _cryptoService.decryptMessage( contact.lastMessage!, sharedSecret, ); updated[i] = contact.copyWith(lastMessage: decrypted); } catch (_) { // Если расшифровать не удалось — оставляем как есть, дальше попробуем локальную БД. } } } _contacts = updated; _allContacts = updated; notifyListeners(); } }