import 'package:travel_mate/models/trip.dart'; import 'package:travel_mate/services/place_image_service.dart'; import 'package:travel_mate/repositories/trip_repository.dart'; import 'package:travel_mate/services/error_service.dart'; /// Service pour gérer le chargement automatique des images des voyages class TripImageService { final PlaceImageService _placeImageService = PlaceImageService(); final TripRepository _tripRepository = TripRepository(); final ErrorService _errorService = ErrorService(); /// Charge les images manquantes pour une liste de voyages Future loadMissingImages(List trips) async { final tripsWithoutImage = trips .where((trip) => trip.imageUrl == null || trip.imageUrl!.isEmpty) .toList(); if (tripsWithoutImage.isEmpty) { return; } for (final trip in tripsWithoutImage) { try { await _loadImageForTrip(trip); // Petite pause entre les requêtes pour éviter de surcharger l'API await Future.delayed(const Duration(milliseconds: 500)); } catch (e) { _errorService.logError( 'TripImageService', 'Erreur lors du chargement d\'image pour ${trip.title}: $e', ); } } } /// Charge l'image pour un voyage spécifique Future _loadImageForTrip(Trip trip) async { // D'abord vérifier si une image existe déjà dans le Storage String? imageUrl = await _placeImageService.getExistingImageUrl( trip.location, ); // Si aucune image n'existe, en télécharger une nouvelle imageUrl ??= await _placeImageService.getPlaceImageUrl(trip.location); if (imageUrl != null && trip.id != null) { // Mettre à jour le voyage avec l'image (existante ou nouvelle) final updatedTrip = trip.copyWith( imageUrl: imageUrl, updatedAt: DateTime.now(), ); await _tripRepository.updateTrip(trip.id!, updatedTrip); } else {} } /// Recharge l'image d'un voyage spécifique (force le rechargement) Future reloadImageForTrip(Trip trip) async { try { final imageUrl = await _placeImageService.getPlaceImageUrl(trip.location); if (imageUrl != null && trip.id != null) { final updatedTrip = trip.copyWith( imageUrl: imageUrl, updatedAt: DateTime.now(), ); await _tripRepository.updateTrip(trip.id!, updatedTrip); return imageUrl; } return null; } catch (e) { _errorService.logError( 'TripImageService', 'Erreur lors du rechargement d\'image pour ${trip.title}: $e', ); return null; } } /// Nettoie les images inutilisées du stockage Future cleanupUnusedImages(String userId) async { try { // Récupérer tous les voyages de l'utilisateur final tripsStream = _tripRepository.getTripsByUserId(userId); final trips = await tripsStream.first; // Extraire toutes les URLs d'images utilisées final usedImageUrls = trips .where((trip) => trip.imageUrl != null && trip.imageUrl!.isNotEmpty) .map((trip) => trip.imageUrl!) .toList(); // Nettoyer les images inutilisées await _placeImageService.cleanupUnusedImages(usedImageUrls); } catch (e) { _errorService.logError( 'TripImageService', 'Erreur lors du nettoyage des images: $e', ); } } /// Obtient des statistiques sur les images stockées Future> getImageStatistics(String userId) async { try { final tripsStream = _tripRepository.getTripsByUserId(userId); final trips = await tripsStream.first; final tripsWithImages = trips .where((trip) => trip.imageUrl != null && trip.imageUrl!.isNotEmpty) .length; final tripsWithoutImages = trips.length - tripsWithImages; return { 'totalTrips': trips.length, 'tripsWithImages': tripsWithImages, 'tripsWithoutImages': tripsWithoutImages, 'timestamp': DateTime.now().toIso8601String(), }; } catch (e) { _errorService.logError( 'TripImageService', 'Erreur lors de l\'obtention des statistiques: $e', ); return { 'error': e.toString(), 'timestamp': DateTime.now().toIso8601String(), }; } } /// Nettoie spécifiquement les doublons d'images Future cleanupDuplicateImages() async { try { await _placeImageService.cleanupDuplicateImages(); } catch (e) { _errorService.logError( 'TripImageService', 'Erreur lors du nettoyage des doublons: $e', ); } } }