package com.braintree.service.impl;

import com.braintree.configuration.service.BrainTreeConfigService;
import com.braintree.hybris.data.graphql.commands.request.BrainTreeTransactionDescriptorInput;
import com.braintree.service.BrainTreeDescriptorService;
import com.braintree.util.BrainTreeUtils;
import de.hybris.platform.core.model.order.AbstractOrderEntryModel;
import de.hybris.platform.core.model.product.ProductModel;
import de.hybris.platform.order.CartService;

public class DefaultBrainTreeDescriptorService implements BrainTreeDescriptorService {

    private static final String PAYPAL_PRODUCT_NAME_PREFIX = "PAYPAL ";
    private static final String VENMO_PRODUCT_NAME_PREFIX = "VENMO  ";
    private static final String ASTERISK = "*";
    private static final String BLANK_STRING = " ";
    private static final int MAX_GENERAL_DESCRIPTOR_NAME_LENGTH = 22;
    private static final int ZERO_INDEX = 0;

    private CartService cartService;
    private BrainTreeConfigService brainTreeConfigService;

    @Override
    public boolean isDescriptorAvailable(String paymentProvider) {
        return !BrainTreeUtils.isUsBankAccountPayment(paymentProvider) &&
                areDescriptorFieldsAvailable();
    }

    @Override
    public BrainTreeTransactionDescriptorInput getTransactionDescriptor(String paymentProvider) {
        BrainTreeTransactionDescriptorInput descriptorInput = new BrainTreeTransactionDescriptorInput();

        descriptorInput.setName(getDescriptorName(paymentProvider));
        descriptorInput.setPhone(brainTreeConfigService.getDescriptorPhoneNumber());
        descriptorInput.setUrl(brainTreeConfigService.getDescriptorUrl());

        return descriptorInput;
    }


    private String getDescriptorName(String paymentProvider) {
        StringBuilder descriptorName = new StringBuilder();

        if (BrainTreeUtils.isPayPalPayment(paymentProvider)) {
            descriptorName.append(PAYPAL_PRODUCT_NAME_PREFIX);
        } else if (BrainTreeUtils.isVenmoPayment(paymentProvider)) {
            descriptorName.append(VENMO_PRODUCT_NAME_PREFIX);
        } else {
            descriptorName.append(brainTreeConfigService.getDescriptorBusinessName());
        }

        descriptorName.append(ASTERISK);
        descriptorName.append(getProductName());

        return truncateDescriptorName(descriptorName.toString());
    }

    private String getProductName() {
        String productName = brainTreeConfigService.getDescriptorProductName();

        if (productName == null) {
            productName = cartService.getSessionCart()
                    .getEntries()
                    .stream()
                    .findFirst()
                    .map(AbstractOrderEntryModel::getProduct)
                    .map(ProductModel::getName)
                    .orElseGet(() -> BLANK_STRING);
        }

        return productName;
    }

    private boolean areDescriptorFieldsAvailable() {
        return brainTreeConfigService.getDescriptorBusinessName() != null
                && brainTreeConfigService.getDescriptorPhoneNumber() != null
                && brainTreeConfigService.getDescriptorUrl() != null;
    }

    private String truncateDescriptorName(String fullDescriptorName) {
        if (fullDescriptorName.length() > MAX_GENERAL_DESCRIPTOR_NAME_LENGTH) {
            return fullDescriptorName.substring(ZERO_INDEX, MAX_GENERAL_DESCRIPTOR_NAME_LENGTH);
        }
        return fullDescriptorName;
    }

    public void setCartService(CartService cartService) {
        this.cartService = cartService;
    }

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