function createPayPalPaymentMarkFlow(paypalOptions) {
    if (checkIntentOption(paypalIntent) === false) {
        var globalErrorsComponent = $(CONST.MARK_PAYPAL_BUTTON);
        globalErrorsComponent.empty();
        globalErrorsComponent.append(createErrorDiv(ACC.addons.braintreeaddon['braintree.message.incorect.intent']))

    } else {
        if ($(CONST.MARK_PAYPAL_BUTTON).is(":empty")) {
            braintree.paypalCheckout.create({
                autoSetDataUserIdToken: shouldRenderPayPalChangePaymentButton,
                client: client
            }, function (paypalCheckoutErr, paypalCheckoutInstance) {
                const commit = paypalIntent === CONST.INTENT_SALE && userAction === 'true';
                loadSDK(paypalCheckoutInstance, paypalIntent, commit, paypalOptions.flow, function () {
                    payPalCheckoutRenderButton(paypalCheckoutInstance, CONST.MARK_PAYPAL_BUTTON, paypalOptions, commit, payPalButtonConfig);
                })
            });
        }
    }
}

function createPayPalExpressCheckout(paypalOptions, payPalButtonContainer, isMiniCartCheckout) {
    if ($(payPalButtonContainer).length > 0) {
        const commit = paypalIntent === CONST.INTENT_SALE && userAction === 'true';
        var isIntentValid = checkIntentOption(paypalIntent);
        if (isIntentValid === false) {
            var payPalErrorComponent = $(CONST.PAYPAL_EXPRESS_ERROR_ID);
            payPalErrorComponent.empty();
            payPalErrorComponent.append(createErrorDiv(ACC.addons.braintreeaddon['braintree.message.incorect.intent']));
            return;
        }

        braintree.paypalCheckout.create({
            autoSetDataUserIdToken: shouldRenderPayPalChangePaymentButton,
            client: client
        }, function (paypalCheckoutErr, paypalCheckoutInstance) {
            if (typeof paypal === 'undefined') {
                loadSDK(paypalCheckoutInstance, paypalIntent, commit, paypalOptions.flow, function () {
                    $(payPalButtonContainer).html('');
                    payPalCheckoutRenderButton(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonConfig, isMiniCartCheckout);

                    hidePayPalPayLaterMessages();
                });
            } else if (typeof addPaymentMethodsPage !== 'undefined' && typeof paypal === 'undefined') {
                loadSDK(paypalCheckoutInstance, paypalIntent, commit, paypalOptions.flow, function () {
                    payPalCheckoutRenderButton(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonConfig, isMiniCartCheckout);
                });
            } else {
                payPalCheckoutRenderButton(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonConfig, isMiniCartCheckout);
            }
        });
    }

}

function payPalCheckoutRenderButton(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonStyle, isMiniCartCheckout) {
    const isCheckoutFlow = getPaypalFlow().localeCompare(CONST.CHECKOUT_FLOW);
    if (isCheckoutFlow === 0) {
        if ((creditEnabled || shouldRenderPayPalChangePaymentButton) && storeInVault) {
            renderCheckoutBillingButtons(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonStyle, isMiniCartCheckout);
        }
        else {
            renderCheckoutFlowPayPalButtons(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonStyle, isMiniCartCheckout);
        }
    }
    else {
        renderVaultFlowPayPalButtons(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonStyle);
    }
}

function renderCheckoutFlowPayPalButtons(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonStyle, isMiniCartCheckout){
    let fundingSource;
    const defaultShippingAddressEditable = paypalOptions.shippingAddressEditable;
    try {
        paypal.Buttons({
            style: payPalButtonStyle,
            locale: braintreeLocale,
            commit: commit,
            onClick: function (button) {
                fundingSource = button.fundingSource;
                updatePaypalOptions(paypalOptions, fundingSource, defaultShippingAddressEditable);
            },
            createOrder: function () {
                return paypalCheckoutInstance.createPayment(paypalOptions);
            },
            onApprove: function (data) {
                data.intent = paypalIntent;
                return paypalCheckoutInstance.tokenizePayment(data).then(function (payload) {
                    payload.fundingSource = fundingSource;
                    processExpressCheckoutForm(payload, false, undefined, isMiniCartCheckout);
                });
            },
            onCancel: function () {},

            onError: function (err) {
                console.error('Error: ' + err, err);
                handlePayPalClientError(err);
            }
        }).render(payPalButtonContainer);
    }
    catch (err) {
        handlePayPalButtonError(err.message);
    }
}

function renderVaultFlowPayPalButtons(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonStyle){
    let fundingSource;
    const defaultShippingAddressEditable = paypalOptions.shippingAddressEditable;
    try {
        var buttonConfig = {
            style: payPalButtonStyle,
            locale: braintreeLocale,
            commit: commit,
            onClick: function (button) {
                fundingSource = button.fundingSource;
                updatePaypalOptions(paypalOptions, fundingSource, defaultShippingAddressEditable);
            },
            createBillingAgreement: function () {
                return paypalCheckoutInstance.createPayment(paypalOptions);
            },
            onApprove: function(data) {
                onApproveFunction (data, paypalCheckoutInstance, fundingSource)
            },
            onCancel: function (data) {},

            onError: function (err) {
                console.error('Error: ' + err, err);
                handlePayPalClientError(err);
            }
        };
        if (typeof addPaymentMethodsPage !== 'undefined' && typeof shoppingMiniCart === 'undefined') {
            addPaymentMethodPaypalSdk.Buttons(buttonConfig).render(payPalButtonContainer);
        } else {
            paypal.Buttons(buttonConfig).render(payPalButtonContainer).then(() => {
                 ACC.loadingSpinner.hideSpinner(CONST.LOGIN_SAVE_PAYMENT_INFO_BUTTONS_CONTAINER);
            });
        }
    }
    catch (err) {
        handlePayPalButtonError(err.message);
    }
}

