Files
TravelMate/lib/services/trip_image_service.dart
2025-11-03 15:30:20 +01:00

143 lines
4.6 KiB
Dart

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<void> loadMissingImages(List<Trip> 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<void> _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
if (imageUrl == null) {
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<String?> 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<void> 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<Map<String, dynamic>> 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<void> cleanupDuplicateImages() async {
try {
await _placeImageService.cleanupDuplicateImages();
} catch (e) {
_errorService.logError(
'TripImageService',
'Erreur lors du nettoyage des doublons: $e',
);
}
}
}