import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';

import '../../core/constants/env_config.dart';

/// Configuration de compression d'image.
class CompressionConfig {
  const CompressionConfig({
    this.quality = 85,
    this.maxWidth = 1920,
    this.maxHeight = 1920,
    this.format = CompressFormat.jpeg,
  });

  final int quality; // 0-100
  final int maxWidth;
  final int maxHeight;
  final CompressFormat format;

  /// Configuration pour les posts (équilibre qualité/taille)
  static const CompressionConfig post = CompressionConfig(
    quality: 85,
    maxWidth: 1920,
    maxHeight: 1920,
  );

  /// Configuration pour les thumbnails (petite taille)
  static const CompressionConfig thumbnail = CompressionConfig(
    quality: 70,
    maxWidth: 400,
    maxHeight: 400,
  );

  /// Configuration pour les stories (vertical, haute qualité)
  static const CompressionConfig story = CompressionConfig(
    quality: 90,
    maxWidth: 1080,
    maxHeight: 1920,
  );

  /// Configuration pour les avatars (petit, carré)
  static const CompressionConfig avatar = CompressionConfig(
    quality: 80,
    maxWidth: 500,
    maxHeight: 500,
  );
}

/// Service de compression d'images.
///
/// Compresse les images avant l'upload pour réduire la bande passante
/// et améliorer les performances.
class ImageCompressionService {
  /// Compresse une image selon la configuration donnée.
  Future<XFile?> compressImage(
    XFile file, {
    CompressionConfig config = CompressionConfig.post,
  }) async {
    try {
      final filePath = file.path;
      final lastIndex = filePath.lastIndexOf('.');
      final splitted = filePath.substring(0, lastIndex);
      final outPath = '${splitted}_compressed${path.extension(filePath)}';

      if (EnvConfig.enableDetailedLogs) {
        final originalSize = await File(filePath).length();
        debugPrint('[ImageCompression] Compression de: ${path.basename(filePath)}');
        debugPrint('[ImageCompression] Taille originale: ${_formatBytes(originalSize)}');
      }

      final result = await FlutterImageCompress.compressAndGetFile(
        filePath,
        outPath,
        quality: config.quality,
        minWidth: config.maxWidth,
        minHeight: config.maxHeight,
        format: config.format,
      );

      if (result != null) {
        if (EnvConfig.enableDetailedLogs) {
          final compressedSize = await File(result.path).length();
          final originalSize = await File(filePath).length();
          final reduction = ((1 - compressedSize / originalSize) * 100).toStringAsFixed(1);
          debugPrint('[ImageCompression] Taille compressée: ${_formatBytes(compressedSize)}');
          debugPrint('[ImageCompression] Réduction: $reduction%');
        }

        return result;
      }

      return null;
    } catch (e) {
      debugPrint('[ImageCompression] Erreur: $e');
      // En cas d'erreur, on retourne le fichier original
      return file;
    }
  }

  /// Compresse plusieurs images en parallèle.
  Future<List<XFile>> compressMultipleImages(
    List<XFile> files, {
    CompressionConfig config = CompressionConfig.post,
    void Function(int processed, int total)? onProgress,
  }) async {
    final results = <XFile>[];
    int processed = 0;

    for (final file in files) {
      // Ne compresser que les images, pas les vidéos
      if (_isImageFile(file.path)) {
        final compressed = await compressImage(file, config: config);
        results.add(compressed ?? file);
      } else {
        results.add(file);
      }

      processed++;
      if (onProgress != null) {
        onProgress(processed, files.length);
      }
    }

    return results;
  }

  /// Crée un thumbnail à partir d'une image.
  Future<XFile?> createThumbnail(XFile file) async {
    return compressImage(file, config: CompressionConfig.thumbnail);
  }

  /// Vérifie si le fichier est une image.
  bool _isImageFile(String filePath) {
    const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'];
    final extension = path.extension(filePath).toLowerCase();
    return imageExtensions.contains(extension);
  }

  /// Formate la taille en bytes de manière lisible.
  String _formatBytes(int bytes) {
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    if (bytes < 1024 * 1024 * 1024) {
      return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
    }
    return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
  }

  /// Nettoie les fichiers temporaires compressés.
  Future<void> cleanupTempFiles() async {
    try {
      final tempDir = await getTemporaryDirectory();
      final files = tempDir.listSync();

      for (final file in files) {
        if (file.path.contains('_compressed')) {
          await file.delete();
        }
      }

      if (EnvConfig.enableDetailedLogs) {
        debugPrint('[ImageCompression] Fichiers temporaires nettoyés');
      }
    } catch (e) {
      debugPrint('[ImageCompression] Erreur nettoyage: $e');
    }
  }
}
