import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:cb_prestige_qr/features/scan/scan_providers.dart'; part 'scan_controller.g.dart'; class ScanState { const ScanState({ this.isScanning = true, this.isProcessing = false, this.isSubmitting = false, this.scannedValue, this.errorMessage, }); final bool isScanning; final bool isProcessing; final bool isSubmitting; final String? scannedValue; final String? errorMessage; static const _sentinel = Object(); ScanState copyWith({ bool? isScanning, bool? isProcessing, bool? isSubmitting, Object? scannedValue = _sentinel, Object? errorMessage = _sentinel, }) { return ScanState( isScanning: isScanning ?? this.isScanning, isProcessing: isProcessing ?? this.isProcessing, isSubmitting: isSubmitting ?? this.isSubmitting, scannedValue: identical(scannedValue, _sentinel) ? this.scannedValue : scannedValue as String?, errorMessage: identical(errorMessage, _sentinel) ? this.errorMessage : errorMessage as String?, ); } } @riverpod class ScanController extends _$ScanController { @override ScanState build() => const ScanState(); Future onBarcodeDetected(String value) async { if (!state.isScanning || state.isProcessing) return; state = state.copyWith( isScanning: false, isProcessing: true, errorMessage: null, ); try { final result = await ref.read(processScanUseCaseProvider)(value); state = state.copyWith( isProcessing: false, scannedValue: result.rawValue, ); } catch (e) { state = state.copyWith( isProcessing: false, isScanning: true, scannedValue: null, errorMessage: e.toString(), ); } } Future submitScannedValue(String value) async { if (state.isSubmitting) return; state = state.copyWith(isSubmitting: true, errorMessage: null); try { await ref.read(scanRepositoryProvider).submitScan(value); state = state.copyWith( isSubmitting: false, scannedValue: null, errorMessage: null, ); } catch (e) { state = state.copyWith(isSubmitting: false, errorMessage: e.toString()); rethrow; } } void resumeScanning() { state = const ScanState( isScanning: true, isProcessing: false, isSubmitting: false, scannedValue: null, errorMessage: null, ); } }