window.boxtalMapsShopifyEnv = {shopId:0,accessToken:'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJXRmJYWEV3VFRCX2VfRWFsXzEtdk4zOGc4Qm1ONjZyaUM5dnEtb0pLdWtBIn0.eyJleHAiOjE3Nzk2ODYyODUsImlhdCI6MTc3OTY4MjY4NSwianRpIjoiZDc2OGY1NDEtM2UyNy00MDkzLWI2MGYtZjEzZmVkYzRkOGE2IiwiaXNzIjoiaHR0cHM6Ly9pYW0uYm94dGFsLmNvbS9yZWFsbXMvYWNjb3VudC1hcHAiLCJzdWIiOiJmOmFjY291bnQtYXBwOmFwcC00ZTliMzIxOC1hNGY0LTQ2MGEtOGM5OC05ZWYwYTIyNjg3YjMiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhY2NvdW50LWFwcC1jbGllbnQiLCJzZXNzaW9uX3N0YXRlIjoiMDhhOGFiMjctOGJlMC00ZjdhLThlN2QtNDkxNjVmYWI1YzRhIiwiYWNyIjoiMSIsInNjb3BlIjoib3BlbmlkIGVtYWlsIiwic2lkIjoiMDhhOGFiMjctOGJlMC00ZjdhLThlN2QtNDkxNjVmYWI1YzRhIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJpYW0iOnsiYWNjb3VudElkIjoiMSIsImxlZ2FjeVVzZXJJZCI6IjExOTYzNjQiLCJsZWdhY3lVc2VyTG9naW4iOiJJQU0tQUNDT1VOVC0xIiwicmVhbG1OYW1lIjoiYWNjb3VudC1hcHAiLCJsb2NhbGUiOiJmciIsInVzZXJJZCI6ImFwcC00ZTliMzIxOC1hNGY0LTQ2MGEtOGM5OC05ZWYwYTIyNjg3YjMiLCJ1c2VybmFtZSI6ImFwcC00ZTliMzIxOC1hNGY0LTQ2MGEtOGM5OC05ZWYwYTIyNjg3YjMifX0.eSLZMSwuQnJwzEC5FRnao3Rn9gucdCKVlTP1Idk0z-COTgRGNSXmaBkR1p1JFfnkzXSfQEYlDaIjI5z79oJPPiCgSYUGgxSau566EAIUbbOCn7VcfnHo8N1gFq_3sWVFBCUZHzwDuXrpUYQ0WFaaXbt_pZU_Q3S9hNm3FYWGlEyPWhsG5i2NOaW9euVP2505j-lRH_ffAS0WgNWH5HTK7Y2jimw_1f5JncqceipbGd5wQrO3NDLbkk9ky2IguKYdv--DUZBkeA_yu6oqSPjEI987OucONq_-J_OaTSHbqUUkaQyLv3SGDmA9-quHjPffc6EDyRT5V7K0mt2z-hUsJA'}
function BoxtalMapsShopify() {
    this.init();
}

