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
    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',
      );
    }
  }
}
