package com.alexanderlogistics.ai;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.imixs.ai.workflow.ImixsAIPromptEvent;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.engine.DocumentService;
import org.imixs.workflow.exceptions.QueryException;

import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;

/**
 * The PromptExampleAdapterXML is a CDI bean that creates XML examples based
 * on the last 3 invoices.
 * 
 * The adapter only runs if the prompt template contains
 * 
 * <<EXAMPLES_XML>>
 * 
 * Prompt example generated by this Adapter:
 * 
 * Example:
 * 
 * <pre>
 * {@code
 * 1. Company Data:
 * - Name and address of the supplier
 * - Supplier contact information (phone number, email, etc.)
 * 
 * 2. Invoice Data:
 * - Invoice number
 * - Invoice date
 * - Order number
 * - Customer number
 * - Total invoice amount
 *
 * <invoice>
 *   <cdtr.name>...</cdtr.name>
 *   <invoice.number>...</invoice.number> 
 *   <invoice.date>2024-12-31</invoice.date>
 *   <invoice.duedate>2024-12-31</invoice.duedate>
 *   <invoice.total type="double">1234.00</invoice.total>
 *   <cdtr.iban>...</cdtr.iban>
 *   <cdtr.bic>...</cdtr.bic>
 * </invoice>
* }
* </pre>
 * 
 */
public class PromptExampleAdapterXML {
    private static Logger logger = Logger.getLogger(PromptExampleAdapterXML.class.getName());

    @Inject
    DocumentService documentService;

    /**
     * @param event
     */
    public void onEvent(@Observes ImixsAIPromptEvent event) {
        if (event.getWorkitem() == null) {
            return;
        }

        String prompt = event.getPromptTemplate();
        if (!prompt.contains("<<EXAMPLES_XML>>")) {
            return;
        }

        String exampleHeaderData = "\n\n### Example Invoice Data:\n\n";
        String exampleHeaderXML = "\n\n### Example XML Object:\n\n";
        String companyName = event.getWorkitem().getItemValueString("document.company");
        List<ItemCollection> invoices = findLastInvoices(companyName, event.getWorkitem().getUniqueID());
        String promptExamples = "";
        if (invoices != null && invoices.size() > 0) {
            // Build an example for each invoice
            for (ItemCollection invoice : invoices) {
                promptExamples = promptExamples + buildExampleDE(invoice, exampleHeaderData,
                        exampleHeaderXML);
            }
        }
        prompt = prompt.replace("<<EXAMPLES_XML>>", "" + promptExamples);

        // System.out.println(prompt);
        event.setPromptTemplate(prompt);
    }

    /**
     * Helper Method that builds a prompt example out of an existing invoice:
     * 
     * <pre>
     * {@code
     *
     * <invoice>
     *   <cdtr.name>...</cdtr.name>
     *   <invoice.number>...</invoice.number> 
     *   <invoice.date>2024-12-31</invoice.date>
     *   <invoice.duedate>2024-12-31</invoice.duedate>
     *   <invoice.total type="double">1234.00</invoice.total>
     *   <cdtr.iban>...</cdtr.iban>
     *   <cdtr.bic>...</cdtr.bic>
     * </invoice>
    * }
    * </pre>
     * 
     * @param invoice
     * @return
     */
    private String buildExampleDE(ItemCollection invoice, String dataExampleHeader, String xmlExampleHeader) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        StringBuffer example = new StringBuffer();

        // add the invoice summary and the example code
        if (invoice.hasItem("invoice.summary")) {
            example.append(dataExampleHeader);
            example.append(invoice.getItemValueString("invoice.summary"));
            example.append(xmlExampleHeader);
            // add JSON result object:
            example.append("<invoice>\n");
            example.append("   <cdtr.name>" + invoice.getItemValueString("cdtr.name") + "</cdtr.name>\n");
            example.append(
                    "   <invoice.number>" + invoice.getItemValueString("invoice.number") + "</invoice.number>\n");
            if (invoice.getItemValueDate("invoice.date") != null) {
                example.append(
                        "   <invoice.date>" + dateFormat.format(invoice.getItemValueDate("invoice.date"))
                                + "</invoice.date>\n");
            }
            if (invoice.getItemValueDate("invoice.duedate") != null) {
                example.append(
                        "   <invoice.duedate>" + dateFormat.format(invoice.getItemValueDate("invoice.duedate"))
                                + "</invoice.duedate>\n");
            }
            example.append("   <invoice.total type=\"double\">" + invoice.getItemValueDouble("invoice.total")
                    + "</invoice.total>\n");
            example.append("   <cdtr.iban>" + invoice.getItemValueString("cdtr.iban") + "</cdtr.iban>\n");
            example.append("   <cdtr.bic>" + invoice.getItemValueString("cdtr.bic") + "</cdtr.bic>\n");
            example.append("</invoice>\n");
        }
        return example.toString();
    }

    /**
     * Helper method to find the last 3 invoices by cdtr.name
     * 
     * @param cdtrName
     * @return
     */
    private List<ItemCollection> findLastInvoices(String companyName, String currentID) {
        List<ItemCollection> result = new ArrayList<>();

        String searchTerm = "(type:workitemarchive) AND ($modelversion:rechnungseingang*) AND ($taskid:5900) AND NOT ($uniqueid:"
                + currentID + ") AND (document.company:\""
                + companyName + "\")";
        try {
            result = documentService.find(searchTerm, 3, 0, "$modified", true);
        } catch (QueryException e) {
            logger.log(Level.SEVERE, "findLastInvoices - invalid query: {0}", e.getMessage());
        }

        logger.info("Found " + result.size() + " examples for '" + companyName + "'");
        return result;

    }

}