BoxtalMapsShopify.prototype = {
    defaultLanguage: "en",
    i18n: {
        fr: {
            parcelPoint: "Point relais",
            recipientAddress: "Adresse destinataire",
            bannerLabel1: "Où récupérer mon colis ?",
            bannerLabel2: "Au point relais choisi, cependant vous pouvez encore le modifier sur la carte ci-dessous.",
            bannerLabel3: "Nous avons choisi par défaut le point relais le plus proche de votre adresse, cependant vous pouvez le modifier sur la carte ci-dessous. Dès que votre choix est fait, vous pouvez quitter la page !",
            bannerLabel4: "Au point relais affiché sur la carte ci-dessous.",
            bannerLabel5: "Un problème ne permettant pas d'afficher le point relais sélectionné sur la carte ci-dessous est survenu, veuillez contacter votre vendeur pour plus de précisions."
        },
        en: {
            parcelPoint: "Parcel point",
            recipientAddress: "Recipient address",
            bannerLabel1: "Where to pick up my package ?",
            bannerLabel2: "At the chosen parcel point, however you can still change it on the map below.",
            bannerLabel3: "We automatically assigned to you the closest parcel point to your address, however you may change it on the map below. Once you're done, you may leave this page !",
            bannerLabel4: "At the parcel point shown on the map below.",
            bannerLabel5: "There has been a problem with not showing the selected parcel point on the map below, please contact your seller for more details."
        }
    },
    api: null,
    iframeId: "boxtal-maps-iframe",
    nativeMapElt: null,
    boxtalMapsIframe: null,
    parcelPointAddressElt: null,
    recipientAddress: null,
    shopId: null,
    accessToken: null,
    merchantUrl: null,
    checkoutToken: null,
    shopOrderInternalReference: null,
    shippingMethod: null,
    parcelPoint: null,
    parcelPointStillSelectable: false,
    parcelPointNetworks: null,
    translations: null,
    bannerLine2HtmlElt: null,
    bannerLine2LabelKey: null,
    init: function () {
        console.log("[BOXTAL-MAPS] Initialize BoxtalMapsShopify component, Shopify = " + JSON.stringify(Shopify));
        if (Shopify.checkout && Shopify.checkout.order_id) {
            let checkout = Shopify.checkout;
            console.log("[BOXTAL-MAPS] Hide native map element");
            this.hideNativeMapElt();
            console.log("[BOXTAL-MAPS] Initialize BoxtalMapsApi component");
            this.api = new BoxtalMapsApi();
            console.log("[BOXTAL-MAPS] Initialize BoxtalMapsIframe component");
            this.boxtalMapsIframe = new BoxtalMapsIframe(this.iframeId);
            this.shopId = window.boxtalMapsShopifyEnv.shopId;
            this.accessToken = window.boxtalMapsShopifyEnv.accessToken;
            this.merchantUrl = Shopify.shop;
            this.checkoutToken = Shopify.Checkout.token;
            this.initTranslations(checkout.customer_locale);
            this.shopOrderInternalReference = checkout.order_id;
            this.shippingMethod = checkout.shipping_rate.title;
            let shippingAddress = checkout.shipping_address;
            this.recipientAddress = {
                street: shippingAddress.address1,
                zipCode: shippingAddress.zip,
                city: shippingAddress.city,
                country: shippingAddress.country_code
            };
            let self = this;
            console.log("[BOXTAL-MAPS] Get Parcel Point ShopOrder status");
            this.api.getParcelPointShopOrderStatus({
                accessToken: this.accessToken,
                shopId: this.shopId,
                merchantUrl: this.merchantUrl,
                shippingMethod: this.shippingMethod,
                checkoutToken: this.checkoutToken,
                shopOrderInternalReference: this.shopOrderInternalReference,
                recipientAddress: this.recipientAddress
            }, function (data) {
                self.handleParcelPointShopOrderStatus(data);
            });
        }
    },
    initTranslations: function (language) {
        let i18n = this.i18n;
        if (language && language.length >= 2) {
            let shortLanguage = language.substr(0, 2).toLowerCase();
            if (i18n[shortLanguage]) {
                this.translations = i18n[shortLanguage];
            } else {
                this.translations = i18n[this.defaultLanguage];
            }
        } else {
            this.translations = i18n[this.defaultLanguage];
        }
    },
    handleParcelPointShopOrderStatus: function (data) {
        this.parcelPoint = data.parcelPoint;
        this.parcelPointStillSelectable = data.parcelPointStillSelectable;
        this.parcelPointNetworks = data.parcelPointNetworks;
        if (data.shippingMethodElligible) {
            this.removeNativeMapElt();
            this.buildHtmlElements();
            this.displayParcelPoint(data.parcelPoint);
            this.displayBanner(data.parcelPoint);
            if (data.parcelPoint && !data.parcelPointStillSelectable) {
                this.boxtalMapsIframe.selectParcelPoint({
                    accessToken: this.accessToken,
                    address: this.recipientAddress,
                    parcelPointCode: this.parcelPoint ? data.parcelPoint.code : null,
                    parcelPointNetwork: this.parcelPoint ? data.parcelPoint.network : null,
                    parcelPointNetworks: this.parcelPointNetworks
                });
            } else {
                let self = this;
                this.boxtalMapsIframe.searchParcelPoints({
                    selectable: data.parcelPointStillSelectable,
                    selectDefault: data.parcelPointStillSelectable,
                    accessToken: this.accessToken,
                    address: this.recipientAddress,
                    parcelPointCode: this.parcelPoint ? this.parcelPoint.code : null,
                    parcelPointNetwork: this.parcelPoint ? this.parcelPoint.network : null,
                    parcelPointNetworks: this.parcelPointNetworks
                }, function (parcelPoint) {
                    self.handleSubmitParcelPoint(parcelPoint);
                });
            }
        } else {
            this.showNativeMapElt();
        }
    },
    handleSubmitParcelPoint: function (parcelPoint) {
        this.displayBanner(this.parcelPoint);
        this.parcelPoint = parcelPoint;
        this.displayParcelPoint(parcelPoint);
            this.api.bookParcelPointShopOrder({
                accessToken: this.accessToken,
                shopId: this.shopId,
                merchantUrl: this.merchantUrl,
                shippingMethod: this.shippingMethod,
                shopOrderInternalReference: this.shopOrderInternalReference,
                recipientAddress: this.recipientAddress,
                parcelPointCountryCode: parcelPoint.location.country,
                parcelPointNetwork: parcelPoint.network,
                parcelPointCode: parcelPoint.code
            });
    },
    displayParcelPoint: function (parcelPoint) {
        if (parcelPoint) {
            let location = parcelPoint.location;
            this.parcelPointAddressElt.innerHTML = parcelPoint.name + "<br>" + location.street + "<br>" + location.zipCode + " " + location.city;
        }
    },
    displayBanner: function (parcelPoint) {
        if (this.parcelPointStillSelectable) {
            this.bannerLine2HtmlElt.innerText = this.translate(parcelPoint ? "bannerLabel2" : "bannerLabel3");
        } else {
            this.bannerLine2HtmlElt.innerText = this.translate(parcelPoint ? "bannerLabel4" : "bannerLabel5");
        }
    },
    hideNativeMapElt: function () {
        this.nativeMapElt = document.querySelectorAll(".map")[0];
        if (this.nativeMapElt && document.body.contains(this.nativeMapElt)) {
            this.nativeMapElt.parentNode.style.display = "none";
        }
    },
    removeNativeMapElt: function () {
        if (this.nativeMapElt && document.body.contains(this.nativeMapElt)) {
            this.nativeMapElt.parentNode.parentNode.removeChild(this.nativeMapElt.parentNode);
        }
    },
    showNativeMapElt: function () {
        if (this.nativeMapElt && document.body.contains(this.nativeMapElt)) {
            this.nativeMapElt.parentNode.style.display = "";
        }
    },
    buildHtmlElements: function () {
        let addressElts = document.getElementsByTagName("address");
        let shippingAddressParentElt = addressElts[0].parentNode;
        let billingAddressParentElt = addressElts[1].parentNode;
        let shippingAddressTitleElt = shippingAddressParentElt.querySelectorAll(".heading-3")[1];
        shippingAddressTitleElt.innerText = this.translate("recipientAddress");
        let parcelPointAddressTitleElt = this.buildParcelPointAddressTitleHtmlElement();
        billingAddressParentElt.appendChild(parcelPointAddressTitleElt);
        this.parcelPointAddressElt = this.buildParcelPointAddressHtmlElement();
        billingAddressParentElt.append(this.parcelPointAddressElt);
        let customerInfoElt = shippingAddressParentElt.parentNode.parentNode.parentNode;
        customerInfoElt.append(this.buildIframeHtmlElement());
        this.bannerLine2HtmlElt = this.buildBannerHtmlElement();
    },
    buildBannerHtmlElement: function () {
        let elt = document.createElement("div");
        elt.style.color = "#17375f";
        elt.style.fontSize = "1em";
        elt.style.paddingTop = "0.75em";
        elt.style.marginTop = "0.75em";
        elt.style.marginBottom = "0.75em";
        elt.style.paddingBottom = "0.75em";
        elt.style.paddingLeft = "0.75em";
        elt.style.paddingRight = "0.75em";
        elt.style.borderLeft = "5px solid #0095c5";
        elt.style.backgroundColor = "rgba(0, 149, 197, 0.15)";
        let line1 = document.createElement("div");
        line1.innerText = this.translate("bannerLabel1");
        line1.style.color = "#0095c5";
        line1.style.fontWeight = "bold";
        let line2 = document.createElement("div");
        elt.appendChild(line1);
        elt.appendChild(line2);
        let sectionContentElt = document.querySelector(".section__content");
        sectionContentElt.parentNode.insertBefore(elt, sectionContentElt);
        elt.parentNode.style.paddingTop = "0";
        return line2;
    },
    buildParcelPointAddressTitleHtmlElement: function () {
        let elt = document.createElement("h3");
        elt.className = "heading-3";
        elt.innerText = this.translate("parcelPoint");
        return elt;
    },
    buildParcelPointAddressHtmlElement: function () {
        let elt = document.createElement("address");
        elt.className = "address";
        return elt;
    },
    buildIframeHtmlElement: function () {
        let elt = document.createElement("div");
        elt.setAttribute("id", this.iframeId);
        elt.style.height = "400px";
        elt.style.padding = "5px 0";
        return elt;
    },
    translate: function (key) {
        if (this.translations[key]) {
            return this.translations[key];
        } else {
            return key;
        }
    }

};