function renderCheckoutBillingButtons(paypalCheckoutInstance, payPalButtonContainer, paypalOptions, commit, payPalButtonStyle, isMiniCartCheckout){
    let fundingSource;
    let addressForOverriding;
    const defaultShippingAddressEditable = paypalOptions.shippingAddressEditable;
    if (shouldRenderPayPalChangePaymentButton && shippingAddressOverride) {
        addressForOverriding = createAddressForOverriding(paypalOptions.shippingAddressOverride);
    }
    try {
        paypal.Buttons({
            style: payPalButtonStyle,
            locale: braintreeLocale,
            commit: commit,
            onClick: function (button) {
                fundingSource = button.fundingSource;
                updatePaypalOptions(paypalOptions, fundingSource, defaultShippingAddressEditable);
            },
            createOrder: function () {
                return paypalCheckoutInstance.createPayment(paypalOptions);
            },
            onApprove: function(data) {
                onApproveFunction(data, paypalCheckoutInstance, fundingSource, isMiniCartCheckout, addressForOverriding)
            },
            onCancel: function (data) {},

            onError: function (err) {
                console.error('Error: ' + err, err);
                handlePayPalClientError(err);
            }
        }).render(payPalButtonContainer);
    }
    catch (err) {
        handlePayPalButtonError(err.message);
    }
}

function updatePaypalOptions(paypalOptions, fundingSource, defaultShippingAddressEditable) {
    if (fundingSource === CONST.PAYPAL_FUNDING_CARD) {
        paypalOptions.shippingAddressEditable = true;
    } else {
        paypalOptions.shippingAddressEditable = defaultShippingAddressEditable;
    }

    if (fundingSource === CONST.PAYPAL_FUNDING_PAYLATER){
        paypalOptions.requestBillingAgreement = false;
    }
}

function handlePayPalClientError(error) {
    if (error != null && (typeof error != 'undefined' || error !== 'undefined')) {
        // skip validation error: use paypal method
        if (error.message !== 'User did not enter a payment method' && error.code !== 'PAYPAL_POPUP_CLOSED') {
            $('#paypal_express_error').empty();
            var messageText = error.message;
            if (typeof messageText === 'undefined' || messageText === 'undefined') {
                //Undefined error
            } else {
                if(error.code === "PAYPAL_INVALID_PAYMENT_OPTION"){
                    $(CONST.GLOBAL_MESSAGES).empty();
                    $(CONST.GLOBAL_MESSAGES).append(createErrorDiv(createErrorDiv(ACC.addons.braintreeaddon['braintree.message.error.invalidPaypalOptions'])));
                } else {
                    var errorMsg = (typeof getErrorMessage(error.code) === "undefined")
                        ? ACC.addons.braintreeaddon['braintree.message.error.provider'] + ' ' + messageText : getErrorMessage(error.code);
                    $(CONST.GLOBAL_MESSAGES).empty();
                    $(CONST.GLOBAL_MESSAGES).append(createErrorDiv(createErrorDiv(errorMsg)));
                }
            }
        }
    }
}

function handlePayPalButtonError(errorMsg) {
    if (typeof errorMsg !== 'undefined' || errorMsg !== 'undefined') {
        if (typeof paymentMethodsPage != "undefined") {
            $(CONST.PAYPAL_BUTTON_MESSAGE).empty();
            $(CONST.PAYPAL_BUTTON_MESSAGE).append(createErrorDiv(createErrorDiv(errorMsg)));
        }
        $('#paypal_express_error').empty();
        $(CONST.PAYPAL_EXPRESS_ERROR_ID).empty();
        $(CONST.PAYPAL_EXPRESS_ERROR_ID).append(createErrorDiv(errorMsg));
    }
}

function onApproveFunction(data, paypalCheckoutInstance, fundingSource, isMiniCartCheckout, addressForOverriding) {
    return paypalCheckoutInstance.tokenizePayment(data).then(function (payload) {
        payload.fundingSource = fundingSource;
        processExpressCheckoutForm(payload, typeof payPalShouldBeSaved !== "undefined" ? payPalShouldBeSaved : false, undefined , isMiniCartCheckout, addressForOverriding);
    });
}

    function createAddressForOverriding(shippingAddressOverride){
        const recipientName = shippingAddressOverride.recipientName.split(' ');
        let newRecipientName;
        let phone;

        if (shippingAddressOverride.phone!==''){
            phone=shippingAddressOverride.phone;
        }

        if(recipientName.length<3){
            newRecipientName = shippingAddressOverride.recipientName;
        }else{
            newRecipientName=recipientName[1]
            .concat(' ')
            .concat(recipientName[2])
        }

        return {
            phone: phone,
            recipientName: newRecipientName
        }
    }
