import 'dart:convert';
import 'package:aitrainer_app/util/common.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'package:aitrainer_app/model/auth.dart';

class APIClient extends ChangeNotifier {

  Future<String> get(String endPoint, String param) async {
    final url = Auth.getBaseUrl() + endPoint + param;
    String authToken = Auth().getAuthToken();
    if ( authToken.length == 0 ) {
      var responseJson = await APIClient.authenticateUser(
          Auth.username,
          Auth.password
      );
      authToken = responseJson['token'];
    }
    final response = await http.get(url,
        headers: {
          'Content-Type': 'application/json',
          'Authorization' : "Bearer " + authToken }
    );
    notifyListeners();
    if(response.statusCode == 200) {
      return utf8.decode(response.bodyBytes);
    } else {
      throw Exception("Unable to perform HTTP request!");
    }
  }

  Future<String> post(String endPoint, String body) async {
    final url = Auth.getBaseUrl() + endPoint;
    print(" ------------ http/post endpoint $endPoint body $body - url: $url ");
    String authToken = Auth().getAuthToken();
    if ( authToken.length == 0 ) {
      var responseJson = await APIClient.authenticateUser(
          Auth.username,
          Auth.password
      );
      authToken = responseJson['token'];
    }

    final response = await http.post(url,
        headers: {
          'Content-Type': 'application/json; charset=UTF-8',
          'Authorization' : "Bearer " + authToken
        },
        body: body,
    );
    String decodedResponse = Common.utf8convert(response.body);
    print(" ------------ response: " + decodedResponse);
    notifyListeners();
    return decodedResponse;
  }

  static dynamic authenticateUser(String email, String password) async {
    var uri = Auth.getBaseUrl() + "authenticate";

    try {
      final body = '{"username":"$email", "password":"$password"}';
      final response = await http.post(
          uri,
          headers: {
            'Authorization': '1',
            'Content-Type': 'application/json'
          },
          body: body
      );
      final responseCode = response.statusCode;
      if ( responseCode != 200) {
        return { "error" : "Authentication error, total failure", };
      }

      final responseJson = json.decode(response.body);
      return responseJson;

    } catch (exception) {
        return { "error" : "Network error, try again later "
            + exception.toString()};
    }
  }

  static fetch(var authToken, var endPoint) async {
    var uri = Auth.getBaseUrl() + endPoint;

    try {
      final response = await http.get(
        uri,
        headers: {
          'Authorization': authToken
        },
      );

      final responseJson = json.decode(response.body);
      return responseJson;

    } catch (exception) {
      print(exception);
      if(exception.toString().contains('SocketException')) {
        return 'NetworkError';
      } else {
        return null;
      }
    }
  }

}