environment_monitoring_app/lib/services/submission_api_service.dart

109 lines
4.4 KiB
Dart

// lib/services/submission_api_service.dart
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:environment_monitoring_app/services/user_preferences_service.dart';
import 'package:environment_monitoring_app/services/base_api_service.dart';
import 'package:environment_monitoring_app/services/retry_service.dart';
/// A generic, reusable service for handling the entire API submission process.
/// It respects user preferences for enabled destinations for any given module.
class SubmissionApiService {
final UserPreferencesService _userPreferencesService = UserPreferencesService();
final BaseApiService _baseApiService = BaseApiService();
final RetryService _retryService = RetryService();
/// Submits a standard JSON POST request to all enabled destinations for a module.
///
/// Returns a success result if AT LEAST ONE destination succeeds.
/// If all destinations fail, it queues the request for manual retry and returns a failure result.
Future<Map<String, dynamic>> submitPost({
required String moduleName,
required String endpoint,
required Map<String, dynamic> body,
}) async {
final destinations = await _userPreferencesService.getEnabledApiConfigsForModule(moduleName);
if (destinations.isEmpty) {
debugPrint("SubmissionApiService: No enabled API destinations for module '$moduleName'. Skipping.");
return {'success': true, 'message': 'No API destinations enabled for this module.'};
}
for (final dest in destinations) {
final baseUrl = dest['api_url'] as String?;
if (baseUrl == null) {
debugPrint("SubmissionApiService: Skipping destination '${dest['config_name']}' due to missing URL.");
continue;
}
debugPrint("SubmissionApiService: Attempting to POST to '${dest['config_name']}' ($baseUrl)");
final result = await _baseApiService.post(baseUrl, endpoint, body);
if (result['success'] == true) {
debugPrint("SubmissionApiService: Successfully submitted to '${dest['config_name']}'.");
return result; // Return immediately on the first success
} else {
debugPrint("SubmissionApiService: Failed to submit to '${dest['config_name']}'. Trying next destination.");
}
}
// If the loop completes, it means all attempts failed.
debugPrint("SubmissionApiService: All API submission attempts for module '$moduleName' failed. Queuing for retry.");
await _retryService.addApiToQueue(
endpoint: endpoint,
method: 'POST',
body: body,
);
return {'success': false, 'message': 'All API attempts failed. Request has been queued for manual retry.'};
}
/// Submits a multipart (form data with files) request to all enabled destinations.
///
/// Follows the same logic as `submitPost`: succeeds on the first successful upload,
/// and queues for retry if all attempts fail.
Future<Map<String, dynamic>> submitMultipart({
required String moduleName,
required String endpoint,
required Map<String, String> fields,
required Map<String, File> files,
}) async {
final destinations = await _userPreferencesService.getEnabledApiConfigsForModule(moduleName);
if (destinations.isEmpty) {
debugPrint("SubmissionApiService: No enabled API destinations for module '$moduleName'. Skipping multipart upload.");
return {'success': true, 'message': 'No API destinations enabled for this module.'};
}
for (final dest in destinations) {
final baseUrl = dest['api_url'] as String?;
if (baseUrl == null) continue;
debugPrint("SubmissionApiService: Attempting multipart upload to '${dest['config_name']}' ($baseUrl)");
final result = await _baseApiService.postMultipart(
baseUrl: baseUrl,
endpoint: endpoint,
fields: fields,
files: files,
);
if (result['success'] == true) {
debugPrint("SubmissionApiService: Successfully uploaded to '${dest['config_name']}'.");
return result;
} else {
debugPrint("SubmissionApiService: Failed to upload to '${dest['config_name']}'. Trying next destination.");
}
}
debugPrint("SubmissionApiService: All multipart upload attempts for module '$moduleName' failed. Queuing for retry.");
await _retryService.addApiToQueue(
endpoint: endpoint,
method: 'POST_MULTIPART',
fields: fields,
files: files,
);
return {'success': false, 'message': 'All API attempts failed. Upload has been queued for manual retry.'};
}
}