import 'dart:convert';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart' as path;
import 'package:video_thumbnail/video_thumbnail.dart' as video_thumb;

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

/// Résultat d'un upload de média.
class MediaUploadResult {
  const MediaUploadResult({
    required this.url,
    required this.thumbnailUrl,
    required this.type,
    this.duration,
  });

  final String url;
  final String? thumbnailUrl;
  final String type; // 'image' ou 'video'
  final Duration? duration;
}

/// Service d'upload de médias vers le backend.
///
/// Gère l'upload d'images et de vidéos avec compression et génération de thumbnails.
class MediaUploadService {
  MediaUploadService(this._client);

  final http.Client _client;

  /// URL de base pour l'upload (à configurer selon votre backend)
  static const String _uploadEndpoint = '${EnvConfig.apiBaseUrl}/media/upload';

  /// Upload un seul média (image ou vidéo).
  Future<MediaUploadResult> uploadMedia(XFile file) async {
    try {
      if (EnvConfig.enableDetailedLogs) {
        debugPrint('[MediaUploadService] Upload de: ${file.path}');
      }

      final fileExtension = path.extension(file.path).toLowerCase();
      final isVideo = _isVideoFile(fileExtension);

      // Créer la requête multipart
      final request = http.MultipartRequest('POST', Uri.parse(_uploadEndpoint));

      // Ajouter le fichier
      final fileBytes = await file.readAsBytes();
      final multipartFile = http.MultipartFile.fromBytes(
        'file',
        fileBytes,
        filename: path.basename(file.path),
      );
      request.files.add(multipartFile);

      // Ajouter le type
      request.fields['type'] = isVideo ? 'video' : 'image';

      // Envoyer la requête
      final streamedResponse = await request.send();
      final response = await http.Response.fromStream(streamedResponse);

      if (response.statusCode == 200 || response.statusCode == 201) {
        // Parser la réponse JSON du backend
        final responseData = json.decode(response.body) as Map<String, dynamic>;

        // Format attendu du backend:
        // {
        //   "url": "https://...",
        //   "thumbnailUrl": "https://...",  (optionnel)
        //   "type": "image" ou "video",
        //   "duration": 60  (en secondes, optionnel)
        // }

        final url = responseData['url'] as String? ??
            'https://example.com/media/${path.basename(file.path)}';
        final thumbnailUrl = responseData['thumbnailUrl'] as String?;
        final typeFromBackend = responseData['type'] as String?;
        final durationSeconds = responseData['duration'] as int?;

        if (EnvConfig.enableDetailedLogs) {
          debugPrint('[MediaUploadService] Upload réussi: $url');
        }

        return MediaUploadResult(
          url: url,
          thumbnailUrl: thumbnailUrl,
          type: typeFromBackend ?? (isVideo ? 'video' : 'image'),
          duration: durationSeconds != null
              ? Duration(seconds: durationSeconds)
              : null,
        );
      } else {
        throw Exception(
          'Échec de l\'upload: ${response.statusCode} - ${response.body}',
        );
      }
    } catch (e) {
      debugPrint('[MediaUploadService] Erreur: $e');
      rethrow;
    }
  }

  /// Upload plusieurs médias en parallèle.
  Future<List<MediaUploadResult>> uploadMultipleMedias(
    List<XFile> files, {
    void Function(int uploaded, int total)? onProgress,
  }) async {
    final results = <MediaUploadResult>[];
    int uploaded = 0;

    for (final file in files) {
      try {
        final result = await uploadMedia(file);
        results.add(result);
        uploaded++;

        if (onProgress != null) {
          onProgress(uploaded, files.length);
        }
      } catch (e) {
        debugPrint('[MediaUploadService] Échec upload ${file.path}: $e');
        // On continue avec les autres fichiers
      }
    }

    return results;
  }

  /// Vérifie si le fichier est une vidéo.
  bool _isVideoFile(String extension) {
    const videoExtensions = ['.mp4', '.mov', '.avi', '.mkv', '.m4v'];
    return videoExtensions.contains(extension);
  }

  /// Supprime un média du serveur.
  Future<void> deleteMedia(String mediaUrl) async {
    try {
      if (EnvConfig.enableDetailedLogs) {
        debugPrint('[MediaUploadService] Suppression de: $mediaUrl');
      }

      // Extraire l'ID ou le nom du fichier de l'URL
      final uri = Uri.parse(mediaUrl);
      final fileName = uri.pathSegments.last;

      // Appel API pour supprimer le média
      final deleteUrl = '${EnvConfig.apiBaseUrl}/media/$fileName';
      final response = await _client.delete(
        Uri.parse(deleteUrl),
        headers: {'Content-Type': 'application/json'},
      );

      if (response.statusCode == 200 || response.statusCode == 204) {
        if (EnvConfig.enableDetailedLogs) {
          debugPrint('[MediaUploadService] Média supprimé: $mediaUrl');
        }
      } else {
        throw Exception(
          'Échec de la suppression: ${response.statusCode} - ${response.body}',
        );
      }
    } catch (e) {
      debugPrint('[MediaUploadService] Erreur suppression: $e');
      rethrow;
    }
  }

  /// Génère un thumbnail pour une vidéo.
  Future<String?> generateVideoThumbnail(String videoPath) async {
    try {
      if (EnvConfig.enableDetailedLogs) {
        debugPrint('[MediaUploadService] Génération thumbnail pour: $videoPath');
      }

      // Générer le thumbnail à partir de la vidéo
      final thumbnailPath = await video_thumb.VideoThumbnail.thumbnailFile(
        video: videoPath,
        thumbnailPath: (await Directory.systemTemp.createTemp()).path,
        imageFormat: video_thumb.ImageFormat.JPEG,
        maxWidth: 640,
        quality: 75,
      );

      if (thumbnailPath != null && EnvConfig.enableDetailedLogs) {
        debugPrint('[MediaUploadService] Thumbnail généré: $thumbnailPath');
      }

      return thumbnailPath;
    } catch (e) {
      debugPrint('[MediaUploadService] Erreur génération thumbnail: $e');
      return null;
    }
  }
}