function BoxtalMapsIframe(id, config) {
    this.init(id, config);
}

BoxtalMapsIframe.prototype = {
    id: null,
    iframeUrl: null,
    iframeElt: null,
    callback: null,
    config: null,
    init: function (id, config) {
        this.id = id;
        this.config = config;
        this.iframeUrl = window.boxtalMapsEnv.iframeBaseUrl + "/iframe.html";
    },
    createMap: function (data, callback) {
        this.callback = callback;
        data.method = "createMap";
        this.callIframe(data);
    },
    searchParcelPoints: function (data, callback) {
        this.callback = callback;
        data.method = "searchParcelPoints";
        this.callIframe(data);
    },
    selectParcelPoint: function (data, callback) {
        this.callback = callback;
        data.method = "selectParcelPoint";
        this.callIframe(data);
    },
    callIframe: function (data) {
        if (!this.iframeElt) {
            this.createIframe();
            let self = this;
            this.iframeElt.onload = function () {
                self.postMessage(data);
            };
        } else {
            this.postMessage(data);
        }
    },
    createIframe: function () {
        let iframeContainerElt = document.querySelector("#" + this.id);
        this.iframeElt = this.buildIframeHtmlElement();
        iframeContainerElt.appendChild(this.iframeElt);
        window.addEventListener("message", this.handleMessage.bind(this), false);
    },
    postMessage: function (data) {
        data.config = this.config;
        data.origin = document.location.origin;
        this.iframeElt.contentWindow.postMessage(
            data,
            this.iframeUrl
        );
    },
    handleMessage: function (event) {
        let data = event.data;
        if (data) {
            if (data.href) {
                window.open(data.href, "_blank");
            } else if (this.callback && data.selectedParcelPoint) {
                this.callback(data.selectedParcelPoint);
            }
        }
    },
    buildIframeHtmlElement: function () {
        let elt = document.createElement("iframe");
        elt.setAttribute("src", this.iframeUrl);
        elt.style.backgroundColor = "#ffffff";
        elt.style.height = "100%";
        elt.style.width = "100%";
        elt.style.border = "0";
        return elt;
    }
};

