package com.braintree.order.service.impl;

import com.braintree.constants.BraintreeConstants;
import com.braintree.model.BrainTreePaymentInfoModel;
import com.braintree.order.dao.BrainTreeOrderDao;
import com.braintree.order.service.BraintreeOrderRetrievalService;
import com.braintree.transaction.service.BrainTreePaymentTransactionService;
import de.hybris.platform.core.model.order.AbstractOrderModel;
import de.hybris.platform.core.model.user.CustomerModel;
import de.hybris.platform.payment.model.PaymentTransactionModel;
import de.hybris.platform.search.restriction.SearchRestrictionService;
import de.hybris.platform.servicelayer.session.SessionExecutionBody;
import de.hybris.platform.servicelayer.session.SessionService;

public class DefaultBraintreeOrderRetrievalService implements BraintreeOrderRetrievalService {

    private SessionService sessionService;

    private SearchRestrictionService searchRestrictionService;

    private BrainTreePaymentTransactionService brainTreePaymentTransactionService;

    private BrainTreeOrderDao brainTreeOrderDao;

    @Override
    public PaymentTransactionModel getTransactionForId(final String transactionID) {
        // Create a temporary session context and disable restrictions
        final PaymentTransactionModel transaction = (PaymentTransactionModel) sessionService
            .executeInLocalView(new SessionExecutionBody() {
                @Override
                public Object execute() {
                    searchRestrictionService.disableSearchRestrictions();
                    final PaymentTransactionModel paymentTransactionModel = brainTreePaymentTransactionService
                        .getTransactionByRequestIdAndPaymentProvider(transactionID,
                            BraintreeConstants.BRAINTREE_PROVIDER_NAME);
                    return paymentTransactionModel != null ? paymentTransactionModel : null;
                }
            });

        return transaction;
    }

    @Override
    public String getOrderCodeForTransaction(final String transactionID) {
        final AbstractOrderModel order = getOrderForTransaction(transactionID);
        if (order != null) {
            return order.getCode();
        }
        return null;
    }

    @Override
    public AbstractOrderModel getOrderForTransaction(String transactionID) {
        final PaymentTransactionModel transactionModel = getTransactionForId(transactionID);
        if (transactionModel != null) {
            return transactionModel.getOrder();
        }
        return null;
    }

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

    public void setSearchRestrictionService(final SearchRestrictionService searchRestrictionService) {
        this.searchRestrictionService = searchRestrictionService;
    }

    public void setBrainTreePaymentTransactionService(
        final BrainTreePaymentTransactionService brainTreePaymentTransactionService) {
        this.brainTreePaymentTransactionService = brainTreePaymentTransactionService;
    }

    public Integer countOrdersWithExpiredTransactions(BrainTreePaymentInfoModel brainTreePaymentInfoModel, int expirationDays){
        return brainTreeOrderDao.countAllOrdersWithExpiredTransactions(brainTreePaymentInfoModel, expirationDays);
    }

    public Integer countOrdersWithExpiredTransactionsByCustomer(CustomerModel customerModel, int expirationDays) {
        return  brainTreeOrderDao.countOrdersWithExpiredTransactionsByCustomer(customerModel, expirationDays);
    }

    public void setBrainTreeOrderDao(BrainTreeOrderDao brainTreeOrderDao) {
        this.brainTreeOrderDao = brainTreeOrderDao;
    }
}
