library vyc_api;

import 'dart:async';
import 'dart:convert';

import 'package:ambito/main.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:http/http.dart' as http;

class RestClient {
  final String baseUrl = 'https://api.baserow.io/api/database/rows/table/';
  static final http.Client _client = http.Client();

  static const String contentType = "application/json; charset=utf-8";
  static const String accept = 'application/json; charset=UTF-8';

  RestClient();

  Map<String, String> _getHeaders() {
    var headers = {
      "Content-Type": contentType,
      "Accept": accept,
      "Authorization": "Token ${dotenv.get('BASEROW_TOKEN')}",
    };
    return headers;
  }

  Future<http.Response> _performRequest(
    Function request,
  ) async {
    try {
      http.Response response = await request();
      _logResponse(response);
      return response;
    } catch (e) {
      _logError(e);
      rethrow;
    }
  }

  void _logResponse(http.Response response) {
    if (response.statusCode != 200 && response.statusCode != 204) {
      logger.e('ERROR PERFORMING REQUEST:');
      logger.e(response.request?.method.toString());
      logger.e(response.request?.url);
      logger.e(response.request?.toString());
      logger.e('REPONSE:');
      logger.e(response.statusCode);
      logger.e(response.headers);
      logger.e(response.body);
    }
  }

  void _logError(dynamic error) {
    logger.e(error);
  }

  Future<http.Response> delete(String endpoint) async {
    final String uriString = '$baseUrl$endpoint';
    final Uri uri = Uri.parse(uriString);
    final Map<String, String> headers = _getHeaders();
    return _performRequest(
      () {
        return _client.delete(
          uri,
          headers: headers,
        );
      },
    );
  }

  Future<http.Response> get(String endpoint) async {
    final String uriString = '$baseUrl$endpoint';
    final Uri uri = Uri.parse(uriString);
    final Map<String, String> headers = _getHeaders();
    return _performRequest(
      () {
        return _client.get(
          uri,
          headers: headers,
        );
      },
    );
  }

  Future<http.Response> post(
    String endpoint,
    dynamic body,
  ) async {
    final String uriString = '$baseUrl$endpoint';
    final Uri uri = Uri.parse(uriString);
    final Map<String, String> headers = _getHeaders();
    return _performRequest(
      () {
        return _client.post(
          uri,
          body: jsonEncode(body),
          headers: headers,
        );
      },
    );
  }

  Future<http.Response> put(
    String endpoint,
    dynamic body,
  ) async {
    final String uriString = '$baseUrl$endpoint';
    final Uri uri = Uri.parse(uriString);
    final Map<String, String> headers = _getHeaders();
    return _performRequest(
      () {
        return _client.put(
          uri,
          body: jsonEncode(body),
          headers: headers,
        );
      },
    );
  }

  Future<http.Response> patch(
    String endpoint,
    dynamic body,
  ) async {
    final String uriString = '$baseUrl$endpoint';
    final Uri uri = Uri.parse(uriString);
    final Map<String, String> headers = _getHeaders();
    return _performRequest(
      () {
        return _client.patch(
          uri,
          body: jsonEncode(body),
          headers: headers,
        );
      },
    );
  }
}
