import 'dart:io'; import 'package:cheminova/utils/api_urls.dart'; import 'package:cheminova/utils/constants.dart'; import 'package:cheminova/utils/show_snackbar.dart'; import 'package:dio/dio.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'app_interceptor.dart'; Dio createDio() { final dio = Dio(); dio.interceptors.add((AuthInterceptor())); return dio; } // Generic API service function that handles API requests with optional file uploads Future commonApiService({ required String url, required String method, Map body = const {}, // Request body File? imageFile, // Optional image file for upload bool isformData = true, Map? additionalHeaders, // Additional headers for the request Map? queryParameters, // Optional query parameters required BodyType Function(Map) fromJson,// Function to parse the response data }) async { try { // Initialize Dio for making HTTP requests Dio dio = createDio(); final Response response; print("body : $body"); // Fetch the token from SharedPreferences SharedPreferences prefs = await SharedPreferences.getInstance(); String? token = prefs.getString('token'); // Setting default headers, including Content-Type and Authorization if token is present Map headers = { 'Content-Type': isformData ? 'multipart/form-data' : 'application/json', }; // Adding the token to the headers if available if (token != null) { headers['Authorization'] = 'Bearer $token'; } // Adding any additional headers provided in the request if (additionalHeaders != null) { headers.addAll(additionalHeaders); } // Setting options with the headers Options options = Options(headers: headers); // Preparing form data for requests, especially if files are involved FormData formData = FormData.fromMap(body); // Adding the image file to the form data if present if (imageFile != null) { String fileName = imageFile.path.split('/').last; formData.files.add(MapEntry( "image", await MultipartFile.fromFile(imageFile.path, filename: fileName), )); } // Handling different HTTP methods based on the provided method parameter if (method == "POST") { response = await dio.post("${ApiUrls.baseUrl}$url", data: isformData ? formData : body, options: options); } else if (method == "PUT") { response = await dio.put("${ApiUrls.baseUrl}$url", data: isformData ? formData : body, options: options); } else if (method == "DELETE") { response = await dio.delete("${ApiUrls.baseUrl}$url", options: options); } else if (method == "PATCH") { response = await dio.patch("${ApiUrls.baseUrl}$url", data: isformData ? formData : body, options: options); } else { // Default to GET method if no specific method is matched response = await dio.get("${ApiUrls.baseUrl}$url", options: options); } print("response of $url : $response"); // Special handling for login endpoint to store token in SharedPreferences if (url == "/api/v1/user/login/" && response.data['token'] != null) { prefs.setString('token', response.data['token']); } // if (url == "/api/territorymanager/my-profile") { // return fromJson(response.data['myData']); // } // Returning parsed response data using the fromJson function provided return fromJson(response.data); } on DioException catch (e) { print("dio exception $url ${e.response?.data}}"); print("dio exception details: ${e.message} ${e.response?.statusCode}"); String errorMessage = "An error occurred"; // Extracting error message from the response if available if (e.response?.data is Map) { errorMessage = e.response?.data['message'] ?? errorMessage; } else if (e.response?.data is String) { errorMessage = e.response?.data; } //showSnackbar(errorMessage); } catch (e) { print("exception $url $e"); } // Returning null in case of any exception return null; }