package waluty;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.time.LocalDate;

import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonValue;

public class PobieranieJSON extends Pobieranie {
	
	public TabelaWalut pobierzBiezaceKursy() throws BladAplikacji {
		String adres = ADRES_BAZOWY + "/A?format=json";
		return pobierzZAdresu(adres);
	}
	
	public TabelaWalut pobierzArchiwalneKursy(String data) throws BladAplikacji {
        return pobierzZAdresu(ADRES_BAZOWY + "/A/" + data + "?format=json");
    }

	private TabelaWalut pobierzZAdresu(String adres) throws BladAplikacji {
		try {
			HttpClient httpClient = HttpClient.newHttpClient();
			URI uri = new URI(adres);
			HttpRequest request = HttpRequest.newBuilder(uri).build();
			HttpResponse<InputStream> response = httpClient.send(request, BodyHandlers.ofInputStream());
			if(response.statusCode() != 200) {
				throw new BladAplikacji("Zapytanie HTTP zwróciło " + response.statusCode());
			}
			// dane odebrane z sieci "parsujemy" jako JSON
			try(JsonReader reader = Json.createReader(response.body())) {
				JsonArray array = reader.readArray();
				JsonObject tabela = array.getJsonObject(0);
				String no = tabela.getString("no");
				LocalDate effectiveDate = LocalDate.parse(tabela.getString("effectiveDate"));
				TabelaWalut tabelaWalut = new TabelaWalut(no, effectiveDate);
				
				JsonArray rates = tabela.getJsonArray("rates");
				for(JsonValue rate : rates) {
					JsonObject rateObj = rate.asJsonObject();
					Waluta waluta = new Waluta(rateObj.getString("code"),
							rateObj.getString("currency"),
							rateObj.getJsonNumber("mid").bigDecimalValue());
					tabelaWalut.addRate(waluta);
				}
				return tabelaWalut;
			}
		} catch (URISyntaxException | IOException | InterruptedException e) {
			throw new BladAplikacji(e);
		}
	}
	
}
