package RestAPISchnittstelle;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

import Logik.ElternAccount;
import Logik.Kind;
import Logik.Mahlzeit;
import Logik.Tagesplan;
import com.google.gson.*;

/**
 * noch nicht getestet
 * TODO FERTIG MACHEN
 * @author Samuel Wolff
 */
public class RestApiClient implements IRestAPI{

	private final String urlBase = "https://pbg2h22awo.web.pb.bib.de/VPR_Schnittstelle/VPR_Schnittstelle/restAPI.php";

	private final HttpClient client;

	private final Gson gson;

	public RestApiClient(){
		client = HttpClient.newHttpClient();
		gson = new Gson();
	}

	public static void main(String[] args){

		RestApiClient client1 = new RestApiClient();


		Tagesplan t = client1.getGerichteOnTag("2023-12-17");

		for(Mahlzeit m : t.getGerichte())
			System.out.println(m);
	}

	/**
	 * Methode für einen Get-Aufruf. Ruft alle Elemente einer Tabelle auf.
	 *
	 * @param controllerName Name des aufzurufenden Controllers
	 */
	@Override
	public String get(String controllerName) {
		URI apiUri = URI.create(String.format("%s/%s", urlBase, controllerName));

		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .GET()
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode());
			System.out.println("Response Body: " + httpResponse.body());
			return httpResponse.body();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Methode für einen Get-Aufruf. Ruft ein spezifisches Element auf.
	 *
	 * @param controllerName Name des aufzurufenden Controllers
	 * @param id Id der Aufzurufenden Zeile
	 */
	@Override
	public String get(String controllerName, int id) {
		URI apiUri = URI.create(String.format("%s/%s/%s", urlBase, controllerName, id));

		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .GET()
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode() + httpResponse.body());

			return httpResponse.body();

			//System.out.println("Response Body: " + test);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Methode für einen Get-Aufruf. Ruft ein spezielles Element auf.
	 *
	 * @param controllerName Name des aufzurufenden Controllers
	 * @param id Id der Aufzurufenden Zeile
	 * @param bezahlt TODO Warum ist das hier?
	 */
	@Override
	public String get(String controllerName, int id, boolean bezahlt) {
		URI apiUri = URI.create(String.format("%s/%s?%s&%s", urlBase, controllerName, id, bezahlt));

		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .GET()
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode());
			System.out.println("Response Body: " + httpResponse.body());
			return httpResponse.body();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Methode für einen Put-Aufruf. Aktualisiert einen Eintrag.
	 *
	 * @param controllerName Name des aufzurufenden Controllers.
	 * @param id Id des zu änderenden Eintrags.
	 * @param jsonData JsonString mit den neuen Daten.
	 */
	@Override
	public void put(String controllerName, int id, String jsonData) {

		URI apiUri = URI.create(String.format("%s/%s/%s", urlBase,controllerName, id));

		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .header("Content-Type", "application/json")
											 .PUT(HttpRequest.BodyPublishers.ofString(jsonData, StandardCharsets.UTF_8))
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode());
			System.out.println("Response Body: " + httpResponse.body());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Methode für einen Post-Aufruf. Fügt einen Eintrag in eine Datenbank hinzu.
	 *
	 * @param controllerName Name des aufzurufenden Controllers.
	 * @param jsonData JsonString mit den Daten des Eintrags.
	 */
	@Override
	public void post(String controllerName, String jsonData) {
		URI apiUri = URI.create(String.format("%s/%s", urlBase,controllerName));

		System.out.println(apiUri);

		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .header("Content-Type", "application/json")
											 .POST(HttpRequest.BodyPublishers.ofString(jsonData, StandardCharsets.UTF_8))
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode());
			System.out.println("Response Body: " + httpResponse.body());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Methode für einen Delete-Aufruf. Löscht einen Eintrag mit einer Id.
	 *
	 * @param controllerName Name des aufzurufenden Controllers
	 * @param id Id des zu löschenden Eintrags.
	 */
	@Override
	public void delete(String controllerName, int id) {
		URI apiUri = URI.create(String.format("%s/%s/%d", urlBase,controllerName, id));

		System.out.println(apiUri);

		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .header("Content-Type", "application/json")
											 .DELETE()
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode());
			System.out.println("Response Body: " + httpResponse.body());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public int nextId(String controllerName){
		URI apiUri = URI.create(String.format("%s/%s/nextId", urlBase, controllerName));

		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .GET()
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode());
			System.out.println("Response Body: " + httpResponse.body());

			JsonElement jsonElement = JsonParser.parseString(httpResponse.body());
			JsonArray jsonArray = jsonElement.getAsJsonArray();

			JsonObject json = jsonArray.get(0).getAsJsonObject();

			return json.get("auto_increment").getAsInt();

		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
	}

	public boolean anmeldeVersuch(String credentials){

		JsonObject json = gson.fromJson(credentials, JsonObject.class);
		String benutzer = json.get("Benutzername").toString();
		benutzer = benutzer.substring(1, benutzer.length()-1);

		String passwort = json.get("passwort").toString();
		passwort = passwort.substring(1, passwort.length()-1);

		URI apiUri = URI.create(String.format("%s/Benutzer/anmeldeVersuch?Benutzername=%s&passwort=%s", urlBase, benutzer, passwort));
		System.out.println(apiUri);
		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .header("Content-Type", "application/json")
											 .GET()
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode());
			System.out.println("Response Body: " + httpResponse.body());
			if(httpResponse.body().equals("true"))
				return true;
			else
				return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public Tagesplan getGerichteOnTag(String datum){

		URI apiUri = URI.create(String.format("%s/Tagesplan/getGerichteOnTag?datum=%s", urlBase, datum));
		System.out.println(apiUri);
		HttpRequest httpRequest = HttpRequest.newBuilder()
											 .uri(apiUri)
											 .header("Content-Type", "application/json")
											 .GET()
											 .build();

		try {
			// Send the request and get the response
			HttpResponse<String> httpResponse = client.send(httpRequest, HttpResponse.BodyHandlers.ofString());

			// Print the response status code and body
			System.out.println("Status Code: " + httpResponse.statusCode());
			System.out.println("Response Body: " + httpResponse.body());

			Tagesplan t = new Tagesplan(datum);

			JsonElement jsonElement = JsonParser.parseString(httpResponse.body());

			JsonArray json = jsonElement.getAsJsonArray();

			for(int i = 0; i< json.size(); i++){

				JsonObject o = json.get(i).getAsJsonObject();
				String name = o.get("name").getAsString();
				float preis = o.get("preis").getAsFloat();
				String beschreibung = o.get("beschreibung").getAsString();

				t.getGerichte().add(new Mahlzeit(name, preis, beschreibung));

			}

			return t;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

}