/**
 *
 * Apple Pay
 *
 * @author Presta-Module.com <support@presta-module.com>
 * @copyright Presta-Module
 *
 *           ____     __  __
 *          |  _ \   |  \/  |
 *          | |_) |  | |\/| |
 *          |  __/   | |  | |
 *          |_|      |_|  |_|
 *
 ****/

var pmApplePayPlugin = {
    debug: false,
    paymentRequest: null,
    session: null,
    stripeChargeUrl: null,
    stripeEditedDetailsUrl: null,
    // Product details
    idProduct: null,
    idProductAttribute: null,
    productQuantity: 1,
    hasProductsInCart: false,
    clearCartConfirmationMessage: null,
    shippingContact: null,
    hasShippingMethods: true,
    hasAddressErrors: false,
    shippingMethodOverride: null,

    // Check if Apple Pay is available, and trigger showApplePayButtons() if so
    showApplePayButtonsIfAvailable: function() {
        if (pmApplePayPlugin.debug) {
            console.log('[Apple Pay][Call] showApplePayButtonsIfAvailable');
        }

        Stripe.applePay.checkAvailability(function(applePayIsAvailable) {
            if (applePayIsAvailable) {
                if (pmApplePayPlugin.debug) {
                    console.log('[Apple Pay] Available');
                }
                // Display the Apple Pay button
                pmApplePayPlugin.showApplePayButtons();
            } else {
                if (pmApplePayPlugin.debug) {
                    console.error('[Apple Pay] Unavailable (need Safari 10+ and a registered domain name)');
                }
            }
        });
    },

    // Called when Apple Pay is available and can make payment on active card
    showApplePayButtons: function() {
        if (pmApplePayPlugin.debug) {
            console.log('[Apple Pay][Call] showApplePayButtons');
        }

        // Set button width to the same as confirmation button, if exists
        if ($('p.cart_navigation a.standard-checkout').width() > 0) {
            $('.pm-apple-pay-button').css('width', $('p.cart_navigation a.standard-checkout').width());
        } else if ($('.product #add_to_cart button').width() > 0) {
            $('.pm-apple-pay-button').css('width', $('.product #add_to_cart button').width());
        }
        $('.pm-apple-pay-container').removeClass('hidden');
        $(document).off('click', '.pm-apple-pay-button').on('click', '.pm-apple-pay-button', function(e) {
            e.preventDefault();
            pmApplePayPlugin.payWithApplePay($(this));
        });
    },

    // Called when Apple Pay is available and advancedeucompliance module is enabled
    fixDisplayPaymentEU: function() {
        parentToReplace = $('#pm-apple-pay-eu-container').parent().parent();
        parentToReplace.replaceWith($('#pm-apple-pay-eu-container'));
        $(document).on('click', '#pm-apple-pay-eu-container', function(e) {
            e.preventDefault();
            pmApplePayPlugin.payWithApplePay($(this));
        });
    },

    // Update product count in cart so we can show alert if needed
    updateCartProductsCount: function(ajaxOptions) {
        if (typeof(ajaxOptions) == 'object' && typeof(ajaxOptions.responseJSON) == 'object' && typeof(ajaxOptions.responseJSON.products) == 'object' && typeof(ajaxOptions.responseJSON.nbTotalProducts) == 'number') {
            pmApplePayPlugin.hasProductsInCart = (ajaxOptions.responseJSON.nbTotalProducts > 0);
        }
    },

    // Start a payment with Apple Pay
    payWithApplePay: function(sourceButton) {
        if (pmApplePayPlugin.debug) {
            console.log('[Apple Pay][Call] payWithApplePay');
        }

        // Reset any previous data to default values
        pmApplePayPlugin.shippingMethodOverride = null;
        pmApplePayPlugin.shippingContact = null;
        pmApplePayPlugin.hasShippingMethods = true;
        pmApplePayPlugin.hasAddressErrors = false;

        // Set Stripe publishable API Key
        Stripe.setPublishableKey(pmApplePayPlugin.stripePublishableKey);

        // Retrieve paymentRequest
        pmApplePayPlugin.idProduct = $(sourceButton).data('id-product');
        // Try to retrieve product informations first
        if (!isNaN(pmApplePayPlugin.idProduct)) {
            // Get id_product_attribute from button (product list) or product sheet
            pmApplePayPlugin.idProductAttribute = $(sourceButton).data('id-product-attribute');
            if (isNaN(pmApplePayPlugin.idProductAttribute)) {
                pmApplePayPlugin.idProductAttribute = $('#idCombination').val();
                if (isNaN(pmApplePayPlugin.idProductAttribute)) {
                    pmApplePayPlugin.idProductAttribute = $('input[name="id_product_attribute"]').val();
                    if (isNaN(pmApplePayPlugin.idProductAttribute)) {
                        pmApplePayPlugin.idProductAttribute = null;
                    }
                }
            }
            pmApplePayPlugin.productQuantity = $('#quantity_wanted').val();
            if (isNaN(pmApplePayPlugin.productQuantity)) {
                pmApplePayPlugin.productQuantity = $('input[name="qty"]').val();
            }
            if (isNaN(pmApplePayPlugin.productQuantity) || pmApplePayPlugin.productQuantity <= 0) {
                pmApplePayPlugin.productQuantity = 1;
            }
            // Show alert if there is at least one product in cart
            if (pmApplePayPlugin.hasProductsInCart) {
                if (confirm(pmApplePayPlugin.clearCartConfirmationMessage)) {
                    pmApplePayPlugin.paymentRequest = pmApplePayPlugin.getPaymentRequestDataFromProduct();
                } else {
                    return;
                }
            } else {
                pmApplePayPlugin.paymentRequest = pmApplePayPlugin.getPaymentRequestDataFromProduct();
            }
        } else {
            // Retrieve shopping cart informations
            pmApplePayPlugin.paymentRequest = pmApplePayPlugin.getPaymentRequestData(null, null);
        }

        // Build and begin Apple Pay session
        pmApplePayPlugin.session = Stripe.applePay.buildSession(pmApplePayPlugin.paymentRequest, pmApplePayPlugin.chargeCustomer, pmApplePayPlugin.stripeBuildSessionError);
        pmApplePayPlugin.session.begin();

        // Handle needed Apple Pay events
        // Cancel action
        pmApplePayPlugin.session.addEventListener('cancel', function(event) {
            if (pmApplePayPlugin.debug) {
                console.log('[Apple Pay][Event] cancel');
                console.log(event);
            }
        });
        // Shipping contact has changed
        pmApplePayPlugin.session.addEventListener('shippingcontactselected', function(event) {
            if (pmApplePayPlugin.debug) {
                console.log('[Apple Pay][Event] shippingcontactselected');
                console.log(event);
            }

            newPaymentRequestData = pmApplePayPlugin.getPaymentRequestData(event.shippingContact, null);
            if (!pmApplePayPlugin.hasShippingMethods || pmApplePayPlugin.hasAddressErrors) {
                pmApplePayPlugin.session.completeShippingContactSelection(ApplePaySession.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS, newPaymentRequestData.shippingMethods, newPaymentRequestData.total, newPaymentRequestData.lineItems);
            } else {
                pmApplePayPlugin.session.completeShippingContactSelection(ApplePaySession.STATUS_SUCCESS, newPaymentRequestData.shippingMethods, newPaymentRequestData.total, newPaymentRequestData.lineItems);
            }
        });
        // Shipping method has changed
        pmApplePayPlugin.session.addEventListener('shippingmethodselected', function(event) {
            if (pmApplePayPlugin.debug) {
                console.log('[Apple Pay][Event] shippingmethodselected');
                console.log(event);
            }

            newPaymentRequestData = pmApplePayPlugin.getPaymentRequestData(null, event.shippingMethod.identifier);
            pmApplePayPlugin.session.completeShippingMethodSelection(ApplePaySession.STATUS_SUCCESS, newPaymentRequestData.total, newPaymentRequestData.lineItems);
        });
    },

    // Retrieve paymentRequest used by Apple Pay
    getPaymentRequestData: function(shippingContact, carrierIdentifier) {
        if (pmApplePayPlugin.debug) {
            console.log('[Apple Pay][Call] getPaymentRequestData');
            console.log(shippingContact);
            console.log(carrierIdentifier);
        }

        if (typeof(shippingContact) == 'object' && shippingContact != null) {
            pmApplePayPlugin.shippingContact = shippingContact;
        }
        $.ajax({
            type: 'POST',
            url: pmApplePayPlugin.stripeEditedDetailsUrl,
            data: {
                shipping_contact: (typeof(pmApplePayPlugin.shippingContact) == 'object' ? JSON.stringify(pmApplePayPlugin.shippingContact) : null),
                carrier_identifier: (typeof(carrierIdentifier) != 'undefined' ? carrierIdentifier : null),
            },
            async: false,
            timeout: 120000,
            dataType: 'json',
        }).always(function(data, textStatus, errorThrown) {
            if (typeof(data) == 'object') {
                if (data.result == true) {
                    // Update newPaymentRequest global variable
                    pmApplePayPlugin.paymentRequest = data.paymentRequest;
                    pmApplePayPlugin.hasShippingMethods = data.hasShippingMethods;
                    pmApplePayPlugin.hasAddressErrors = data.hasAddressErrors;
                    pmApplePayPlugin.stripeChargeUrl = data.stripeChargeUrl;
                    if (pmApplePayPlugin.hasShippingMethods) {
                        pmApplePayPlugin.shippingMethodOverride = pmApplePayPlugin.paymentRequest.shippingMethods[0];
                    } else {
                        pmApplePayPlugin.shippingMethodOverride = null;
                    }
                } else {
                    // Show error
                    if (typeof(data.error) != 'undefined' && data.error.length) {
                        // Show error to the customer
                        alert(data.error);
                        if (typeof(data.redirectURL) != 'undefined' && data.redirectURL.length) {
                            window.location = data.redirectURL;
                        }
                    }
                }
            } else {
                if (pmApplePayPlugin.debug) {
                    console.error('[Apple Pay] Error while retrieving Payment Request');
                }
                pmApplePayPlugin.paymentRequest = null;
                pmApplePayPlugin.session.abort();
            }
        });

        return pmApplePayPlugin.paymentRequest;
    },

    // Retrieve paymentRequest used by Apple Pay
    getPaymentRequestDataFromProduct: function() {
        if (pmApplePayPlugin.debug) {
            console.log('[Apple Pay][Call] getPaymentRequestDataFromProduct');
        }

        $.ajax({
            type: 'POST',
            url: pmApplePayPlugin.stripeBuyProductUrl,
            data: {
                id_product: pmApplePayPlugin.idProduct,
                id_product_attribute: (typeof(pmApplePayPlugin.idProductAttribute) != 'undefined' && !isNaN(pmApplePayPlugin.idProductAttribute) ? pmApplePayPlugin.idProductAttribute : 0),
                quantity: (typeof(pmApplePayPlugin.productQuantity) != 'undefined' && !isNaN(pmApplePayPlugin.productQuantity) && pmApplePayPlugin.productQuantity > 0 ? pmApplePayPlugin.productQuantity : 1),
            },
            async: false,
            timeout: 120000,
            dataType: 'json',
        }).always(function(data, textStatus, errorThrown) {
            if (typeof(data) == 'object') {
                if (data.result == true) {
                    // Update paymentRequest variable
                    pmApplePayPlugin.paymentRequest = data.paymentRequest;
                    pmApplePayPlugin.stripeChargeUrl = data.stripeChargeUrl;
                    pmApplePayPlugin.stripeEditedDetailsUrl = data.stripeEditedDetailsUrl;
                } else {
                    // Show error
                    if (typeof(data.error) != 'undefined' && data.error.length) {
                        // Show error to the customer
                        alert(data.error);
                        if (typeof(data.redirectURL) != 'undefined' && data.redirectURL.length) {
                            window.location = data.redirectURL;
                        }
                    }
                }
            } else {
                if (pmApplePayPlugin.debug) {
                    console.error('[Apple Pay] Error while retrieving Payment Request');
                }
                pmApplePayPlugin.paymentRequest = null;
                pmApplePayPlugin.session.abort();
            }
        });

        return pmApplePayPlugin.paymentRequest;
    },

    // Action when customer is trying to pay
    chargeCustomer: function(payment, callback) {
        if (pmApplePayPlugin.debug) {
            console.log('[Apple Pay][Call] chargeCustomer');
            console.log(payment);
        }

        finalShippingMethod = null;
        if (pmApplePayPlugin.shippingMethodOverride != null) {
            finalShippingMethod = pmApplePayPlugin.shippingMethodOverride;
        } else if (typeof(payment.shippingMethod) == 'object') {
            finalShippingMethod = payment.shippingMethod;
        }

        $.ajax({
            type: 'POST',
            url: pmApplePayPlugin.stripeChargeUrl,
            data: {
                stripe_token: (typeof(payment.token) == 'object' ? JSON.stringify(payment.token) : null),
                shipping_contact: (typeof(payment.shippingContact) == 'object' ? JSON.stringify(payment.shippingContact) : null),
                shipping_method: (typeof(finalShippingMethod) == 'object' ? JSON.stringify(finalShippingMethod) : null),
            },
            async: true,
            timeout: 120000,
            dataType: 'json',
        }).always(function(data, textStatus, errorThrown) {
            if (pmApplePayPlugin.debug) {
                console.log('[Apple Pay][Call] chargeCustomer answer:');
                console.log(data);
            }

            if (typeof(data) == 'object') {
                if (data.result == true) {
                    callback(ApplePaySession.STATUS_SUCCESS);
                    // Redirect to confirmation page...
                    window.location = data.confirmationURL;
                } else {
                    if (typeof(data.error) != 'undefined' && data.error.length) {
                        // Payment or customer creation failed...
                        callback(ApplePaySession.STATUS_FAILURE);
                        // Show error to the customer
                        alert(data.error);
                        if (typeof(data.redirectURL) != 'undefined' && data.redirectURL.length) {
                            window.location = data.redirectURL;
                        }
                    }
                }
            } else {
                // Failed
                callback(ApplePaySession.STATUS_FAILURE);
            }
        });
    },

    // Action if Stripe is not able to start the session (API Error, Apple Pay error ?)
    stripeBuildSessionError: function(error) {
        alert('Stripe error: ' + error.message);
    },
}
