package com.braintree.order.capture.partial.strategy.impl;

import com.braintree.enums.BraintreePaymentTransactionStatus;
import com.braintree.model.BrainTreePaymentInfoModel;
import com.braintree.order.capture.partial.strategy.BraintreePartialOrderCalculationStrategy;
import com.braintree.transaction.service.BrainTreeTransactionService;
import com.braintree.util.BrainTreeUtils;
import de.hybris.platform.core.model.order.OrderModel;
import de.hybris.platform.payment.dto.TransactionStatus;
import de.hybris.platform.payment.dto.TransactionStatusDetails;
import de.hybris.platform.payment.enums.PaymentTransactionType;
import de.hybris.platform.payment.model.PaymentTransactionEntryModel;
import de.hybris.platform.payment.model.PaymentTransactionModel;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;


public class DefaultBraintreePartialOrderCalculationStrategy implements BraintreePartialOrderCalculationStrategy {

    //add service
    private BrainTreeTransactionService brainTreeTransactionService;

    @Override
    public BigDecimal calculateCaptureAmount(OrderModel orderModel) {
        final List<PaymentTransactionModel> paymentTransactions = orderModel.getPaymentTransactions();
        final Iterator<PaymentTransactionModel> iterator = paymentTransactions.iterator();
        if (iterator.hasNext()) {
            final PaymentTransactionModel paymentTransactionModel = iterator.next();
            if (paymentTransactionModel != null && isTransactionAvailableForSettlement(paymentTransactionModel)) {
                return calculateTransaction(paymentTransactionModel, orderModel.getTotalPrice());
            }
        }
        return BigDecimal.ZERO;
    }

    @Override
    public BigDecimal calculateTransaction(PaymentTransactionModel paymentTransactionModel, Double totalAmount) {
        BigDecimal amount = BigDecimal.ZERO;
        final List<PaymentTransactionEntryModel> entries = paymentTransactionModel.getEntries();
        for (final PaymentTransactionEntryModel entryModel : entries) {
            if ((PaymentTransactionType.PARTIAL_CAPTURE.equals(entryModel.getType())
                || PaymentTransactionType.CAPTURE.equals(entryModel.getType()))
                && TransactionStatus.ACCEPTED.name().equals(entryModel.getTransactionStatus())
                && TransactionStatusDetails.SUCCESFULL.name().equals(entryModel.getTransactionStatusDetails())) {
                totalAmount = getBrainTreeTransactionService()
                        .calculateTotalAmount(paymentTransactionModel.getOrder()).doubleValue();
                amount = amount.add(entryModel.getAmount());
            }
        }
        return BigDecimal.valueOf(totalAmount).subtract(amount);
    }

    private boolean isTransactionAvailableForSettlement(PaymentTransactionModel paymentTransactionModel) {
        boolean isTransactionAvailableForSettlement;
        final String paymentProvider = ((BrainTreePaymentInfoModel) paymentTransactionModel.getOrder().getPaymentInfo()).getPaymentProvider();
        final BraintreePaymentTransactionStatus transactionStatus = paymentTransactionModel.getBraintreePaymentTransactionStatus();

        if (BrainTreeUtils.isPayPalPayment(paymentProvider)) {
            isTransactionAvailableForSettlement = (BraintreePaymentTransactionStatus.AUTHORIZED.equals(transactionStatus) ||
                    BraintreePaymentTransactionStatus.SETTLEMENT_PENDING.equals(transactionStatus));
        } else {
            isTransactionAvailableForSettlement = !BraintreePaymentTransactionStatus.SETTLEMENT_DECLINED.equals(transactionStatus);
        }

        return isTransactionAvailableForSettlement;
    }

    public BrainTreeTransactionService getBrainTreeTransactionService() {
        return brainTreeTransactionService;
    }

    public void setBrainTreeTransactionService(BrainTreeTransactionService brainTreeTransactionService) {
        this.brainTreeTransactionService = brainTreeTransactionService;
    }
}
