import 'package:dio/dio.dart';
import 'package:logger/logger.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:qpay/config/app_config.dart';

var logger = Logger(printer: PrettyPrinter());

class Http {
  final Dio dio = Dio();

  final String baseUrl = AppConfig.baseUrl;

  Http() {
    dio.options.baseUrl = baseUrl;
    // dio.options.connectTimeout = const Duration(seconds: 120);
    // dio.options.receiveTimeout = const Duration(seconds: 120);
    // dio.options.sendTimeout = const Duration(seconds: 120);
    dio.interceptors.add(
      LogInterceptor(
        request: true,
        responseBody: false,
        requestBody: true,
        error: true,
      ),
    );
  }

  Future<Map<String, String>> getHeaders() async {
    Map<String, String> headers = {'Content-Type': 'application/json'};

    var prefs = await SharedPreferences.getInstance();
    String token = prefs.getString("token") ?? "";

    headers['Authorization'] = 'Bearer $token';

    return headers;
  }

  Future<dynamic> get(String url) async {
    Map<String, String> headers = await getHeaders();

    Response response;
    response = await dio.get(baseUrl + url, options: Options(headers: headers));
    logger.i(response.data.toString());
    return response.data;
  }

  /// Returns the raw [Response] object (including status code)
  /// instead of just the response body.
  Future<Response> getRaw(String url) async {
    Map<String, String> headers = await getHeaders();

    final response = await dio.get(
      baseUrl + url,
      options: Options(headers: headers),
    );
    logger.i(response.data.toString());
    return response;
  }

  /// Issues a POST request without authentication headers and returns
  /// the raw [Response] object.
  Future<Response> postRaw(String url, {dynamic data}) async {
    Map<String, String> headers = await getHeaders();
    final response = await dio.post(
      baseUrl + url,
      data: data,
      options: Options(headers: headers),
    );
    logger.i(response.data.toString());
    return response;
  }

  Future<dynamic> post(String url, dynamic data) async {
    Map<String, String> headers = await getHeaders();

    Response response;
    response = await dio.post(
      baseUrl + url,
      data: data,
      options: Options(headers: headers),
    );
    logger.i(response.data.toString());
    return response.data;
  }

  Future<dynamic> patch(String url, dynamic data) async {
    Map<String, String> headers = await getHeaders();

    Response response;
    response = await dio.patch(
      baseUrl + url,
      data: data,
      options: Options(headers: headers),
    );
    logger.i(response.data.toString());
    return response.data;
  }

  Future<dynamic> put(String url, dynamic data) async {
    Map<String, String> headers = await getHeaders();

    Response response;
    response = await dio.put(
      baseUrl + url,
      data: data,
      options: Options(headers: headers),
    );
    logger.i(response.data.toString());
    return response.data;
  }

  Future<dynamic> delete(String url) async {
    Map<String, String> headers = await getHeaders();

    Response response;
    response = await dio.delete(
      baseUrl + url,
      options: Options(headers: headers),
    );
    logger.i(response.data.toString());
    return response.data;
  }

  Future<dynamic> multipartPost(
    String url,
    Map<String, String> fields,
    String fileFieldName,
    List<int> fileBytes,
    String fileName,
  ) async {
    final formData = FormData.fromMap({
      ...fields,
      fileFieldName: MultipartFile.fromBytes(fileBytes, filename: fileName),
    });

    final prefs = await SharedPreferences.getInstance();
    final token = prefs.getString("token") ?? "";

    final response = await dio.post(
      baseUrl + url,
      data: formData,
      options: Options(headers: {'Authorization': 'Bearer $token'}),
    );
    logger.i(response.data.toString());
    return response.data;
  }
}