/**
 * 2007-2021 PrestaShop
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
 * versions in the future. If you wish to customize PrestaShop for your
 * needs please refer to http://www.prestashop.com for more information.
 *
 *  @author    PrestaShop SA <contact@prestashop.com>
 *  @copyright 2007-2021 PrestaShop SA
 *  @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 *  International Registered Trademark & Property of PrestaShop SA
 *
 * Don't forget to prefix your containers with your own identifier
 * to avoid any conflicts with others containers.
 */

(function () {

    const bnplBanner = {
        jsonData: {},
        checkExpireThreshold: 60000,
        token: '',
        tokenValidity: 0,
        tokenPromise: null,
        init: function() {
            let that = this;
            let controllers = ['product', 'cart', 'order'];

            if( !controllers.includes(addonpayments.controller) ) {
                return;
            }

            this.token = addonpayments.authToken.token;
            this.tokenValidity = addonpayments.authToken.tokenValidity;
            this.jsonData = this.getJsonData();

            /** @var {Object} prestashop */
            if (typeof prestashop !== 'undefined') {
                // Prestashop 1.7 - update product.
                prestashop.on('updateProduct', this.checkOnUpdate.bind(this));
                prestashop.on('updatedProduct', this.renderOnUpdated.bind(this));
                // Prestashop 1.7 - update cart.
                prestashop.on('updateCart', this.checkOnUpdate.bind(this));
                prestashop.on('updatedCart', this.renderOnUpdated.bind(this));
            }else {
                // Prestashop 1.6
                if(addonpayments.controller === 'product') {
                    // From back we are going to have always the default product price not the variation price so
                    // we take it from priceWithDiscountsDisplay.
                    if (typeof priceWithDiscountsDisplay !== 'undefined') {
                        this.jsonData.amount = priceWithDiscountsDisplay * 100;

                    }
                    // Prestashop 1.6 - update product
                    $('#our_price_display').on('change', function () {
                        if(typeof priceWithDiscountsDisplay !== 'undefined') {
                            window.addonpaymentsAmountUpdate = priceWithDiscountsDisplay
                        }
                        that.renderOnUpdated()
                    });
                }else if(addonpayments.controller === 'order') {
                    const orderDetail = document.getElementById('order-detail-content');
                    const widgetDiv = document.getElementById('addon-payments-widget');

                    if( null !== orderDetail && null !== widgetDiv) {
                        orderDetail.after(widgetDiv)

                        MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

                        const element = document.getElementById('total_price');

                        var observer = new MutationObserver(function (mutations, observer) {
                            that.renderOnUpdated();
                        });
                        observer.observe(element, {
                            characterData: true,
                            childList: true
                        });
                    }
                }
            }

            this.render();
        },
        render: function() {
            NEMURUWIDGET.setEpgBaseUrl(addonpayments.baseUrl);
            NEMURUWIDGET.renderSimulationWidget(this.token, this.jsonData, 'addon-payments-widget', 'Nemuru');
        },
        checkOnUpdate: function() {
            var currentTime = Date.now();
            if (this.tokenValidity <= (currentTime + this.checkExpireThreshold)) {
                this.tokenPromise = this.requestAuthorizationToken();
            }
        },
        renderOnUpdated: function () {
            var that = this;
             that.jsonData.amount = window.addonpaymentsAmountUpdate * 100;

            if(null !== this.tokenPromise) {
                this.tokenPromise.then(function (data) {
                    that.token = data.token;
                    that.tokenValidity = data.tokenValidity;
                    that.render();
                    that.tokenPromise = null;

                }).catch(function (err) {
                    console.error(err);
                });
            }else {
                this.render();
            }
        },
        requestAuthorizationToken: function () {
            return new Promise(function (resolve, reject) {
                let ajaxExecutor = new XMLHttpRequest();

                ajaxExecutor.onreadystatechange = function () {

                    if (ajaxExecutor.readyState !== 4) return;

                    if (ajaxExecutor.status >= 200 && ajaxExecutor.status < 300) {
                        var data;

                        try {
                            data = JSON.parse(ajaxExecutor.response);
                        } catch (error) {
                            reject('Invalid authorization response');
                        }

                        if (data.hasOwnProperty('error')) {
                            reject(data.error.message);
                        }

                        resolve(data);
                    }

                    if (ajaxExecutor.status >= 400) {
                        reject('Authorization failed 1');
                    }
                };

                ajaxExecutor.addEventListener('timeout', function (e) {
                    reject('Authorization timed out');
                });

                ajaxExecutor.open('POST', addonpayments.authUrl);
                ajaxExecutor.setRequestHeader('Accept', 'application/json');
                ajaxExecutor.send();
            });
        },
        getJsonData: function() {
            /** @var {Object} addonpayments */
            let [decimalSeparator, thousandSeparator] = addonpayments.currency.specifications.symbol;

            return {
                "amount": addonpayments.amount * 100,
                "product": addonpayments.banner.product,
                "styleColor": addonpayments.banner.styleColor,
                "styleVariant": addonpayments.banner.styleVariant,
                "styleBranding": addonpayments.banner.styleBranding,
                "style": "width: 100%",
                "clientId": addonpayments.clientId,
                "currency": addonpayments.currency.iso_code,
                "locale": addonpayments.language.locale,
                "decimalSeparator": '.',
                "thousandSeparator": ','
            }
        }
    };

     document.addEventListener('DOMContentLoaded', function () {
        bnplBanner.init();
     });

})();
