package com.braintree.facade.impl;

import com.braintree.enums.BraintreePaymentTransactionStatus;
import com.braintree.facade.BrainTreeOrderFacade;
import com.braintree.model.PaymentTransactionLogEntryModel;
import com.braintree.transaction.service.BrainTreeTransactionService;
import com.braintreegateway.Transaction;
import com.braintreegateway.WebhookNotification;
import de.hybris.platform.core.enums.OrderStatus;
import de.hybris.platform.core.model.order.AbstractOrderModel;
import de.hybris.platform.payment.enums.PaymentTransactionType;
import de.hybris.platform.payment.model.PaymentTransactionModel;
import de.hybris.platform.servicelayer.model.ModelService;

import java.util.Date;

import static com.braintree.constants.BraintreeConstants.BRAINTREE_REJECT;
import static com.braintree.constants.BraintreeConstants.BRAINTREE_SUCCESS;

public class DefaultBrainTreeOrderFacade implements BrainTreeOrderFacade {

    private BrainTreeTransactionService brainTreeTransactionService;
    private ModelService modelService;

    @Override
    public void updateOrderStatusWithUsBankAccountPaymentMethod(WebhookNotification webhookNotification) {

        Transaction transaction = webhookNotification.getTransaction();
        Date time = transaction.getStatusHistory().get(transaction.getStatusHistory().size() - 1).getTimestamp().getTime();

        PaymentTransactionModel paymentTransactionModel = brainTreeTransactionService.findTransactionByTransactionId(transaction.getId());
        AbstractOrderModel orderModel = paymentTransactionModel.getOrder();

        PaymentTransactionLogEntryModel logEntryModel;
        String paymentTransactionStatus;

        if (webhookNotification.getKind() == WebhookNotification.Kind.TRANSACTION_SETTLEMENT_DECLINED) {
            orderModel.setStatus(OrderStatus.CANCELLED);
            paymentTransactionStatus = BraintreePaymentTransactionStatus.SETTLEMENT_DECLINED.toString();
            logEntryModel = brainTreeTransactionService.createTransactionLogEntry(PaymentTransactionType.CAPTURE.name(),
                    BRAINTREE_REJECT, transaction.getPaymentInstrumentType(), transaction.getAchReturnCode(), time);
        } else {
            paymentTransactionStatus = BraintreePaymentTransactionStatus.SETTLED.toString();
            logEntryModel = brainTreeTransactionService.createTransactionLogEntry(PaymentTransactionType.CAPTURE.name(),
                    BRAINTREE_SUCCESS, transaction.getPaymentInstrumentType(), null, time);
        }

        logEntryModel.setPaymentTransaction(paymentTransactionModel);
        modelService.save(logEntryModel);
        brainTreeTransactionService.saveBraintreeTransactionStatus(paymentTransactionStatus, paymentTransactionModel);
    }

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

    public void setModelService(ModelService modelService) {
        this.modelService = modelService;
    }
}
