import '../../../../core/network/api_client.dart'; import '../../../../core/errors/exceptions.dart'; import '../models/save_request_model.dart'; /// Abstract remote data source for scanner operations abstract class ScannerRemoteDataSource { /// Save scan data to remote server Future saveScan(SaveRequestModel request); /// Get scan data from remote server (optional for future use) Future?> getScanData(String barcode); } /// Implementation of ScannerRemoteDataSource using HTTP API class ScannerRemoteDataSourceImpl implements ScannerRemoteDataSource { final ApiClient apiClient; ScannerRemoteDataSourceImpl({required this.apiClient}); @override Future saveScan(SaveRequestModel request) async { try { // Validate request before sending if (!request.isValid) { throw ValidationException('Invalid request data: ${request.validationErrors.join(', ')}'); } final response = await apiClient.post( '/api/scans', data: request.toJson(), ); // Check if the response indicates success if (response.statusCode == null || (response.statusCode! < 200 || response.statusCode! >= 300)) { final errorMessage = response.data?['message'] ?? 'Unknown server error'; throw ServerException('Failed to save scan: $errorMessage'); } // Log successful save (in production, use proper logging) // print('Scan saved successfully: ${request.barcode}'); } on ValidationException { rethrow; } on ServerException { rethrow; } on NetworkException { rethrow; } catch (e) { // Handle any unexpected errors throw ServerException('Unexpected error occurred while saving scan: ${e.toString()}'); } } @override Future?> getScanData(String barcode) async { try { if (barcode.trim().isEmpty) { throw const ValidationException('Barcode cannot be empty'); } final response = await apiClient.get( '/api/scans/$barcode', ); if (response.statusCode == 404) { // Scan not found is not an error, just return null return null; } if (response.statusCode == null || (response.statusCode! < 200 || response.statusCode! >= 300)) { final errorMessage = response.data?['message'] ?? 'Unknown server error'; throw ServerException('Failed to get scan data: $errorMessage'); } return response.data as Map?; } on ValidationException { rethrow; } on ServerException { rethrow; } on NetworkException { rethrow; } catch (e) { throw ServerException('Unexpected error occurred while getting scan data: ${e.toString()}'); } } /// Update scan data on remote server (optional for future use) Future updateScan(String barcode, SaveRequestModel request) async { try { if (barcode.trim().isEmpty) { throw const ValidationException('Barcode cannot be empty'); } if (!request.isValid) { throw ValidationException('Invalid request data: ${request.validationErrors.join(', ')}'); } final response = await apiClient.put( '/api/scans/$barcode', data: request.toJson(), ); if (response.statusCode == null || (response.statusCode! < 200 || response.statusCode! >= 300)) { final errorMessage = response.data?['message'] ?? 'Unknown server error'; throw ServerException('Failed to update scan: $errorMessage'); } } on ValidationException { rethrow; } on ServerException { rethrow; } on NetworkException { rethrow; } catch (e) { throw ServerException('Unexpected error occurred while updating scan: ${e.toString()}'); } } /// Delete scan data from remote server (optional for future use) Future deleteScan(String barcode) async { try { if (barcode.trim().isEmpty) { throw const ValidationException('Barcode cannot be empty'); } final response = await apiClient.delete('/api/scans/$barcode'); if (response.statusCode == null || (response.statusCode! < 200 || response.statusCode! >= 300)) { final errorMessage = response.data?['message'] ?? 'Unknown server error'; throw ServerException('Failed to delete scan: $errorMessage'); } } on ValidationException { rethrow; } on ServerException { rethrow; } on NetworkException { rethrow; } catch (e) { throw ServerException('Unexpected error occurred while deleting scan: ${e.toString()}'); } } }