import 'package:dio/dio.dart'; import 'package:image_picker/image_picker.dart'; import '../../../../core/logging/logger.dart'; import '../../../../core/network/api_problem.dart'; import '../../../../data/network/api_client.dart'; import '../models/feedback.dart'; class FeedbackApi { FeedbackApi({required ApiClient apiClient}) : _apiClient = apiClient; final ApiClient _apiClient; final Logger _logger = getLogger('features.settings.feedback_api'); Future submitFeedback({ required FeedbackType type, required String content, required DeviceInfo deviceInfo, required String appVersion, required String osVersion, required List images, required bool isAnonymous, }) async { final typeName = switch (type) { FeedbackType.bug => 'bug', FeedbackType.suggestion => 'suggestion', FeedbackType.other => 'other', }; final formData = FormData.fromMap({ 'feedback_type': typeName, 'content': content, 'device_info': '{"platform":"${deviceInfo.platform}","model":"${deviceInfo.model}"}', 'app_version': appVersion, 'os_version': osVersion, }); for (final image in images) { formData.files.add( MapEntry( 'images', await MultipartFile.fromFile(image.path, filename: image.name), ), ); } final options = isAnonymous ? Options(extra: {'skipAuth': true}) : Options(); try { await _apiClient.rawDio.post( '/api/v1/feedback', data: formData, options: options, ); } on DioException catch (error, stackTrace) { _logger.error( message: 'Submit feedback failed', error: error, stackTrace: stackTrace, ); throw _mapProblem(error); } } ApiProblem _mapProblem(DioException error) { final status = error.response?.statusCode ?? 500; final data = error.response?.data; if (data is Map) { return ApiProblem( status: status, title: (data['title'] as String?) ?? 'Request failed', detail: (data['detail'] as String?) ?? '', code: data['code'] as String?, ); } return ApiProblem( status: status, title: 'Network error', detail: error.message ?? 'Request failed', ); } }