package at.vvo.omds.client.gui.api.calc;

import at.vvo.omds.helpers.GuiProdukt;
import at.vvo.omds.helpers.ObjectFactoryFactory;
import at.vvo.omds.helpers.RDFHelper;
import at.vvo.omds.types.omds3.r2025_05.common.*;
import at.vvo.omds.types.omds3.r2025_05.on2antrag.common.*;
import jakarta.xml.bind.JAXBElement;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.Rio;

import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import java.io.ByteArrayOutputStream;

public class BuildCalculateRequestAuskunft {
    private static final at.vvo.omds.types.omds3.r2025_05.on2antrag.common.ObjectFactory OUOF =
            new at.vvo.omds.types.omds3.r2025_05.on2antrag.common.ObjectFactory();

    private BuildCalculateRequestAuskunft(){}

    static public JAXBElement<CalculateRequest> buildRequestFromTreeView(TreeView<GuiProdukt> treeView, XMLGregorianCalendar vtBeg) {
        CalculateRequest request = OUOF.createCalculateRequest();
        VerkaufsproduktType verkaufsprodukt = TreeViewToVerkaufsprodukt(treeView, vtBeg);
        verkaufsprodukt.setVtgBeg(vtBeg);
        verkaufsprodukt.setTyp(((ProduktbausteinType)treeView.getRoot().getValue().getProdukt()).getTyp());
        SpezBerechnungGenType berechnungsanfrage = new SpezBerechnungGenType();

        berechnungsanfrage.setVerkaufsprodukt(verkaufsprodukt);
        request.setBerechnungsanfrage(berechnungsanfrage);
        request.setKorrelationsId("12444579");
        request.setVUNr("042");

        return createCalculateRequest(request);
    }

    static public String buildRDFRequestFromTreeView(TreeView<GuiProdukt> treeView, XMLGregorianCalendar vtBeg) {
        RDFHelper rdf = new RDFHelper();
        Model requestModel = rdf.createRdfModel(treeView.getRoot());

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Rio.write(requestModel, baos, RDFFormat.JSONLD);

        return baos.toString();
    }

    public static JAXBElement<CalculateRequest> createCalculateRequest(CalculateRequest value) {
        return new JAXBElement<>(new QName("urn:at.vvo.omds.types.omds3types.v1-3-0.on2antrag.common","CalculateRequest"),
                CalculateRequest.class, null, value);
    }

    public static ProduktbausteinType TreeItemToBaustein(TreeItem<GuiProdukt> treeItem) {
         ProduktbausteinType baustein = new ObjectFactoryFactory().create(
                 ((ProduktbausteinType)treeItem.getValue().getProdukt()).getTyp());

        baustein.setBezeichnung(((ProduktbausteinType)treeItem.getValue().getProdukt()).getBezeichnung());
        baustein.setId(((ProduktbausteinType)treeItem.getValue().getProdukt()).getId());
        baustein.setVerkaufsoffenVon(((ProduktbausteinType)treeItem.getValue().getProdukt()).getVerkaufsoffenVon());
        baustein.setVerkaufsoffenBis(((ProduktbausteinType)treeItem.getValue().getProdukt()).getVerkaufsoffenBis());
        baustein.getAttribute().addAll(((ProduktbausteinType)treeItem.getValue().getProdukt()).getAttribute());
        baustein.setTyp(((ProduktbausteinType)treeItem.getValue().getProdukt()).getTyp());
        baustein.setMinVorkommen(((ProduktbausteinType)treeItem.getValue().getProdukt()).getMinVorkommen());
        baustein.setMaxVorkommen(((ProduktbausteinType)treeItem.getValue().getProdukt()).getMaxVorkommen());
        baustein.getVersicherteObjekte().addAll(((ProduktbausteinType) treeItem.getValue().getProdukt()).getVersicherteObjekte());
        baustein.setPraemienfaktor(((ProduktbausteinType)treeItem.getValue().getProdukt()).getPraemienfaktor());

        return baustein;
    }

    public static VerkaufsproduktType TreeViewToVerkaufsprodukt(TreeView<GuiProdukt> treeView, XMLGregorianCalendar vtBeg) {
        VerkaufsproduktType verkaufsprodukt = (VerkaufsproduktType) TreeItemToBaustein(treeView.getRoot());
        verkaufsprodukt.setVtgBeg(vtBeg);

        if (!treeView.getRoot().getChildren().isEmpty()) {
            for (int i = 0; i < treeView.getRoot().getChildren().size(); i++) {
                verkaufsprodukt.getBausteine().add((addUpFromTreeItem(treeView.getRoot().getChildren().get(i))));
            }
        }

        return verkaufsprodukt;
    }

    public static ProduktbausteinType addUpFromTreeItem(TreeItem<GuiProdukt> treeItem) {
        ProduktbausteinType baustein = TreeItemToBaustein(treeItem);

        if (!treeItem.getChildren().isEmpty()) {
            for (int i = 0; i < treeItem.getChildren().size(); i++) {
                baustein.getBausteine().add(addUpFromTreeItem(treeItem.getChildren().get(i)));
            }
        }
        return baustein;
    }
}
