import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/core/blocs/session/session_cubit.dart'; import 'package:flux/features/operations/data/operations_repository.dart'; import 'package:flux/features/operations/models/operation_model.dart'; import 'package:get_it/get_it.dart'; import 'package:uuid/uuid.dart'; part 'operation_form_state.dart'; class OperationFormCubit extends Cubit { final OperationsRepository _repository = GetIt.I(); final SessionCubit _sessionCubit = GetIt.I(); final Uuid _uuid = const Uuid(); OperationFormCubit() : super( OperationFormState( // Inizializziamo con un modello vuoto di sicurezza operation: OperationModel( storeId: '', companyId: '', reference: '', status: OperationStatus.draft, createdAt: DateTime.now(), ), ), ); Future initForm({ OperationModel? existingOperation, String? operationId, }) async { emit(state.copyWith(status: OperationFormStatus.loading)); try { if (existingOperation != null) { emit( state.copyWith( operation: existingOperation, status: OperationFormStatus.ready, ), ); } else if (operationId != null) { // Avendo separato i cubit, se ci passano solo l'ID lo scarichiamo dal DB final operation = await _repository.fetchOperationById(operationId); emit( state.copyWith( operation: operation, status: OperationFormStatus.ready, ), ); } else { // NUOVA PRATICA: Creiamo un nuovo Batch UUID emit( state.copyWith( operation: OperationModel( storeId: _sessionCubit.state.currentStore?.id ?? '', reference: '', createdAt: DateTime.now(), companyId: _sessionCubit.state.company!.id!, status: OperationStatus.draft, batchUuid: _uuid.v4(), ), status: OperationFormStatus.ready, ), ); } } catch (e) { emit( state.copyWith( status: OperationFormStatus.failure, errorMessage: "Errore inizializzazione form: $e", ), ); } } // --- LOGICA BATCH --- void _prepareNextOperationInBatch() { final current = state.operation; emit( state.copyWith( status: OperationFormStatus.ready, // Torna ready per il nuovo form operation: OperationModel( companyId: current.companyId, storeId: current.storeId, storeDisplayName: current.storeDisplayName, batchUuid: current.batchUuid, // MANTIENE IL COLLEGAMENTO customerId: current.customerId, // MANTIENE IL CLIENTE customerDisplayName: current.customerDisplayName, status: OperationStatus.draft, createdAt: DateTime.now(), ), ), ); } // --- SALVATAGGIO --- Future saveOperation({ required OperationStatus targetStatus, required bool keepAdding, }) async { emit( state.copyWith(status: OperationFormStatus.saving, errorMessage: null), ); try { final operationToSave = state.operation.copyWith(status: targetStatus); final savedOperation = await _repository.saveFullOperation( operation: operationToSave, ); if (keepAdding) { // Salviamo nella "memoria" del batch le pratiche create finora final updatedBatchList = List.from( state.savedBatchOperations, )..add(savedOperation); emit( state.copyWith( status: OperationFormStatus.successAndAddAnother, savedBatchOperations: updatedBatchList, ), ); // Pulisce i campi per la prossima operazione _prepareNextOperationInBatch(); } else { emit( state.copyWith( status: OperationFormStatus.success, operation: savedOperation, // Aggiorniamo con l'ID restituito dal DB ), ); } } catch (e) { emit( state.copyWith( status: OperationFormStatus.failure, errorMessage: e.toString(), ), ); } } Future saveOperationDraft() async { try { final operationToSave = state.operation; if (operationToSave.customerId == null || operationToSave.customerId!.isEmpty) { throw Exception('Seleziona un cliente prima di poter usare il QR'); } final savedOperation = await _repository.saveFullOperation( operation: operationToSave, ); emit( state.copyWith( operation: savedOperation, status: OperationFormStatus.ready, ), ); return savedOperation.id; } catch (e) { emit( state.copyWith( status: OperationFormStatus.failure, errorMessage: e.toString(), ), ); return null; } } // --- GESTIONE DEI CAMPI IN TEMPO REALE --- void updateFields({ String? customerId, String? customerDisplayName, String? reference, String? note, String? type, String? providerId, String? providerDisplayName, String? subtype, String? description, DateTime? expirationDate, int? quantity, String? modelId, String? modelDisplayName, String? staffId, String? staffDisplayName, OperationStatus? status, bool clearProvider = false, bool clearType = false, bool clearSubtype = false, bool clearDescription = false, bool clearExpiration = false, bool clearQuantity = false, bool clearModel = false, }) { final current = state.operation; int? newQuantity; if (clearQuantity) newQuantity = 1; if (quantity != null && quantity <= 0) newQuantity = 0; if (quantity != null && quantity > 0) newQuantity = quantity; final updated = current.copyWith( customerId: customerId ?? current.customerId, // Se non passo customerId, tengo il vecchio customerDisplayName: customerDisplayName ?? current.customerDisplayName, reference: reference ?? current.reference, note: note ?? current.note, providerId: clearProvider ? null : (providerId ?? current.providerId), providerDisplayName: clearProvider ? null : (providerDisplayName ?? current.providerDisplayName), quantity: newQuantity ?? current.quantity, type: clearType ? null : (type ?? current.type), description: clearDescription ? null : (description ?? current.description), subtype: clearSubtype ? null : (subtype ?? current.subtype), expirationDate: clearExpiration ? null : (expirationDate ?? current.expirationDate), modelId: clearModel ? null : (modelId ?? current.modelId), modelDisplayName: clearModel ? null : (modelDisplayName ?? current.modelDisplayName), staffId: staffId ?? current.staffId, staffDisplayName: staffDisplayName ?? current.staffDisplayName, status: status ?? current.status, ); emit(state.copyWith(operation: updated)); } // --- UTILS --- void setTypeWithSmartDefault(String type) { DateTime? defaultDate; final now = DateTime.now(); if (type == 'Energy') { defaultDate = DateTime(now.year, now.month + 24, now.day); } if (type == 'Fin') { defaultDate = DateTime(now.year, now.month + 30, now.day); } if (type == 'Entertainment') { defaultDate = DateTime(now.year, now.month + 12, now.day); } updateFields( type: type, expirationDate: defaultDate, clearProvider: true, clearSubtype: true, clearModel: true, clearQuantity: true, ); } }