import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.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/membre_model.dart';

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

  final ApiService _apiService;
  bool _isLoading = false;

  MembreRepository(this._apiService);

  // Getters
  bool get isLoading => _isLoading;
  List<MembreModel> get membres => getAllMembres();

  // 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.membresBoxName)) {
        debugPrint('Ouverture de la boîte ${AppKeys.membresBoxName}...');
        await Hive.openBox<MembreModel>(AppKeys.membresBoxName);
        debugPrint('Boîte ${AppKeys.membresBoxName} ouverte avec succès');
      }
    } catch (e) {
      debugPrint(
          'Erreur lors de l\'ouverture de la boîte ${AppKeys.membresBoxName}: $e');
      throw Exception(
          'Impossible d\'ouvrir la boîte ${AppKeys.membresBoxName}: $e');
    }
  }

  // Récupérer tous les membres
  List<MembreModel> getAllMembres() {
    try {
      return _membreBox.values.toList();
    } catch (e) {
      debugPrint('Erreur lors de la récupération des membres: $e');
      return [];
    }
  }

  // Récupérer un membre par son ID
  MembreModel? getMembreById(int id) {
    try {
      return _membreBox.get(id);
    } catch (e) {
      debugPrint('Erreur lors de la récupération du membre: $e');
      return null;
    }
  }

  // Créer ou mettre à jour un membre
  Future<MembreModel> saveMembre(MembreModel membre) async {
    await _ensureBoxIsOpen();
    await _membreBox.put(membre.id, membre);
    notifyListeners();
    return membre;
  }

  // Supprimer un membre
  Future<void> deleteMembre(int id) async {
    await _ensureBoxIsOpen();
    await _membreBox.delete(id);
    notifyListeners();
  }

  // Récupérer les membres depuis l'API (uniquement pour l'interface admin)
  Future<List<MembreModel>> fetchMembresFromApi() async {
    _isLoading = true;
    notifyListeners();

    try {
      final hasConnection = await _apiService.hasInternetConnection();
      if (!hasConnection) {
        debugPrint(
            'Pas de connexion Internet, utilisation des données locales');
        return getAllMembres();
      }

      // Endpoint à adapter selon votre API
      final response = await _apiService.get('/membres');
      final List<dynamic> membresData = response.data['membres'];

      // Vider la boîte avant d'ajouter les nouveaux membres
      await _ensureBoxIsOpen();
      await _membreBox.clear();

      final List<MembreModel> membres = [];
      for (var membreData in membresData) {
        try {
          final membre = MembreModel.fromJson(membreData);
          await _membreBox.put(membre.id, membre);
          membres.add(membre);
        } catch (e) {
          debugPrint('Erreur lors du traitement d\'un membre: $e');
          continue;
        }
      }

      notifyListeners();
      return membres;
    } catch (e) {
      debugPrint(
          'Erreur lors de la récupération des membres depuis l\'API: $e');
      return getAllMembres();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  // Créer un membre via l'API
  Future<MembreModel?> createMembreViaApi(MembreModel membre) async {
    _isLoading = true;
    notifyListeners();

    try {
      final hasConnection = await _apiService.hasInternetConnection();
      if (!hasConnection) {
        debugPrint('Pas de connexion Internet, impossible de créer le membre');
        return null;
      }

      // Endpoint à adapter selon votre API
      final response =
          await _apiService.post('/membres', data: membre.toJson());
      final membreData = response.data['membre'];

      final newMembre = MembreModel.fromJson(membreData);
      await saveMembre(newMembre);

      return newMembre;
    } catch (e) {
      debugPrint('Erreur lors de la création du membre via l\'API: $e');
      return null;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  // Mettre à jour un membre via l'API
  Future<MembreModel?> updateMembreViaApi(MembreModel membre) async {
    _isLoading = true;
    notifyListeners();

    try {
      final hasConnection = await _apiService.hasInternetConnection();
      if (!hasConnection) {
        debugPrint(
            'Pas de connexion Internet, impossible de mettre à jour le membre');
        return null;
      }

      // Endpoint à adapter selon votre API
      final response =
          await _apiService.put('/membres/${membre.id}', data: membre.toJson());
      final membreData = response.data['membre'];

      final updatedMembre = MembreModel.fromJson(membreData);
      await saveMembre(updatedMembre);

      return updatedMembre;
    } catch (e) {
      debugPrint('Erreur lors de la mise à jour du membre via l\'API: $e');
      return null;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  // Supprimer un membre via l'API
  Future<bool> deleteMembreViaApi(int id) async {
    _isLoading = true;
    notifyListeners();

    try {
      final hasConnection = await _apiService.hasInternetConnection();
      if (!hasConnection) {
        debugPrint(
            'Pas de connexion Internet, impossible de supprimer le membre');
        return false;
      }

      // Endpoint à adapter selon votre API
      await _apiService.delete('/membres/$id');

      // Supprimer localement
      await deleteMembre(id);

      return true;
    } catch (e) {
      debugPrint('Erreur lors de la suppression du membre via l\'API: $e');
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
}