function BoxtalMapsApi() {
    this.init();
}

BoxtalMapsApi.prototype = {
    parcelPointSearchEndpoint: null,
    parcelPointShopOrderStatusEndpoint: null,
    parcelPointShopOrderBookEndpoint: null,
    accessTokenEndpoint: null,
    sandbox: false,
    init: function () {
        let env = window.boxtalMapsEnv;
        this.parcelPointSearchEndpoint = env.mapsBaseUrl + "/api/v2/parcel-point";
        this.parcelPointShopOrderStatusEndpoint = env.mapsBaseUrl + "/api/v2/maps-shopify/status";
        this.parcelPointShopOrderBookEndpoint = env.mapsBaseUrl + "/api/v2/maps-shopify/book";
        this.accessTokenEndpoint = env.mapsBaseUrl + "/api/v2/token";
        this.sandbox = env.sandbox || false;
    },
    searchParcelPoints: function (data, callback) {
        let address = data.address;
        let url = this.parcelPointSearchEndpoint;
        url += "?country=" + encodeURIComponent(address.country);
        url += "&zipCode=" + encodeURIComponent(address.zipCode);
        url += "&city=" + encodeURIComponent(address.city);
        if (address.street) {
            url += "&street=" + encodeURIComponent(address.street);
        }
        if (data.parcelPointNetworks) {
            for (let i = 0; i < data.parcelPointNetworks.length; i++) {
                let network = data.parcelPointNetworks[i];
                url += "&networks%5B%5D=" + encodeURIComponent(network);
            }
        }
        let httpConfig = this.buildCommonHttpConfig("GET", data);
        fetch(url, httpConfig)
            .then(this.checkHttpStatus)
            .then(this.parseJSON)
            .then(function (response) {
                callback(response);
            }).catch(function (error) {
            console.error(error);
        });
    },
    getParcelPointShopOrderStatus: function (data, callback) {
        let url = this.parcelPointShopOrderStatusEndpoint;
        url += "?shopId=" + encodeURIComponent(data.shopId);
        url += "&merchantUrl=" + encodeURIComponent(data.merchantUrl);
        url += "&shippingMethod=" + encodeURIComponent(data.shippingMethod);
        if (data.shopOrderInternalReference) {
            url += "&shopOrderInternalReference=" + encodeURIComponent(data.shopOrderInternalReference);
        }
        if (data.recipientAddress) {
            url += "&recipientCountryCode=" + encodeURIComponent(data.recipientAddress.country);
        }
        if (data.checkoutToken) {
            url += "&checkoutToken=" + encodeURIComponent(data.checkoutToken);
        }
        let httpConfig = this.buildCommonHttpConfig("GET", data);
        fetch(url, httpConfig)
            .then(this.checkHttpStatus)
            .then(this.parseJSON)
            .then(function (response) {
                callback(response);
            }).catch(function (error) {
            console.error(error);
        });
    },
    bookParcelPointShopOrder: function (data) {
        let url = this.parcelPointShopOrderBookEndpoint;
        let payload = JSON.stringify({
            shopId: data.shopId,
            merchantUrl: data.merchantUrl,
            shippingMethod: data.shippingMethod,
            shopOrderInternalReference: data.shopOrderInternalReference,
            recipientAddress: data.recipientAddress,
            parcelPointCountryCode: data.parcelPointCountryCode,
            parcelPointNetwork: data.parcelPointNetwork,
            parcelPointCode: data.parcelPointCode
        });
        let httpConfig = this.buildCommonHttpConfig("POST", data);
        httpConfig["body"] = payload;
        fetch(url, httpConfig)
            .then(this.checkHttpStatus)
            .catch(function (error) {
                console.error(error);
            });
    },
    getAccessToken: function (accessKey, secretKey, callback, error) {
        let url = this.accessTokenEndpoint;
        let httpConfig = {
            method: "POST",
            headers: new Headers()
        };
        httpConfig.headers.set("Content-Type", "application/json");
        httpConfig.headers.set("Authorization", "Basic " + btoa(accessKey + ":" + secretKey));
        fetch(url, httpConfig)
            .then(this.checkHttpStatus)
            .then(this.parseJSON)
            .then(function (response) {
                callback(response.accessToken);
            }).catch(function (err) {
            error(err);
        });
    },
    buildCommonHttpConfig: function (method, data) {
        let headers = new Headers();
        headers.append("Content-Type", "application/json");
        if (data.accessToken) {
            let accessToken = data.accessToken;
            headers.append("Authorization", "Bearer " + accessToken);
        }
        return {method, headers};
    },
    checkHttpStatus: function (response) {
        if (response.status >= 200 && response.status < 300) {
            return response;
        } else {
            let error = new Error(response.statusText);
            error.response = response;
            throw error;
        }
    },
    parseJSON: function (response) {
        return response.json();
    }
};

window.boxtalMapsEnv = {
    appVersion: "1.2.11",
    mapsBaseUrl: "https://maps.boxtal.com",
    iframeBaseUrl: "https://maps.boxtal.com/app/v2",
    logoBaseUrl: "https://www.boxtal.com"
};

if (!window.boxtalMapsShopify) {
    window.boxtalMapsShopify = new BoxtalMapsShopify();
}