(function ($, global) {
    var clientLoginGlobal = {
        _isActive: false,
        _profile: undefined,
        _business: undefined,
        _completePayment: undefined,
        _callbacks: [],
        _profileChangedCallbacks: [],
        whenActive: function whenActive(callback) {
            if (this._isActive) {
                callback(this._profile, this._business);
            } else {
                this._callbacks.push(callback);
            }
        },
        whenProfileChanged: function whenProfileChanged(callback) {
            this._profileChangedCallbacks.push(callback);
        },
        setActive: function setActive(profile, business) {
            this._profile = profile;
            this._business = business;
            this._isActive = true;

            this._callbacks.forEach(function (cb) {
                cb(profile, business);
            });

            this._callbacks = [];
        },
        postMessage: function postMessage(message) {
            if (!global.parent || global.parent.window === window) {
                return;
            }

            global.parent.postMessage(message, global.__clientLoginUrl);
        },
        setClientLoginTitle: function setClientLoginTitle() {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:online-bookings-title-change',
                title: getHeaderTitle(),
                hasBackButton: headerHasBackButton()
            });
        },
        choosePaymentMethod: function choosePaymentMethod(invoiceGuid, paymentMethodToken, completePayment) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:choose-payment-method',
                invoiceGuid: invoiceGuid,
                paymentMethodToken: paymentMethodToken
            });
            clientLoginGlobal._completePayment = completePayment;
        },
        savePaymentMethod: function savePaymentMethod(paymentMethodId, savePaymentMethodCallback) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:save-payment-method',
                paymentMethodId: paymentMethodId
            });
            clientLoginGlobal._savePaymentMethodCallback = savePaymentMethodCallback;
        },
        setSendSmsCallback: function setSendSmsCallback(sendSmsCallback) {
            clientLoginGlobal._sendSmsCallback = sendSmsCallback;
        },
        sendSms: function sendSms(smsNumber) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:send-sms',
                smsNumber: smsNumber
            });
        },
        submitCode: function submitCode(code, staySignedIn, smsNumber, submitCodeCallback) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:submit-code',
                code: code,
                staySignedIn: staySignedIn,
                smsNumber: smsNumber
            });
            clientLoginGlobal._submitCodeCallback = submitCodeCallback;
        },
        showJoinWaitlist: function showJoinWaitlist(obg, returnUrl) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:navigate-to-join-waitlist',
                obg: obg,
                returnUrl: returnUrl
            });
        }
    };
    global.__clientLoginMode = clientLoginGlobal;
    var messageHandlers = {
        'timely:client-login:set-client-login-mode-flag': function timelyClientLoginSetClientLoginModeFlag(event) {
            clientLoginGlobal.setActive(event.data.profile, event.data.business);
            event.source.postMessage({
                type: 'timely:client-login:online-bookings-load',
                title: getHeaderTitle(),
                hasBackButton: headerHasBackButton(),
                url: global.location.href
            }, event.origin);
        },
        'timely:client-login:trigger-back-button-click': function timelyClientLoginTriggerBackButtonClick(event) {
            var backButton$ = $('a.backward');
            var href = backButton$ && backButton$.attr('href');

            if (href) {
                global.location.href = href;
            }
        },
        'timely:client-login:confirm-payment-selection': function timelyClientLoginConfirmPaymentSelection(event) {
            clientLoginGlobal._completePayment();
        },
        'timely:client-login:submit-code-callback': function timelyClientLoginSubmitCodeCallback(event) {
            clientLoginGlobal._submitCodeCallback(event.data);
        },
        'timely:client-login:send-sms-callback': function timelyClientLoginSendSmsCallback(event) {
            clientLoginGlobal._sendSmsCallback(event.data);
        },
        'timely:client-login:save-payment-method-callback': function timelyClientLoginSavePaymentMethodCallback(event) {
            clientLoginGlobal._savePaymentMethodCallback(event.data);
        },
        'timely:client-login:profile-changed': function timelyClientLoginProfileChanged(event) {
            clientLoginGlobal.setActive(event.data.profile, event.data.business);

            if (clientLoginGlobal._profileChangedCallbacks.length > 0) {
                clientLoginGlobal._profileChangedCallbacks.forEach(function (cb) {
                    cb(event.data.profile, event.data.business);
                });
            }
        }
    };
    global.addEventListener('message', function (event) {
        if (!event || event.origin !== global.__clientLoginUrl) {
            return;
        }

        if (!event.data || !event.data.type || !messageHandlers[event.data.type]) {
            return;
        }

        var handler = messageHandlers[event.data.type];
        handler(event);
    });
    clientLoginGlobal.whenActive(function (profile) {
        if (!window.ga) {
            return;
        }

        window.ga('set', 'dimension1', 'true'); // Is Client Login

        window.ga('set', 'dimension3', '' + !!profile); // Is Client Login Authenticated
    });
    clientLoginGlobal.whenActive(function () {
        $(document).on('click', '.modal-close', function () {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:close-modal'
            });
        });
    });
    clientLoginGlobal.postMessage({
        type: 'timely:client-login:online-bookings-is-listening'
    });

    function getHeaderTitle() {
        // page title can be just an <h3>, or an <h3> with visible children elements, or an <h3> with a mix of visible and hidden children elements
        var pageTitle$ = $('.mobile-header > h3');
        var children$ = pageTitle$.children().filter(":not(.backward.submitter)");
        var title;

        if (children$.length === 0) {
            title = pageTitle$.text().trim();
        } else {
            title = children$.filter(function () {
                return $(this).css('display') !== 'none';
            }).text().trim();
        }

        pageTitle$.closest('.mobile-header').hide();
        return title;
    }

    function headerHasBackButton() {
        var backButton$ = $('a.backward');
        return !!backButton$.length;
    }
})($, window);

