package org.jpos.tcpay;

import org.jpos.iso.ISOMsg;
import org.jpos.tcpay.acquirer.JposAcquirerTranslator;
import org.jpos.tcpay.acquirer.JposAcquirerTranslatorFactory;
import org.jpos.tcpay.connection.AcquirerChannel;
import org.jpos.tcpay.connection.AcquirerChannelFactory;
import org.jpos.tcpay.db.entity.*;
import org.jpos.tcpay.db.service.TransactionAuxUtils;
import org.jpos.tcpay.model.IsoAcquirerTerminal;
import org.jpos.util.AppLogger;
import org.jpos.util.LogEvent;

import java.util.Objects;
import java.util.Random;

public class TransactionRouter {
    int[] SUPPORTED_FIELDS = {3,4,5,9,11,12,13,22,23,24,25,37,38,39,41,42,44,49,54,55,60,62,63};
    private AppLogger logger = new AppLogger();

    TransactionAuxUtils transactionAuxUtils = new TransactionAuxUtils();
    public ISOMsg handleRequest(ISOMsg request) {
        try {


            // Identify the Acquirer Terminal
            PosTerminal posTerminal = transactionAuxUtils.getPosTerminalByTerminalId(request.getString(41));
            if (Objects.isNull(posTerminal)) {
                logger.log("No Matching AcquirerTerminal");
                return generateErrorMsg(request);
            }

            // Get First terminal
            AcquirerTerminal acquirerTerminal = posTerminal.getAcquirerTerminals().get(0);
            // Get Respective Acquirer instance
            Acquirer acquirer = acquirerTerminal.getAcquirer();
            AcquirerConnection acquirerConnection = transactionAuxUtils.getAcquirerConnectionByAcquirer(acquirer);
            if (Objects.isNull(acquirerConnection)) {
                logger.log("No Matching AcquirerConnection");
                return generateErrorMsg(request);
            }

            // Translate the request
            JposAcquirerTranslator translator = JposAcquirerTranslatorFactory.getJposAcquirerTranslator(acquirer.getName());
            if (Objects.isNull(translator)) {
                logger.log("No Matching JposAcquirerTranslator");
                return generateErrorMsg(request);
            }

            AcquirerChannel acquirerChannel = AcquirerChannelFactory.getAcquirerChannel(acquirer.getName());
            if (Objects.isNull(acquirerChannel)) {
                logger.log("No Matching AcquirerChannel");
                return generateErrorMsg(request);
            }

            IsoAcquirerTerminal isoAcquirerTerminal = new IsoAcquirerTerminal(acquirerTerminal.getTerminalId(), acquirerTerminal.getAcquirerMerchant().getMerchantId(), acquirer.getNii());

            ISOMsg acqRequest = translator.toMessage(request, isoAcquirerTerminal, null);

            // Send and receive the Payload
            ISOMsg acqResponse = acquirerChannel.transceive(acqRequest, acquirerConnection);
            if (Objects.isNull(acqResponse)) {
                logger.log("No Response From Acquirer " + acquirer.getName());
                return generateErrorMsg(request);
            }

            // Transform the Payload
            ISOMsg response = translator.fromMessage(acqResponse, request, null);

            // return the payload
            return response;
        } catch (Exception e) {
            logger.log("Exception while processing the txn ");
            logger.exceptionLog (e);
            return generateErrorMsg(request);
        }
    }

    private ISOMsg generateErrorMsg(ISOMsg request) {
        ISOMsg response = (ISOMsg)request.clone(SUPPORTED_FIELDS);
        response.set(39, "99");

        return response;
    }
}
