package demo.mapi.ccv.eu.mapi_demo.handlers;

import java.text.SimpleDateFormat;
import java.util.Date;

import demo.mapi.ccv.eu.mapi_demo.AndroidLogger;
import demo.mapi.ccv.eu.mapi_demo.DelegationFactory;
import demo.mapi.ccv.eu.mapi_demo.Flow;
import eu.ccvlab.mapi.api.PaymentService;
import eu.ccvlab.mapi.api.TerminalService;
import eu.ccvlab.mapi.core.RequestType;
import eu.ccvlab.mapi.core.api.PaymentApi;
import eu.ccvlab.mapi.core.api.TerminalApi;
import eu.ccvlab.mapi.core.api.response.delegate.PaymentDelegate;
import eu.ccvlab.mapi.core.api.response.delegate.TerminalDelegate;
import eu.ccvlab.mapi.core.logging.MPALogging;
import eu.ccvlab.mapi.core.payment.Money;
import eu.ccvlab.mapi.core.payment.Payment;
import eu.ccvlab.mapi.core.terminal.ExternalTerminal;

public class OpiChFlowHandler implements PaymentHandler{

    private final DelegationFactory delegationFactory;
    private final SimpleDateFormat posTimestampFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ");

    public OpiChFlowHandler(DelegationFactory delegationFactory) {
        this.delegationFactory = delegationFactory;
    }

    @Override
    public void startPayment(ExternalTerminal externalTerminal, Payment payment) {
        PaymentDelegate delegate = delegationFactory.createPaymentDelegate(Flow.PAYMENT.description());
        PaymentApi paymentService = new PaymentService();
        paymentService.payment(externalTerminal, payment, delegate);
    }
    
    @Override
    public void startAbortOnNewConnection(ExternalTerminal externalTerminal) {
        TerminalDelegate delegate = delegationFactory.createPaymentAdministrationDelegate(Flow.ABORT_ON_NEW_CONNECTION.description());
        PaymentApi paymentService = new PaymentService();
        paymentService.abortOnNewConnection(externalTerminal, delegate);
    }

    @Override
    public void startRefund(ExternalTerminal externalTerminal, Payment.Type type, Money money, Integer referenceNumber) {
        Payment payment = Payment
                .builder()
                .type(type)
                .amount(money)
                .posTimestamp(posTimestampFormatter.format(new Date()))
                .build();
        PaymentDelegate delegate = delegationFactory.createPaymentDelegate(Flow.REFUND.description());
        PaymentApi paymentService = new PaymentService();
        paymentService.payment(externalTerminal, payment, delegate);
    }

    @Override
    public void startRetrieveLastTicket(ExternalTerminal externalTerminal) {
        TerminalDelegate delegate = delegationFactory.createPaymentAdministrationDelegate(Flow.RETRIEVE_LAST_TICKET.description());
        TerminalApi terminalService = new TerminalService();
        terminalService.retrieveLastTicket(externalTerminal, delegate);
    }

    @Override
    public void recoverPayment(ExternalTerminal externalTerminal, String paymentRequestId) {
        TerminalDelegate delegate = delegationFactory.createPaymentAdministrationDelegate(Flow.RECOVER_PAYMENT.description());
        TerminalApi terminalService = new TerminalService();
        terminalService.recoverPayment(externalTerminal, paymentRequestId, delegate);
    }

    @Override
    public void performPeriodClosing(ExternalTerminal externalTerminal) {
        TerminalApi terminalService = new TerminalService();
        TerminalDelegate delegate = delegationFactory.createPaymentAdministrationDelegate(Flow.PERFORM_PERIOD_CLOSING.description());
        terminalService.periodClosing(externalTerminal, delegate);
    }

    @Override
    public void getTransactionOverview(ExternalTerminal externalTerminal) {
        TerminalApi terminalService = new TerminalService();
        TerminalDelegate delegate = delegationFactory.createPaymentAdministrationDelegate(Flow.TRANSACTION_OVERVIEW.description());
        terminalService.transactionOverview(externalTerminal, delegate);
    }

    @Override
    public void activateTerminal(ExternalTerminal externalTerminal) {
        TerminalApi terminalService = new TerminalService();
        TerminalDelegate delegate = delegationFactory.createPaymentAdministrationDelegate(Flow.ACTIVATE_TERMINAL.description());
        terminalService.activateTerminal(externalTerminal, delegate);
    }

    @Override
    public void startVoid(ExternalTerminal externalTerminal, Payment.Type type, Money money, String transactionId, RequestType originalRequestType, String token) {
        Payment payment = Payment
                .builder()
                .type(type)
                .amount(money)
                .originalTransactionRequestType(originalRequestType)
                .posTimestamp(posTimestampFormatter.format(new Date()))
                .build();

        PaymentDelegate paymentDelegate = delegationFactory.createPaymentDelegate(Flow.VOID.description());
        PaymentApi paymentService = new PaymentService();
        paymentService.payment(externalTerminal, payment, paymentDelegate);
    }

    @Override
    public void startStatus(ExternalTerminal externalTerminal) {
        TerminalDelegate delegate = delegationFactory.createPaymentAdministrationDelegate(Flow.STATUS.description());
        TerminalApi terminalService = new TerminalService();
        terminalService.status(externalTerminal, delegate);
    }

    @Override
    public void startup(ExternalTerminal externalTerminal) {
        TerminalApi terminalService = new TerminalService();
        TerminalDelegate delegate = delegationFactory.createPaymentAdministrationDelegate(Flow.STARTUP.description());
        terminalService.startup(externalTerminal, delegate);
    }
}
