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<void> _ensureCacheReady() async {
    if (!_isCacheInitialized) {
      await _apiService.cache.initialize();
      _isCacheInitialized = true;
    }
  }

  Future<List<Contact>> fetchChatContacts({bool forceRefresh = false}) async {
    final token = await _apiService.getAccessToken();

    DateTime now = DateTime.now();
    Duration offset = now.timeZoneOffset;

    final Map<String, String> 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<dynamic> 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<dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
        return data.map((json) => Contact.fromJson(json)).toList();
      } catch (cacheError) {
        throw Exception('Нет доступа к сети. Проверте подключение к интернету.');
      }
    }
  }

  Future<List<Contact>> 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<String, String> 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<dynamic> 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<Contact> fetchContactById(
    int userId, {
    bool forceRefresh = false,
  }) async {
    final token = await _apiService.getAccessToken();

    final Map<String, String> 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<List<Map<String, dynamic>>> 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<String, String> 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<dynamic> data = jsonDecode(utf8.decode(response.bodyBytes));
      return data.map((item) => item as Map<String, dynamic>).toList();
    } else {
      throw Exception('Failed to load last messages');
    }
  }
}
