package org.jpos.tcpay.acquirer.ysp;

import com.google.gson.Gson;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.packager.ISO87BPackager;
import org.jpos.tcpay.acquirer.JposAcquirerTranslator;
import org.jpos.tcpay.data_element.AdditionalData;
import org.jpos.tcpay.model.IsoAcquirerTerminal;
import org.jpos.util.AppLogger;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

public class JposYspTranslator implements JposAcquirerTranslator {
    private AppLogger logger = new AppLogger();
    private YspRequestManager yspRequestManager = new YspRequestManager();


    int[] SUPPORTED_FIELDS = {2,3,4,11,12,13,14,22,23,24,25,35,37,38,39,41,42,49,52,55,62,63};
    @Override
    public ISOMsg toMessage(ISOMsg isoMsg, IsoAcquirerTerminal isoAcquirerTerminal, Map<String, Object> metadata) {
        try {
            ISOMsg  acqRequest = (ISOMsg) isoMsg.clone(SUPPORTED_FIELDS);
            acqRequest.setPackager(new ISO87BPackager());
            if ("0800".equals(isoMsg.getMTI())) {
                if (!isoMsg.hasField(3)) {
                    return yspRequestManager.getNetworkMsgEcho(isoMsg, isoAcquirerTerminal, metadata);
                } else if ("810000".equals(isoMsg.getString(3))) {
                    return yspRequestManager.getNetworkMsgTmK(isoMsg, isoAcquirerTerminal, metadata);
                } else if ("811000".equals(isoMsg.getString(3))) {
                    return yspRequestManager.getNetworkMsgPinIpek(isoMsg, isoAcquirerTerminal, metadata);
                }  else {
                    return null;
                }
            } else if ("0100".equals(isoMsg.getMTI())) {
                // Preauth
                return yspRequestManager.getPreauthMsg(isoMsg, isoAcquirerTerminal, metadata);
            } else if ("0200".equals(isoMsg.getMTI())) {
                // Sale or Void
                if ("02".equals(isoMsg.getString(3).substring(0, 2)))  {
                    return yspRequestManager.getVoidMsg(isoMsg, isoAcquirerTerminal, metadata);
                } else {
                    return yspRequestManager.getSaleMsg(isoMsg, isoAcquirerTerminal, metadata);
                }

            } else if ("0220".equals(isoMsg.getMTI())) {
                // Refund
                if ("20".equals(isoMsg.getString(3).substring(0, 2)))  {
                    return yspRequestManager.getRefundMsg(isoMsg, isoAcquirerTerminal, metadata);
                } else {
                    return yspRequestManager.getCompletionMsg(isoMsg, isoAcquirerTerminal, metadata);
                }
            } else if ("0400".equals(isoMsg.getMTI())) {
                // Reversal
                return yspRequestManager.getReversal(isoMsg, isoAcquirerTerminal, metadata);

            } else {
                return null;
            }
        } catch (ISOException e) {
            logger.exceptionLog(e);
        }

        return null;
    }

    @Override
    public ISOMsg fromMessage(ISOMsg isoMsg, ISOMsg jposRequest, Map<String, Object> metadata) throws ISOException {

        ISOMsg  jposResponse = (ISOMsg) isoMsg.clone(SUPPORTED_FIELDS);
        jposResponse.setPackager(new ISO87BPackager());

        if ("0800".equals(jposRequest.getMTI())) {
            // Echo Message
            jposResponse.set(3, jposRequest.getString(3));
            jposResponse.set(41, jposRequest.getString(41));
            jposResponse.set(42, jposRequest.getString(42));
            jposResponse.set(63, isoMsg.getString(62));
            jposResponse.unset(53);
            jposResponse.unset(70);

        } else {
            jposResponse.set(3, jposRequest.getString(3));
            jposResponse.set(11, jposRequest.getString(11));
            jposResponse.set(24, jposRequest.getString(24));
            jposResponse.set(25, jposRequest.getString(25));
            jposResponse.set(41, jposRequest.getString(41));
            jposResponse.set(42, jposRequest.getString(42));
            jposResponse.unset(63);
        }

        jposResponse.setMTI(jposRequest.getMTI());
        jposResponse.setResponseMTI();
        byte[] srcHeader = jposRequest.getHeader();
        if (Objects.nonNull(srcHeader)) {
            byte[] destHeader = new byte[5];
            System.arraycopy(srcHeader, 0, destHeader, 0, 5);
            destHeader[1] = srcHeader[3]; destHeader[2] = srcHeader[4];
            destHeader[3] = srcHeader[1]; destHeader[4] = srcHeader[2];
            jposResponse.setHeader(destHeader);

        }

        return jposResponse;
    }

    @Override
    public ISOMsg toMessageReversal(ISOMsg isoMsg, IsoAcquirerTerminal isoAcquirerTerminal, Map<String, Object> metadata) {
        isoMsg.set(90, yspRequestManager.getField90(yspRequestManager.getOriginalInfo(isoMsg)));
        isoMsg.set(25, "00");
        isoMsg.unset(37);
        isoMsg.unset(63);
        isoMsg.unset(47);
        return isoMsg;
    }
}
