package com.braintree.customersupportbackoffice.actions.order.refreshpaymentstatus;

import com.braintree.customersupportbackoffice.actions.order.AbstractOrderAction;
import com.braintree.enums.BraintreePaymentTransactionStatus;
import com.braintree.facade.backoffice.BraintreeBackofficeRefreshPaymentStatusFacade;
import com.hybris.cockpitng.actions.ActionContext;
import com.hybris.cockpitng.actions.ActionResult;
import de.hybris.platform.core.model.order.OrderModel;
import de.hybris.platform.payment.model.PaymentTransactionModel;
import org.zkoss.zul.Messagebox;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;

public class BraintreeRefreshPaymentStatusOrderAction extends AbstractOrderAction {

    private static final String REFRESH_PAYMENT_STATUS_SUCCESS = "braintree.refresh.payment.status.order.action.success";
    private static final String REFRESH_PAYMENT_STATUS_TITLE = "braintree.refresh.payment.status.order.action.title";

    @Resource(name = "braintreeBackofficeRefreshPaymentStatusFacade")
    private BraintreeBackofficeRefreshPaymentStatusFacade refreshPaymentStatusFacade;

    public ActionResult<OrderModel> perform(ActionContext<OrderModel> actionContext) {
        OrderModel orderModel = actionContext.getData();
        refreshPaymentStatusFacade.updateBraintreePaymentTransactionStatuses(orderModel.getPaymentTransactions());

        showMessage(actionContext);

        ActionResult<OrderModel> result = new ActionResult<>(ActionResult.SUCCESS);
        result.setStatusFlags(EnumSet.of(ActionResult.StatusFlag.OBJECT_MODIFIED));
        return result;
    }

    protected void showMessage(ActionContext<OrderModel> actionContext) {
        Messagebox.show(actionContext.getLabel(REFRESH_PAYMENT_STATUS_SUCCESS),
                actionContext.getLabel(REFRESH_PAYMENT_STATUS_TITLE), Messagebox.OK, Messagebox.INFORMATION);
    }

    @Override
    public boolean canPerform(ActionContext<OrderModel> actionContext) {
        if (actionContext.getData() != null) {
            return actionContext.getData().getPaymentTransactions().stream()
                    .map(PaymentTransactionModel::getBraintreePaymentTransactionStatus)
                    .anyMatch(status -> getPaymentTransactionStatuses().contains(status));
        }
        return false;
    }

    private List<BraintreePaymentTransactionStatus> getPaymentTransactionStatuses() {
        return Arrays.asList(BraintreePaymentTransactionStatus.AUTHORIZED,
                BraintreePaymentTransactionStatus.SUBMITTED_FOR_SETTLEMENT,
                BraintreePaymentTransactionStatus.SETTLING,
                BraintreePaymentTransactionStatus.SETTLEMENT_PENDING);
    }
}
