package waluty;

import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class PobieranieXML extends Pobieranie {
    private HttpClient httpClient = HttpClient.newHttpClient();
    private DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    private XPathFactory xpf = XPathFactory.newInstance();

    @Override
    public TabelaWalut pobierzBiezaceKursy() throws BladAplikacji {
        return pobierzZAdresu(ADRES_BAZOWY + "/A" + "?format=xml");
    }
    
    @Override
    public TabelaWalut pobierzArchiwalneKursy(String data) throws BladAplikacji {
        return pobierzZAdresu(ADRES_BAZOWY + "/A/" + data + "?format=xml");
    }

    private TabelaWalut pobierzZAdresu(String adres) throws BladAplikacji {
        try {
            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("Brak danych w odpowiedzi HTTP, kod " + response.statusCode());
            }
            DocumentBuilder builder = dbf.newDocumentBuilder();
            Document document = builder.parse(response.body());
            return tabelaZXML(document);
        } catch(BladAplikacji e) {
            throw e;
        } catch(Exception e) {
            throw new BladAplikacji("Błąd podczas pobierania XML: " + e.getMessage(), e);
        }
    }

    private TabelaWalut tabelaZXML(Document document) throws XPathExpressionException {
        XPath xpath = xpf.newXPath();
        
//        String no = xpath.evaluate("/ArrayOfExchangeRatesTable/ExchangeRatesTable/No", document);
//        String date = xpath.evaluate("/ArrayOfExchangeRatesTable/ExchangeRatesTable/EffectiveDate", document);
        String no = xpath.evaluate("//No", document);
        String date = xpath.evaluate("//EffectiveDate", document);
        TabelaWalut tabela = new TabelaWalut(no, date);
        
        NodeList rates = (NodeList) xpath.evaluate("//Rate", document, XPathConstants.NODESET);
        final int length = rates.getLength();
        for(int i = 0; i < length; i++) {
            Node rate = rates.item(i);
            String currency = xpath.evaluate("Currency", rate);
            String code = xpath.evaluate("Code", rate);
            BigDecimal mid = new BigDecimal(xpath.evaluate("Mid", rate));
            Waluta waluta = new Waluta(code, currency, mid);
            tabela.addRate(waluta);
        }
        return tabela;
    }

}
