import 'dart:io'; import 'package:dio/dio.dart'; import 'package:http_parser/http_parser.dart'; import 'package:injectable/injectable.dart'; import '../../../../core/config/environment.dart'; import '../../../../core/utils/logger.dart'; /// Service pour uploader des documents (pièces justificatives LCB-FT) @lazySingleton class DocumentUploadService { final Dio _dio; DocumentUploadService(this._dio); /// Upload un fichier vers le backend /// Retourne l'ID du document créé Future uploadDocument({ required File file, String? description, String typeDocument = 'PIECE_JUSTIFICATIVE', }) async { try { final fileName = file.path.split('/').last; final fileExtension = fileName.split('.').last.toLowerCase(); // Déterminer le type MIME String contentType; if (fileExtension == 'pdf') { contentType = 'application/pdf'; } else if (fileExtension == 'jpg' || fileExtension == 'jpeg') { contentType = 'image/jpeg'; } else if (fileExtension == 'png') { contentType = 'image/png'; } else if (fileExtension == 'gif') { contentType = 'image/gif'; } else { throw Exception('Type de fichier non supporté: .$fileExtension'); } // Vérifier la taille (max 5 MB) final fileSize = await file.length(); const maxSize = 5 * 1024 * 1024; // 5 MB if (fileSize > maxSize) { throw Exception('Fichier trop volumineux. Taille max: 5 MB'); } // Créer le FormData final formData = FormData.fromMap({ 'file': await MultipartFile.fromFile( file.path, filename: fileName, contentType: MediaType.parse(contentType), ), if (description != null && description.isNotEmpty) 'description': description, 'typeDocument': typeDocument, }); AppLogger.debug('Upload de $fileName (${_formatBytes(fileSize)})'); final response = await _dio.post( '${AppConfig.apiBaseUrl}/documents/upload', data: formData, options: Options( headers: { 'Content-Type': 'multipart/form-data', }, ), ); if (response.statusCode == 201 && response.data != null) { final documentId = response.data['id'] as String; AppLogger.info('Document uploadé avec succès: $documentId'); return documentId; } else { throw Exception('Erreur lors de l\'upload: ${response.statusCode}'); } } on DioException catch (e) { AppLogger.error('Erreur Dio lors de l\'upload: ${e.message}', error: e); if (e.response?.data != null && e.response!.data['error'] != null) { throw Exception(e.response!.data['error']); } throw Exception('Erreur réseau lors de l\'upload'); } catch (e) { AppLogger.error('Erreur lors de l\'upload du document', error: e); rethrow; } } String _formatBytes(int bytes) { if (bytes < 1024) { return '$bytes B'; } else if (bytes < 1024 * 1024) { return '${(bytes / 1024).toStringAsFixed(2)} KB'; } else { return '${(bytes / (1024 * 1024)).toStringAsFixed(2)} MB'; } } }