(function ($, global) {
    var clientLoginGlobal = {
        _isActive: false,
        _profile: undefined,
        _business: undefined,
        _completePayment: undefined,
        _callbacks: [],
        _profileChangedCallbacks: [],
        whenActive: function (callback) {
            if (this._isActive) {
                callback(this._profile, this._business);
            } else {
                this._callbacks.push(callback);
            }
        },
        whenProfileChanged: function (callback) {
            this._profileChangedCallbacks.push(callback);
        },
        setActive: function (profile, business) {
            this._profile = profile;
            this._business = business;
            this._isActive = true;
            this._callbacks.forEach(function (cb) { cb(profile, business); });
            this._callbacks = [];
        },
        postMessage: function(message) {
            if (!global.parent || global.parent.window === window) {
                return;
            }
            global.parent.postMessage(message, global.__clientLoginUrl);
        },
        setClientLoginTitle: function () {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:online-bookings-title-change',
                title: getHeaderTitle(),
                hasBackButton: headerHasBackButton()
            });
        },
        choosePaymentMethod: function (invoiceGuid, paymentMethodToken, completePayment) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:choose-payment-method',
                invoiceGuid,
                paymentMethodToken
            });
            clientLoginGlobal._completePayment = completePayment;
        },
        savePaymentMethod: function (paymentMethodId, savePaymentMethodCallback) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:save-payment-method',
                paymentMethodId
            });
            clientLoginGlobal._savePaymentMethodCallback = savePaymentMethodCallback;
        },
        sendSms: function (smsNumber, sendSmsCallback) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:send-sms',
                smsNumber
            });
            clientLoginGlobal._sendSmsCallback = sendSmsCallback;
        },
        submitCode: function (code, staySignedIn, smsNumber, submitCodeCallback) {
            clientLoginGlobal.postMessage({
                type: 'timely:client-login:submit-code',
                code,
                staySignedIn,
                smsNumber
            });
            clientLoginGlobal._submitCodeCallback = submitCodeCallback;
        }
    };
    global.__clientLoginMode = clientLoginGlobal;

    var messageHandlers = {
        'timely:client-login:set-client-login-mode-flag': function (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 (event) {
            var backButton$ = $('a.backward');
            var href = backButton$ && backButton$.attr('href');
            if (href) {
                global.location.href = href;
            }
        },
        'timely:client-login:confirm-payment-selection': function (event) {
            clientLoginGlobal._completePayment();
        },
        'timely:client-login:submit-code-callback': function (event) {
            clientLoginGlobal._submitCodeCallback(event.data);
        },
        'timely:client-login:send-sms-callback': function (event) {
            clientLoginGlobal._sendSmsCallback(event.data);
        },
        'timely:client-login:save-payment-method-callback': function (event) {
            clientLoginGlobal._savePaymentMethodCallback(event.data);
        },
        'timely:client-login:profile-changed': function (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);

