package de.avatic.lcc.service.api;

import eu.europa.ec.taxation.taric.client.*;
import jakarta.xml.bind.JAXBElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.ws.client.core.WebServiceTemplate;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.CompletableFuture;

@Service
public class EUTaxationApiService {

    private final WebServiceTemplate webServiceTemplate;
    private final ObjectFactory objectFactory;
    private Logger logger = LoggerFactory.getLogger(EUTaxationApiService.class);

    public EUTaxationApiService(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
        this.objectFactory = new ObjectFactory();
    }

    @Async("customLookupExecutor")
    public CompletableFuture<GoodsDescrForWsResponse> getGoodsDescription(String goodsCode, String languageCode) {

        logger.info("Start lookup for {} and {}", goodsCode, languageCode);

        GoodsDescrForWs request = new GoodsDescrForWs();
        request.setGoodsCode(goodsCode);
        request.setLanguageCode(languageCode);
        request.setReferenceDate(getCurrentDate());

        JAXBElement<GoodsDescrForWs> requestElement = objectFactory.createGoodsDescrForWs(request);

        @SuppressWarnings("unchecked")
        JAXBElement<GoodsDescrForWsResponse> responseElement =
                (JAXBElement<GoodsDescrForWsResponse>) webServiceTemplate.marshalSendAndReceive(requestElement);

        return CompletableFuture.completedFuture(responseElement.getValue());
    }

    @Async("customLookupExecutor")
    public CompletableFuture<GoodsMeasForWsResponse> getGoodsMeasures(String goodsCode, String countryCode, String tradeMovement) {
        GoodsMeasForWs request = new GoodsMeasForWs();
        request.setGoodsCode(goodsCode);
        request.setCountryCode(countryCode);
        request.setReferenceDate(getCurrentDate());
        request.setTradeMovement(TradeMovementCode.fromValue(tradeMovement));

        JAXBElement<GoodsMeasForWs> requestElement = objectFactory.createGoodsMeasForWs(request);

        @SuppressWarnings("unchecked")
        JAXBElement<GoodsMeasForWsResponse> responseElement =
                (JAXBElement<GoodsMeasForWsResponse>) webServiceTemplate.marshalSendAndReceive(requestElement);

        return CompletableFuture.completedFuture(responseElement.getValue());
    }

    private XMLGregorianCalendar getCurrentDate() {
        try {
            String currentDate = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
            return DatatypeFactory.newInstance().newXMLGregorianCalendar(currentDate);
        } catch (Exception e) {
            throw new RuntimeException("Fehler beim Erstellen des Datums", e);
        }
    }

    public Logger getLogger() {
        return logger;
    }

    public void setLogger(Logger logger) {
        this.logger = logger;
    }
}