import 'dart:io'; import 'package:dio/dio.dart'; import 'package:news/data/repositories/Auth/authLocalDataSource.dart'; import 'package:news/utils/ErrorMessageKeys.dart'; import 'package:news/utils/internetConnectivity.dart'; import 'package:news/utils/constant.dart'; class ApiMessageAndCodeException implements Exception { final String errorMessage; ApiMessageAndCodeException({required this.errorMessage}); Map toError() => {"message": errorMessage}; @override String toString() => errorMessage; } class ApiException implements Exception { String errorMessage; ApiException(this.errorMessage); @override String toString() { return errorMessage; } } class Api { static String getToken() { String token = AuthLocalDataSource().getJWTtoken(); return (token.trim().isNotEmpty) ? token : ""; } static Map get headers => {"Authorization": 'Bearer ${getToken()}'}; //all apis list static String getUserSignUpApi = 'user_signup'; static String getNewsApi = 'get_news'; static String getSettingApi = 'get_settings'; static String getCatApi = 'get_category'; static String setBookmarkApi = 'set_bookmark'; static String getBookmarkApi = 'get_bookmark'; static String setCommentApi = 'set_comment'; static String getCommentByNewsApi = 'get_comment_by_news'; static String getBreakingNewsApi = 'get_breaking_news'; static String setUpdateProfileApi = 'update_profile'; static String setRegisterToken = 'register_token'; static String setUserCatApi = 'set_user_category'; static String getUserByIdApi = 'get_user_by_id'; static String setCommentDeleteApi = 'delete_comment'; static String setLikesDislikesApi = 'set_like_dislike'; static String setFlagApi = 'set_flag'; static String getLiveStreamingApi = 'get_live_streaming'; static String getSubCategoryApi = 'get_subcategory_by_category'; static String setLikeDislikeComApi = 'set_comment_like_dislike'; static String deleteUserNotiApi = 'delete_user_notification'; static String getQueApi = 'get_question'; static String getQueResultApi = 'get_question_result'; static String setQueResultApi = 'set_question_result'; static String userDeleteApi = 'delete_user'; static String getTagsApi = 'get_tag'; static String setNewsApi = 'set_news'; static String setDeleteNewsApi = 'delete_news'; static String setDeleteImageApi = 'delete_news_images'; static String getVideosApi = 'get_videos'; static String getLanguagesApi = 'get_languages_list'; static String getLangJsonDataApi = 'get_language_json_data'; static String getPagesApi = 'get_pages'; static String getPolicyPagesApi = 'get_policy_pages'; static String getFeatureSectionApi = 'get_featured_sections'; static String getLikeNewsApi = 'get_like'; static String setNewsViewApi = 'set_news_view'; static String setBreakingNewsViewApi = 'set_breaking_news_view'; static String getAdsNewsDetailsApi = 'get_ad_space_news_details'; static String getLocationCityApi = 'get_location'; static String slugCheckApi = 'check_slug_availability'; static String rssFeedApi = 'get_rss_feed'; static String becomeAnAuthorApi = 'become_author'; static String getAuthorNewsApi = 'get_authors_news'; static String getDraftNewsApi = 'get_user_drafted_news'; static String geminiMetaInfoApi = 'https://generativelanguage.googleapis.com/v1beta/models/'; static FormData? toFormData(dynamic data) { if (data == null) return null; if (data is Map) { return FormData.fromMap(data, ListFormat.multiCompatible); } if (data is List) { final formData = FormData(); for (var value in data) { formData.fields.add(MapEntry("list[]", value.toString())); } return formData; } // Raw value (int/string/etc.) → cannot convert → return null return null; } static Future> sendApiRequest({required dynamic body, required String url, bool isGet = false}) async { try { if (!await InternetConnectivity.isNetworkAvailable()) { throw const SocketException(ErrorMessageKeys.noInternet); } final Dio dio = Dio(); final apiUrl = "$databaseUrl$url"; // Auto-detect GET for endpoints starting with "get_" final shouldUseGet = isGet || url.startsWith('get_'); // Convert body to query parameters for GET requests Map? queryParams; if (shouldUseGet && body != null && body is Map) { queryParams = body; } // Convert only if possible (for POST) final convertedBody = toFormData(body); final response = (shouldUseGet) ? await dio.get( apiUrl, queryParameters: queryParams ?? {}, options: Options(headers: headers), ) : await dio.post( apiUrl, data: convertedBody ?? body, options: Options(headers: headers), ); if (response.data['error'] == 'true') { throw ApiException(response.data['message']); } return Map.from(response.data); } on DioException catch (e) { print('DEBUG API ERROR: ${e.response?.statusCode} - ${e.message} - URL: $url'); print('DEBUG API RESPONSE: ${e.response?.data}'); if (e.response?.statusCode == 503) { throw ApiException(ErrorMessageKeys.serverDownMessage); } else if (e.response?.statusCode == 404) { throw ApiException(ErrorMessageKeys.requestAgainMessage); } throw ApiException( e.error is SocketException ? ErrorMessageKeys.noInternet : ErrorMessageKeys.defaultErrorMessage, ); } on SocketException catch (e) { print('DEBUG SOCKET ERROR: ${e.message}'); throw SocketException(e.message); } on ApiException catch (e) { print('DEBUG API EXCEPTION: ${e.errorMessage}'); throw ApiException(e.errorMessage); } catch (e) { print('DEBUG CATCH ALL ERROR: $e'); throw ApiException(ErrorMessageKeys.defaultErrorMessage); } } }