import 'package:flutter/material.dart';
import '/data/models/contact_model.dart';
import '/data/repositories/contact_repository.dart';
import '/domain/services/crypto_service.dart';
import 'dart:isolate';
import 'package:cryptography/cryptography.dart';
import 'package:flutter/foundation.dart';

class ContactProvider extends ChangeNotifier {
  final ContactRepository _repository = ContactRepository();
  final CryptoService _cryptoService;

  ContactProvider(this._cryptoService);
  final Map<int, SecretKey> _sharedKeysCache = {};
  List<Contact> _contacts = [];
  List<Contact> _allContacts = [];
  bool _isLoading = false;
  bool _isFirstLoad = true;
  String? _error;
  int? _currentUserId;

  List<Contact> get contacts => _contacts;
  List<Contact> get allContacts => _allContacts;
  bool get isLoading => _isLoading;
  String? get error => _error;
  Map<int, SecretKey> get sharedKeysCache => _sharedKeysCache;

  void setSharedKey(int contactId, SecretKey key) {
    _sharedKeysCache[contactId] = key;
  }

  void setCurrentUserId(int? id) {
    _currentUserId = id;
    notifyListeners();
  }

  int? getCurrentUserId() {
    return _currentUserId;
  }

  Future<void> loadContacts({bool enrichContacts = true}) async {
    if (_isFirstLoad) {
      _isFirstLoad = false;
      _isLoading = true;
    }
    _error = null;
    notifyListeners();

    try {
      final allContacts = await _repository.fetchChatContacts();
      final userIdCopy = _currentUserId;
      _contacts = await Isolate.run(() {
        return allContacts
            .where((contact) => contact.id != userIdCopy)
            .toList();
      });
      _allContacts = _contacts;
      _isLoading = false;
      notifyListeners();

      if (enrichContacts) {
        await _enrichContactsWithLastMessages();
      }
    } catch (e) {
      _error = e.toString();
      print("❌ ОШИБКА ПРИ ЗАГРУЗКЕ КОНТАКТОВ: $_error");
    } finally {
      if (_error != null) {
        _isLoading = false;
      }
      notifyListeners();
    }
  }

  Future<void> 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<void> _enrichContactsWithLastMessages() async {
  final myPrivKeyBase64 = await _cryptoService.getPrivateKey();
  if (myPrivKeyBase64 == null) return;

  // Создаем локальные копии для передачи
  final contactsToProcess = List<Contact>.from(_contacts);
  final cacheCopy = Map<int, SecretKey>.from(_sharedKeysCache);

  print('Avialable cache for contacts: ${cacheCopy.length}');

  try {
    final updatedContacts = await compute(
      CryptoService.bulkDecryptContacts,
      {
        'contacts': contactsToProcess,
        'privKey': myPrivKeyBase64,
        'cache': cacheCopy,
      },
    );
    for (var contact in updatedContacts) {
      print('Decrypted contact: ${contact.name} ${contact.surname}, lastMessage: ${contact.lastMessage}, isDecrypted: ${contact.isLastMsgDecrypted}');
    }
    _contacts = updatedContacts;
    notifyListeners();
  } catch (e) {
    print("Ошибка дешифровки: $e");
  }
}

  Future<void> updateContact(int userId) async {
    try {
      final updatedContact = await _repository.fetchContactById(userId);
      final index = _contacts.indexWhere((c) => c.id == userId);
      if (index != -1) {
        // Обновляем только поля профиля, сохраняя lastMessage и т.д.
        final existing = _contacts[index];
        _contacts[index] = existing.copyWith(
          username: updatedContact.username,
          name: updatedContact.name,
          surname: updatedContact.surname,
          avatarUrl: updatedContact.avatarUrl,
          avatarFileId: updatedContact.avatarFileId,
          isOnline: updatedContact.isOnline,
          publicKey: updatedContact.publicKey,
        );
        notifyListeners();
      }
    } catch (e) {
      print("Error updating contact: $e");
    }
  }

}
