import 'package:hive/hive.dart';
import 'package:geosector_app/core/data/models/sector_model.dart';
import 'package:geosector_app/core/services/api_service.dart';
import 'package:geosector_app/core/constants/app_keys.dart';

class SectorRepository {
  final ApiService _apiService;
  
  SectorRepository(this._apiService);
  
  // Utiliser un getter lazy pour n'accéder à la boîte que lorsque nécessaire
  // et vérifier qu'elle est ouverte avant accès
  Box<SectorModel> get _sectorsBox {
    _ensureBoxIsOpen();
    return Hive.box<SectorModel>(AppKeys.sectorsBoxName);
  }
  
  // Méthode pour vérifier si la boîte est ouverte et l'ouvrir si nécessaire
  Future<void> _ensureBoxIsOpen() async {
    final boxName = AppKeys.sectorsBoxName;
    if (!Hive.isBoxOpen(boxName)) {
      print('Ouverture de la boîte $boxName dans SectorRepository...');
      await Hive.openBox<SectorModel>(boxName);
    }
  }
  
  // Récupérer tous les secteurs depuis la base de données locale
  List<SectorModel> getAllSectors() {
    return _sectorsBox.values.toList();
  }
  
  // Récupérer un secteur par son ID
  SectorModel? getSectorById(int id) {
    try {
      return _sectorsBox.values.firstWhere(
        (sector) => sector.id == id,
      );
    } catch (e) {
      return null;
    }
  }
  
  // Sauvegarder les secteurs dans la base de données locale
  Future<void> saveSectors(List<SectorModel> sectors) async {
    // Vider la box avant d'ajouter les nouveaux secteurs
    await _sectorsBox.clear();
    
    // Ajouter les nouveaux secteurs
    for (final sector in sectors) {
      await _sectorsBox.put(sector.id, sector);
    }
  }
  
  // Ajouter ou mettre à jour un secteur
  Future<void> saveSector(SectorModel sector) async {
    await _sectorsBox.put(sector.id, sector);
  }
  
  // Supprimer un secteur
  Future<void> deleteSector(int id) async {
    await _sectorsBox.delete(id);
  }
  
  // Récupérer les secteurs depuis l'API
  Future<List<SectorModel>> fetchSectorsFromApi() async {
    try {
      final response = await _apiService.get(AppKeys.sectorsEndpoint);
      final Map<String, dynamic> responseData = response as Map<String, dynamic>;
      
      if (responseData['status'] == 'success' && responseData['sectors'] != null) {
        final List<dynamic> sectorsJson = responseData['sectors'];
        final List<SectorModel> sectors = sectorsJson
            .map((json) => SectorModel.fromJson(json))
            .toList();
        
        // Sauvegarder les secteurs localement
        await saveSectors(sectors);
        
        return sectors;
      }
      
      return [];
    } catch (e) {
      // En cas d'erreur, retourner les secteurs locaux
      return getAllSectors();
    }
  }
  
  // Créer un nouveau secteur via l'API
  Future<SectorModel?> createSector(SectorModel sector) async {
    try {
      final response = await _apiService.post(
        AppKeys.sectorsEndpoint,
        data: sector.toJson(),
      );
      final Map<String, dynamic> responseData = response as Map<String, dynamic>;
      
      if (responseData['status'] == 'success' && responseData['sector'] != null) {
        final SectorModel newSector = SectorModel.fromJson(responseData['sector']);
        await saveSector(newSector);
        return newSector;
      }
      
      return null;
    } catch (e) {
      return null;
    }
  }
  
  // Mettre à jour un secteur via l'API
  Future<SectorModel?> updateSector(SectorModel sector) async {
    try {
      final response = await _apiService.put(
        '${AppKeys.sectorsEndpoint}/${sector.id}',
        data: sector.toJson(),
      );
      final Map<String, dynamic> responseData = response as Map<String, dynamic>;
      
      if (responseData['status'] == 'success' && responseData['sector'] != null) {
        final SectorModel updatedSector = SectorModel.fromJson(responseData['sector']);
        await saveSector(updatedSector);
        return updatedSector;
      }
      
      return null;
    } catch (e) {
      return null;
    }
  }
  
  // Supprimer un secteur via l'API
  Future<bool> deleteSectorFromApi(int id) async {
    try {
      final response = await _apiService.delete(
        '${AppKeys.sectorsEndpoint}/$id',
      );
      final Map<String, dynamic> responseData = response as Map<String, dynamic>;
      
      if (responseData['status'] == 'success') {
        await deleteSector(id);
        return true;
      }
      
      return false;
    } catch (e) {
      return false;
    }
  }
}
