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';
// Generic API service function that handles API requests with optional file uploads
Future<BodyType?> commonApiService<BodyType>({
  required String url,
  required String method,
  Map<String, dynamic> body = const {}, // Request body
  File? imageFile, // Optional image file for upload
  bool isformData = true,
  Map<String, String>? additionalHeaders, // Additional headers for the request
  Map<String, String>? queryParameters, // Optional query parameters
  required BodyType Function(Map<String, dynamic>) fromJson,// Function to parse the response data
}) async {
  try {
    // Initialize Dio for making HTTP requests
    Dio dio = Dio();
    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<String, String> 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<String, dynamic>) {
      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;
}
