package com.braintree.customersupportbackoffice.services.impl;

import com.braintree.configuration.service.BrainTreeConfigService;
import com.braintree.customersupportbackoffice.services.BrainTreeOrderManagementActionsService;
import com.braintree.model.BrainTreePaymentInfoModel;
import com.braintree.order.capture.partial.services.BraintreePartialCaptureService;
import com.braintree.util.BrainTreeUtils;
import de.hybris.platform.core.enums.OrderStatus;
import de.hybris.platform.core.model.order.OrderModel;
import de.hybris.platform.payment.dto.TransactionStatus;
import de.hybris.platform.payment.enums.PaymentTransactionType;
import de.hybris.platform.payment.model.PaymentTransactionEntryModel;
import de.hybris.platform.payment.model.PaymentTransactionModel;
import de.hybris.platform.returns.ReturnService;
import java.math.BigDecimal;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

@Deprecated
public class BrainTreeOrderManagementActionsServiceImpl implements BrainTreeOrderManagementActionsService {

    private BrainTreeConfigService brainTreeConfigService;
    private BraintreePartialCaptureService braintreePartialCaptureService;
    private ReturnService returnService;

    @Deprecated
    @Override
    public boolean isMultipleCapturePossible(final OrderModel order) {
        if (order != null && order.getPaymentInfo() instanceof BrainTreePaymentInfoModel) {
            return isSuccessfulTransactionPresent(order, PaymentTransactionType.AUTHORIZATION);
        }
        return false;
    }

    @Deprecated
    @Override
    public boolean isPartialRefundPossible(final OrderModel order) {
        if (order == null) {
            return false;
        }
        BigDecimal capturedAmount = BigDecimal.ZERO;
        for (final PaymentTransactionModel paymentTransaction : order.getPaymentTransactions()) {
            for (final PaymentTransactionEntryModel transactionEntry : paymentTransaction.getEntries()) {
                if ("SUCCESFULL".equals(transactionEntry.getTransactionStatusDetails()) &&
                    TransactionStatus.ACCEPTED.name().equals(transactionEntry.getTransactionStatus())) {
                    capturedAmount = checkTransactionTypeAndAddCapturedAmount(transactionEntry, capturedAmount);
                }
            }
        }
        return capturedAmount.compareTo(BigDecimal.ZERO) > 0;
    }

    private BigDecimal checkTransactionTypeAndAddCapturedAmount(PaymentTransactionEntryModel transactionEntry,
                                                                BigDecimal capturedAmount) {
        final PaymentTransactionType transactionType = transactionEntry.getType();
        if (PaymentTransactionType.CAPTURE.equals(transactionType) || PaymentTransactionType.PARTIAL_CAPTURE
                .equals(transactionType)) {
            capturedAmount = capturedAmount.add(transactionEntry.getAmount());
        } else if (PaymentTransactionType.REFUND_PARTIAL.equals(transactionType)) {
            capturedAmount = capturedAmount.subtract(transactionEntry.getAmount());
        }
        return capturedAmount;
    }

    @Deprecated
    @Override
    public boolean isMultiCaptureEnabled() {
        return brainTreeConfigService.isMultiCaptureEnabled();
    }

    @Deprecated
    @Override
    public boolean isRefundPossible(OrderModel order) {
        if (order != null && !returnService.getAllReturnableEntries(order).isEmpty()) {
            if (OrderStatus.COMPLETED.equals(order.getStatus())) {
                return true;
            }
            if (isMultiCaptureEnabled()) {
                boolean isRefundPossible = false;
                isRefundPossible = !isPartialCaptureTakePlace(order);
                return isRefundPossible && StringUtils.isBlank(order.getVersionID());
            }
            return StringUtils.isBlank(order.getVersionID());
        }
        return false;
    }

    private boolean isPartialCaptureTakePlace(OrderModel order) {
        final List<PaymentTransactionModel> paymentTransactions = order.getPaymentTransactions();

        if (CollectionUtils.isNotEmpty(paymentTransactions)) {
            final PaymentTransactionModel next = paymentTransactions.iterator().next();
            final List<PaymentTransactionEntryModel> paymentTransactionEntries = next.getEntries();
            for (final PaymentTransactionEntryModel paymentTransactionEntry : paymentTransactionEntries) {
                if (PaymentTransactionType.PARTIAL_CAPTURE.equals(paymentTransactionEntry.getType())) {

                    return true;
                }
            }
        }
        return false;
    }

    @Deprecated
    @Override
    public boolean isReplacePossible(OrderModel order) {
        return order != null && StringUtils.isBlank(order.getVersionID());
    }

    public BrainTreeConfigService getBrainTreeConfigService() {
        return brainTreeConfigService;
    }

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

    public BraintreePartialCaptureService getBraintreePartialCaptureService() {
        return braintreePartialCaptureService;
    }

    public void setBraintreePartialCaptureService(BraintreePartialCaptureService braintreePartialCaptureService) {
        this.braintreePartialCaptureService = braintreePartialCaptureService;
    }

    public ReturnService getReturnService() {
        return returnService;
    }

    public void setReturnService(ReturnService returnService) {
        this.returnService = returnService;
    }

    private boolean isSuccessfulTransactionPresent(final OrderModel order, PaymentTransactionType transactionType) {
        for (final PaymentTransactionModel paymentTransaction : order.getPaymentTransactions()) {
            for (final PaymentTransactionEntryModel transactionEntry : paymentTransaction.getEntries()) {
                if (transactionType.equals(transactionEntry.getType()) &&
                    "SUCCESFULL".equals(transactionEntry.getTransactionStatusDetails()) &&
                    TransactionStatus.ACCEPTED.name().equals(transactionEntry.getTransactionStatus())) {
                    return true;
                }
            }
        }
        return false;
    }

}
