package com.braintree.order.dao.impl;

import com.braintree.model.BrainTreePaymentInfoModel;
import com.braintree.order.dao.BrainTreeOrderDao;
import de.hybris.platform.core.enums.OrderStatus;
import de.hybris.platform.core.model.order.OrderModel;
import de.hybris.platform.core.model.user.CustomerModel;
import de.hybris.platform.servicelayer.internal.dao.AbstractItemDao;
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery;

import java.util.List;

public class DefaultBrainTreeOrderDao extends AbstractItemDao implements BrainTreeOrderDao {

    private static final String BASE_QUERY_LEADING =
            "SELECT COUNT({" + OrderModel.PK + "}) " +
                    "FROM {" + OrderModel._TYPECODE + " AS order " +
                    "JOIN " + BrainTreePaymentInfoModel._TYPECODE + " AS pm " +
                    "ON {order:" + OrderModel.PAYMENTINFO + "}={pm:" + BrainTreePaymentInfoModel.PK + "} }" +
                    "WHERE {order:" + OrderModel.STATUS + "} IS NULL OR ({order:" + OrderModel.STATUS +"} <> ?status ";

    private static final String BASE_QUERY_ENDING =
            "AND {order:" + OrderModel.CREATIONTIME + "} >= DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL ?expirationDays DAY))";


    @Override
    public Integer countAllOrdersWithExpiredTransactions(BrainTreePaymentInfoModel paymentInfoModel, int expirationDays) {
        final FlexibleSearchQuery query = new FlexibleSearchQuery(
                BASE_QUERY_LEADING +
                        "AND {pm:" + BrainTreePaymentInfoModel.ORIGINAL + "} = ?paymentId " +
                        BASE_QUERY_ENDING
        );

        query.addQueryParameter("paymentId", paymentInfoModel.getPk());
        query.addQueryParameter("expirationDays", expirationDays);
        query.addQueryParameter("status", OrderStatus.COMPLETED);

        return executeQuery(query);
    }

    @Override
    public Integer countOrdersWithExpiredTransactionsByCustomer(CustomerModel customerModel, int expirationDays) {
        final FlexibleSearchQuery query = new FlexibleSearchQuery(
                BASE_QUERY_LEADING +
                        "AND {pm:user}=?currentUser " +
                        BASE_QUERY_ENDING
        );

        query.addQueryParameter("currentUser", customerModel);
        query.addQueryParameter("expirationDays", expirationDays);
        query.addQueryParameter("status", OrderStatus.COMPLETED);

        return executeQuery(query);
    }

    private Integer executeQuery(FlexibleSearchQuery flexibleSearchQuery) {
        flexibleSearchQuery.setResultClassList(List.of(Integer.class));
        List<Integer> result = getFlexibleSearchService().<Integer>search(flexibleSearchQuery).getResult();
        return result.isEmpty() ? 0 : result.get(0);
    }
}
