import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:geosector_app/core/constants/app_keys.dart';
import 'package:geosector_app/core/services/api_service.dart';
import 'package:geosector_app/core/data/models/client_model.dart';

class ClientRepository extends ChangeNotifier {
  // Utilisation de getters lazy pour n'accéder à la boîte que lorsque nécessaire
  Box<ClientModel> get _clientBox =>
      Hive.box<ClientModel>(AppKeys.clientsBoxName);

  final ApiService _apiService;
  bool _isLoading = false;

  ClientRepository(this._apiService);

  // Getters
  bool get isLoading => _isLoading;

  // Méthode pour vérifier si une boîte est ouverte et l'ouvrir si nécessaire
  Future<void> _ensureBoxIsOpen() async {
    try {
      if (!Hive.isBoxOpen(AppKeys.clientsBoxName)) {
        debugPrint('Ouverture de la boîte clients...');
        await Hive.openBox<ClientModel>(AppKeys.clientsBoxName);
      }
    } catch (e) {
      debugPrint('Erreur lors de l\'ouverture de la boîte clients: $e');
      throw Exception('Impossible d\'ouvrir la boîte clients: $e');
    }
  }

  // Récupérer tous les clients
  List<ClientModel> getAllClients() {
    try {
      _ensureBoxIsOpen();
      return _clientBox.values.toList();
    } catch (e) {
      debugPrint('Erreur lors de la récupération des clients: $e');
      return [];
    }
  }

  // Récupérer un client par son ID
  ClientModel? getClientById(int id) {
    try {
      _ensureBoxIsOpen();
      return _clientBox.get(id);
    } catch (e) {
      debugPrint('Erreur lors de la récupération du client: $e');
      return null;
    }
  }

  // Créer ou mettre à jour un client localement
  Future<ClientModel> saveClient(ClientModel client) async {
    await _ensureBoxIsOpen();
    await _clientBox.put(client.id, client);
    notifyListeners(); // Notifier les changements pour mettre à jour l'UI
    return client;
  }

  // Supprimer un client localement
  Future<void> deleteClient(int id) async {
    await _ensureBoxIsOpen();
    await _clientBox.delete(id);
    notifyListeners();
  }

  // Vider la boîte des clients
  Future<void> clearClients() async {
    await _ensureBoxIsOpen();
    await _clientBox.clear();
    notifyListeners();
  }

  // Traiter les données des clients reçues de l'API
  Future<void> processClientsData(dynamic clientsData) async {
    try {
      debugPrint('Traitement des données des clients...');

      // Vérifier que les données sont au bon format
      if (clientsData == null) {
        debugPrint('Aucune donnée de client à traiter');
        return;
      }

      List<dynamic> clientsList;
      if (clientsData is List) {
        clientsList = clientsData;
      } else if (clientsData is Map && clientsData.containsKey('data')) {
        clientsList = clientsData['data'] as List<dynamic>;
      } else {
        debugPrint('Format de données de clients non reconnu');
        return;
      }

      // Vider la boîte avant d'ajouter les nouvelles données
      await _ensureBoxIsOpen();
      await _clientBox.clear();

      // Traiter chaque client
      int count = 0;
      for (final clientData in clientsList) {
        try {
          final client = ClientModel.fromJson(clientData);
          await _clientBox.put(client.id, client);
          count++;
          debugPrint('Client traité: ${client.name} (ID: ${client.id})');
        } catch (e) {
          debugPrint('Erreur lors du traitement d\'un client: $e');
        }
      }

      debugPrint('$count clients traités et stockés');
      notifyListeners();
    } catch (e) {
      debugPrint('Erreur lors du traitement des clients: $e');
    }
  }

  // Récupérer les clients depuis l'API
  Future<List<ClientModel>> fetchClientsFromApi() async {
    _isLoading = true;
    notifyListeners();

    try {
      final response = await _apiService.get('/clients');

      if (response.statusCode == 200) {
        final clientsData = response.data;
        await processClientsData(clientsData);
        return getAllClients();
      } else {
        debugPrint(
            'Erreur lors de la récupération des clients: ${response.statusCode}');
        return [];
      }
    } catch (e) {
      debugPrint('Erreur lors de la récupération des clients: $e');
      return [];
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  // Filtrer les clients par nom
  List<ClientModel> searchClientsByName(String query) {
    if (query.isEmpty) {
      return getAllClients();
    }

    final lowercaseQuery = query.toLowerCase();
    return _clientBox.values
        .where((client) => client.name.toLowerCase().contains(lowercaseQuery))
        .toList();
  }

  // Filtrer les clients par type
  List<ClientModel> getClientsByType(int type) {
    return _clientBox.values.where((client) => client.fkType == type).toList();
  }

  // Filtrer les clients par région
  List<ClientModel> getClientsByRegion(int regionId) {
    return _clientBox.values
        .where((client) => client.fkRegion == regionId)
        .toList();
  }

  // Filtrer les clients actifs
  List<ClientModel> getActiveClients() {
    return _clientBox.values
        .where((client) => client.chkActive == true)
        .toList();
  }
}
