package com.braintree.actions.order;


import com.braintree.configuration.service.BrainTreeConfigService;
import com.braintree.model.BrainTreePaymentInfoModel;
import com.braintree.util.BrainTreeUtils;
import de.hybris.platform.core.model.order.OrderModel;
import de.hybris.platform.orderprocessing.model.OrderProcessModel;
import de.hybris.platform.processengine.action.AbstractSimpleDecisionAction;
import de.hybris.platform.servicelayer.session.SessionExecutionBody;
import de.hybris.platform.servicelayer.session.SessionService;
import org.apache.log4j.Logger;

import java.util.Map;

public class BrainTreeGoToSubmitForSettlementAction extends AbstractSimpleDecisionAction<OrderProcessModel> {

    private static final Logger LOG = Logger.getLogger(BrainTreeGoToSubmitForSettlementAction.class);

    private static final String CURRENT_SITE = "currentSite";

    private BrainTreeConfigService brainTreeConfigService;
    private SessionService sessionService;

    @Override
    public Transition executeAction(OrderProcessModel orderProcessModel) throws Exception {
        return sessionService.executeInLocalViewWithParams(Map.of(CURRENT_SITE, orderProcessModel.getOrder().getSite()), new SessionExecutionBody() {
            @Override
            public Object execute() {
                final OrderModel order = orderProcessModel.getOrder();

                if (order.getPaymentInfo() != null && order.getPaymentInfo() instanceof BrainTreePaymentInfoModel) {
                    if (canCreateCaptureTransactionForOrder(order)) {
                        LOG.info("[BRAINTREE ORDER PROCESS] Order process (orderProcess.code " + orderProcessModel.getCode()
                                + ") will be captured. order.code: " + order.getCode());
                        return Transition.OK;
                    }
                    LOG.info("[BRAINTREE ORDER PROCESS] Order process (code " + orderProcessModel.getCode()
                            + ") is waiting for submitForSettlement event.");
                    return Transition.NOK;
                }

                LOG.warn(
                        "[BRAINTREE ORDER PROCESS] PayPal intent not found for this order. Order process is stopped and waiting for submitForSettlement event, order.code: "
                                + order.getCode());
                return Transition.OK;
            }
        });
    }

    private boolean canCreateCaptureTransactionForOrder(OrderModel order) {
        final String paymentProvider = ((BrainTreePaymentInfoModel) order.getPaymentInfo()).getPaymentProvider();
        final String intent = ((BrainTreePaymentInfoModel) order.getPaymentInfo()).getPayPalIntent();
        if (BrainTreeUtils.isApplePayPayment(paymentProvider)) {
            return brainTreeConfigService.isSubmitForSettlement();
        }
        if (BrainTreeUtils.isGooglePayment(paymentProvider)) {
            return brainTreeConfigService.isSubmitForSettlement();
        }
        if (BrainTreeUtils.isSrcPayment(paymentProvider)) {
            return brainTreeConfigService.isSubmitForSettlement();
        }
        if (BrainTreeUtils.isCreditCardPayment(paymentProvider)) {
            return brainTreeConfigService.isSubmitForSettlement();
        }
        if (BrainTreeUtils.isVenmoPayment(paymentProvider)) {
            return brainTreeConfigService.isSubmitForSettlement();
        }
        if (BrainTreeUtils.isPayPalPayment(paymentProvider)) {
            LOG.warn("intent: " + intent);
            return BrainTreeUtils.isIntentSale(intent);
        }
        if (BrainTreeUtils.isLPMPayment(paymentProvider)) {
            return BrainTreeUtils.isIntentSale(intent);
        }
        if (BrainTreeUtils.isUsBankAccountPayment(paymentProvider)) {
            return true;
        }
        LOG.warn("[BRAINTREE ORDER PROCESS] Unknown payment provider: " + paymentProvider);
        return false;
    }

    public void setBrainTreeConfigService(BrainTreeConfigService brainTreeConfigService) {
        this.brainTreeConfigService = brainTreeConfigService;
    }

    public void setSessionService(SessionService sessionService) {
        this.sessionService = sessionService;
    }

}

