import 'dart:async'; import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flux/features/customers/data/customer_repository.dart'; import 'package:flux/features/customers/models/customer_file_model.dart'; import 'package:get_it/get_it.dart'; part 'customer_files_events.dart'; part 'customer_files_state.dart'; class CustomerFilesBloc extends Bloc { final CustomerRepository _repository = GetIt.I(); final String customerId; CustomerFilesBloc(this.customerId) : super(const CustomerFilesState(status: CustomerFilesStatus.initial)) { on(_loadCustomerFiles); on(_uploadCustomerFile); on(_uploadMultipleCustomerFiles); on(_deleteCustomerFiles); on(_toggleCustomerFileSelection); } void _loadCustomerFiles( LoadCustomerFilesEvent event, Emitter emit, ) async { await emit.forEach>( _repository.getCustomerFilesStream(customerId), onData: (customerFiles) => CustomerFilesState( status: CustomerFilesStatus.success, customerFiles: customerFiles, ), onError: (error, stackTrace) => CustomerFilesState( status: CustomerFilesStatus.failure, error: error.toString(), ), ); } Future _uploadCustomerFile( UploadCustomerFileEvent event, Emitter emit, ) async { emit(state.copyWith(status: CustomerFilesStatus.uploading)); if (event.pickedFile != null) { try { await _repository.uploadAndRegisterFile( customerId: customerId, pickedFile: event.pickedFile!, ); emit(state.copyWith(status: CustomerFilesStatus.success)); } catch (e) { emit( state.copyWith( status: CustomerFilesStatus.failure, error: e.toString(), ), ); } } } FutureOr _uploadMultipleCustomerFiles( UploadMultipleCustomerFilesEvent event, Emitter emit, ) async { if (event.files.isEmpty) { emit( state.copyWith( status: CustomerFilesStatus.failure, error: "Nessun file selezionato", ), ); return; } emit(state.copyWith(status: CustomerFilesStatus.uploading, error: null)); try { // 2. Creiamo una lista di "Promesse" (Futures) per il repository final List> uploadTasks = []; for (var file in event.files) { // Aggiungiamo il task alla lista, ma NON usiamo await qui dentro! uploadTasks.add( _repository.uploadAndRegisterFile( customerId: customerId, pickedFile: file, ), ); } // 3. ESECUZIONE PARALLELA! // Aspettiamo che tutti i file siano caricati contemporaneamente. await Future.wait(uploadTasks); // 4. GRAN FINALE: Tutto caricato, emettiamo il success! emit(state.copyWith(status: CustomerFilesStatus.success)); } catch (e) { // Se anche un solo file fallisce, catturiamo l'errore emit( state.copyWith( status: CustomerFilesStatus.failure, error: "Errore durante l'upload multiplo: $e", ), ); } } Future _deleteCustomerFiles( DeleteCustomerFilesEvent event, Emitter emit, ) async { emit(state.copyWith(status: CustomerFilesStatus.loading)); try { await _repository.deleteDocuments(state.selectedFiles); emit( state.copyWith(status: CustomerFilesStatus.success, selectedFiles: []), ); } catch (e) { emit( state.copyWith( status: CustomerFilesStatus.failure, error: e.toString(), ), ); } } void _toggleCustomerFileSelection( ToggleCustomerFileSelectionEvent event, Emitter emit, ) { List selectedFiles = List.from(state.selectedFiles); if (selectedFiles.contains(event.file)) { selectedFiles.remove(event.file); } else { selectedFiles.add(event.file); } emit(state.copyWith(selectedFiles: selectedFiles)); } }