---
# System prepended metadata

title: Untitled

---

```javascript=
document.onreadystatechange = function() {
    if (document.readyState === 'ready' || document.readyState === 'complete') {

        window.Foxy = new Foxy();
        window.Foxy.go();
    }
};

window.isiOS = () => {
    return [
            'iPad Simulator',
            'iPhone Simulator',
            'iPod Simulator',
            'iPad',
            'iPhone',
            'iPod'
        ].includes(navigator.platform)
        // iPad on iOS 13 detection
        || (navigator.userAgent.includes("Mac") && "ontouchend" in document)
};

window.isFacebookBrowser = () => {
    let ua = navigator.userAgent || navigator.vendor || window.opera;
    return (ua.indexOf("FBAN") > -1) || (ua.indexOf("FBAV") > -1) || (ua.indexOf("INSTAGRAM") > -1);
};

class Foxy {
    constructor() {
        this.params = new URLSearchParams(window.location.search);

        this.css = {
            fab: {
                backgroundColor: '#ffffff;border: solid 1px rgba(151, 151, 151, 0.28);',
                backgroundImage: 'linear-gradient(to right, #ff585d, #ff4b84)',
                boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.24);'
            },
        };
        this.formStep = 1;
        this.selectedStoreId = 0;

        // determine hosts
        let foxy_live_host;
        let api_host;

        let urls = {
            production: {
                foxy_live_host: 'https://live.foxy.in',
                api_host: 'https://live.foxy.in',
            },
            local: {
                foxy_live_host: 'http://localhost:3000',
                api_host: 'http://localhost:3000',
            },
            liveDev1: {
                foxy_live_host: 'https://live.live-dev-1.foxy.in',
                api_host: 'https://live.live-dev-1.foxy.in',
            }
        };

        if (window.environment === 'liveDev1') {
            // enable cross domain post messages
            document.domain = 'live-dev-1.foxy.in';
        } else if (window.environment === 'production') {
            try {
                document.domain = 'foxy.in'
            } catch {

            }

        }

        this.foxy_live_host = urls[window.environment].foxy_live_host;
        this.api_host = urls[window.environment].api_host;

        this.brand_id = window.brand_id;

        // determine if this is a testing environment
        this.test = this.params.get('test');

        this.defaultFirebaseParams = {
            brand_id: this.brand_id,
            utm_source: this.params.get('utm_source'),
            utm_medium: this.params.get('utm_medium'),
            utm_campaign: this.params.get('utm_campaign'),
            invite_id: this.params.get('invite_id'),
            stream_session_id: localStorage.getItem('stream_session_id'),
            one_on_one_session_id: localStorage.getItem('stream_session_id'),
            screen_name: 'fab-plugin',
            is_guest_flow: false
        };
    }

    go() {
        // things to do before jq
        this.loadScripts();
        this.setUpFirebase();
    }

    checkBrowserCompatbility() {
        let supported = Twilio.Video.isSupported;

        if (window.isiOS()) {
            supported = false;
        }

        return supported;
    }
    
    setUpFormEvents() {
        let that = this;
        that.jq(document).on('focusin focusout keypress', 'input', function (e) {
            let target = that.jq(e.target);
            that.logEvent(`input_${e.type}`, {...that.defaultFirebaseParams, ...{
                name: target.attr('name'),
                id: target.attr('id')
            }})
        })
    }

    onJqLoaded() {
        this.appendFAB();
        this.setUpFormEvents();

        // lead page stuff
        if (window.leadPage) {
            let toggle = window.Foxy.toggleFab();

            if (toggle && !window.Foxy.selectedStoreId) {
                window.Foxy.getLocation();
            }
        }
    }

    loadScripts() {
        let that = this;

        //
        // load jquery
        //
        window.onload = function() {
            let script;

            // load jquery
            if (window.jQuery) {
                let jqVersion = $().jquery;
                if (parseInt(jqVersion.split('.')[0]) < 3) {
                    // jquery version is too low; load it.
                    // set the first version to no conflict
                    let $ = $.noConflict(true);

                    // load the new version
                    script = document.createElement('script');
                    script.onload = function() {
                        window.jq = $.noConflict(true);
                        that.jq = window.jq;
                        that.onJqLoaded();
                    };
                    script.src = 'https://code.jquery.com/jquery-3.5.1.min.js';
                    document.head.appendChild(script);
                } else {
                    that.jq = $;
                    that.onJqLoaded();
                }
            } else {
                script = document.createElement('script');
                script.onload = function() {
                    window.jq = $.noConflict(true);
                    that.jq = window.jq;
                    that.onJqLoaded();
                };
                script.src = 'https://code.jquery.com/jquery-3.5.1.min.js';
                document.head.appendChild(script);
            }
        };
    }

    appendFAB() {
        let that = this;

        // this.jq('body').append(this.jq(this.FABTemplate()).html());

        // find and save elements
        this.fab = this.jq('body').find('#foxy-fab');
        this.form = this.jq('body').find('#foxy-fab-form');
        this.formClose = this.jq('body').find('#foxy-fab-form-close');
        this.searchInput = this.jq('body').find('#foxy-fab-search');
        this.searchLabel = this.jq('body').find('#dev-search-label');
        this.searchResult = this.jq('body').find('#dev-search-result');
        this.searchResultContainer = this.jq('body').find('#dev-search-results');
        this.searchResultTitle = this.jq('body').find('#dev-search-results-title');
        this.formFields = this.jq('body').find('#dev-form-fields');
        this.submitForm1 = this.jq('body').find('#dev-submit-form');
        this.nameInput = this.jq('body').find('#dev-name');
        this.emailInput = this.jq('body').find('#dev-email');
        this.mobileInput = this.jq('body').find('#dev-mobile');
        this.otpInput = this.jq('body').find('#dev-otp');
        this.changeStoreButton = this.jq('body').find('#dev-store-change');
        this.locationInput = this.jq('body').find('#dev-lat-long');
        this.ipInput = this.jq('body').find('#dev-ip');
        this.otpLoader = this.jq('body').find('#dev-otp-loader');
        this.resendButton = this.jq('#resend-otp');
        this.timer = this.jq('#timer');
        this.resendWhatsapp = this.jq('#resend-via-whatsapp');
        this.whatsappIcon = this.jq('.whatsapp-icon');
        this.whatsappDisabledIcon = this.jq('.whatsapp-disabled-icon');
        this.resendWhatsappText = this.jq('.resend-via-whatsapp-text');
        this.changeNumberText = this.jq('#dev-otp-number');
        this.geoLocateButton = this.jq('#dev-geo-locate');
        this.geoLocatingShimmer = this.jq('#dev-geolocating-shimmer');
        this.geoLocationInput = this.jq('#dev-geolocation-input');
        this.detectPrompt = this.jq('#dev-detect-prompt');
        this.noArtists = this.jq('#dev-no-artists');
        this.introText = this.jq('#dev-intro-text');

        this.fab.removeClass('hidden');
        this.fab.fadeIn('slow');

        // pre fill values if present
        let saved_name = localStorage.getItem('foxy_name');
        let saved_phone = localStorage.getItem('foxy_phone_number');
        let saved_email = localStorage.getItem('foxy_email');
        if (saved_name) {
            this.nameInput.val(saved_name);
        }
        if (saved_phone) {
            this.mobileInput.val(saved_phone);
        }
        if (saved_email) {
            this.emailInput.val(saved_email);
        }

        // set event listeners for the button
        this.fab.on('click', function() {
            let toggle = that.toggleFab();
            // if (localStorage.getItem('selected-store')) {
            //     that.selectStore(parseInt(localStorage.getItem('selected-store')))
            // } else {
            //     if (!that.selectedStoreId) {
            //         that.getLocation();
            //     }
            // }

            if (toggle && !that.selectedStoreId) {
                that.getLocation();
            }

        });

        // check if fab has to be opened automatically
        if (that.params.get('auto-open') === 'true'){
          that.fab.trigger('click');
        }

        this.formClose.on('click', function() {
            that.toggleFab();
        });

        // set event listeners for change store button
        this.changeStoreButton.on('click', function() {
            that.changeStore();
        });

        // set event listeners for form 1 submission
        this.submitForm1.on('click', function() {
            let params = that.params;

            if (that.formStep === 1) {
                // validate form
                let valid = !that.validateForm1();

                if (valid) {
                    that.submitForm1.text('Submitting...');

                    // check if at least one artist is available
                    that.ensureAtleastOneArtist()
                        .then(() => {
                            // if phone number was previously verified, go ahead and directly start call
                            let savedToken = localStorage.getItem('foxy_token');
                            let saved_phone = localStorage.getItem('foxy_phone_number');
                            let saved_name = localStorage.getItem('foxy_name');
                            if (
                                savedToken &&
                                saved_phone === that.mobileInput.val() &&
                                saved_name === that.nameInput.val()
                            ) {
                                that.logEvent('verification_skip', that.defaultFirebaseParams);
                                that.logEvent('call_redirect', that.defaultFirebaseParams);

                                window.top.location.href = `${
                                    that.foxy_live_host
                                }/foxy-live/call?auth_token=${savedToken}&coords=${that.locationInput.val()}&store=${
                                    that.selectedStoreId
                                }&test=${that.test ? '1' : ''}&brand=${that.brand_id}&environment=${window.environment}&utm_source=${params.get('utm_source')}&utm_campaign=${params.get('utm_campaign')}&utm_medium=${params.get('utm_medium')}&invite_id=${params.get('invite_id')}&referrer=${localStorage.getItem('referrer')}`;
                                return;
                            }

                            that.jq.ajax({
                                url: `${that.api_host}/api/v1/users/send_otp`,
                                method: 'POST',
                                data: {
                                    user: {
                                        phone_number: `${that.mobileInput.val()}`,
                                        country_code: '91',
                                    },
                                    profile: {
                                        name: that.nameInput.val(),
                                        email: that.emailInput.val()
                                    },
                                    via: 'sms',
                                },
                                success: function() {
                                    that.submitForm1.text('Continue');
                                    that.goToOTPVerification();
                                    that.formStep = 2;

                                    localStorage.setItem('foxy_name', that.nameInput.val());
                                    localStorage.setItem('foxy_phone_number', that.mobileInput.val());
                                    localStorage.setItem('foxy_email', that.emailInput.val());
                                    localStorage.removeItem('foxy_token');

                                    that.otpInput.parent().removeClass('hidden');
                                    that.otpInput.show();
                                    that.otpLoader.hide();
                                    that.changeNumberText.text(that.mobileInput.val());
                                    that.logEvent('otp_send', that.defaultFirebaseParams);
                                },
                                error: function(error) {
                                    that.submitForm1.text('Continue');
                                    console.error(error);
                                    alert('An error occurred. Please contact customer support.');
                                    that.logEvent('otp_sending_failure', that.defaultFirebaseParams);
                                },
                            });
                        });
                }
                // verify OTP
            } else if (that.formStep === 2) {
                that.submitForm1.text('Verifying...');

                that.jq.ajax({
                    url: `${that.api_host}/api/v1/users/verify_otp`,
                    method: 'POST',
                    data: {
                        user: {
                            phone_number: `${that.mobileInput.val()}`,
                            country_code: '91',
                            otp: that.getOTP(),
                        },
                        profile: {
                            name: that.nameInput.val(),
                        },
                    },
                    success: function(response) {
                        that.submitForm1.text('Continue');
                        let token = response.user.token;
                        localStorage.setItem('foxy_token', token);
                        that.logEvent('otp_verification_success', that.defaultFirebaseParams);
                        that.logEvent('call_redirect', that.defaultFirebaseParams);

                        window.top.location.href = `${
                            that.foxy_live_host
                        }/foxy-live/call?auth_token=${token}&coords=${that.locationInput.val()}&store=${
                            that.selectedStoreId
                        }&test=${that.test ? '1' : ''}&brand=${that.brand_id}&environment=${window.environment}&utm_source=${params.get('utm_source')}&utm_campaign=${params.get('utm_campaign')}&utm_medium=${params.get('utm_medium')}&invite_id=${params.get('invite_id')}&referrer=${localStorage.getItem('referrer')}`;
                    },
                    error: function(error) {
                        that.submitForm1.text('Continue');
                        that.otpInput.addClass('error');
                        that.otpInput.data('error-message', 'OTP is incorrect');
                        that.showErrors();

                        that.logEvent('otp_wrong', that.defaultFirebaseParams);
                    },
                });
            }
        });

        this.resendButton.on('click', function() {
            that.resendOtp('sms');
        });

        this.resendWhatsapp.on('click', function() {
            if (that.jq(this).hasClass('disabled')) {
                return;
            }
            that.resendOtp('whatsapp');
        });

        this.geoLocateButton.on('click', function() {
            that.detectPrompt.hide();
            that.getLocation();
            that.logEvent('geolocation_request', that.defaultFirebaseParams);
        });
    }

    toggleFab() {
        let that = this;

        // check browser compat
        let isSupported = that.checkBrowserCompatbility();
        if (!isSupported) {
            that.jq('#dev-unsupported-browser').removeClass('hidden');
            if (window.isiOS()) {
                that.jq('#dev-unsupported-text').text('Please open this link with Google Chrome on Android, macOS or Windows.');
            } else {
                that.jq('#dev-unsupported-text').text('Please open this link with Google Chrome to start the video call');
            }
            that.fab.hide();
            that.form.hide();
            that.jq('body').css('overflow', 'hidden');
            window.parent.postMessage({
                event: 'toggleFAB',
                is_open: this.fab.hasClass('active')
            }, '*');

            if (window.isFacebookBrowser() && !window.isiOS()){
                that.jq('.facebook-prompt').removeClass('hidden');
            } else {
                that.jq('#dev-copy-text-section').removeClass('hidden');
            }

            that.jq('#dev-copy-link').val(window.top.location.href);
            that.jq('#dev-copy').on('click', function () {
                let copyText = document.getElementById("dev-copy-link");

                copyText.select();
                copyText.setSelectionRange(0, 99999); /*For mobile devices*/

                document.execCommand("copy");

                that.jq('#dev-link-copied').removeClass('invisible');
                window.setTimeout(() => {
                    that.jq('#dev-link-copied').addClass('invisible');
                }, 3000)
            });

            window.fyrebase.logEvent('browser_unsupported', {
                user_agent: navigator.userAgent,
                ...that.defaultFirebaseParams
            });

            return false;
        } else {
            that.form.show();
        }

        // tell the parent we're toggling FAB
        if (!window.leadPage) {
            window.parent.postMessage({
                event: 'toggleFAB',
                is_open: this.fab.hasClass('active')
            }, '*');

            // remove the hidden class
            this.form.removeClass('hidden');

            if (this.fab.hasClass('active')) {
                this.fab.show();
                this.form.hide();
                this.fab.removeClass('active');

                // tell firebase we closed fab
                this.logEvent('plugin_close', that.defaultFirebaseParams);

            } else {
                this.fab.hide();
                this.form.show();
                this.form.css('display', 'flex');
                this.fab.addClass('active');

                this.logEvent('plugin_open', that.defaultFirebaseParams);
            }

            that.nameInput.focus();
        }

        // enable google map search
        that.initGoogleSearchBox();

        return true;
    }

    initGoogleSearchBox() {
        let that = this;

        window.autoComplete = new google.maps.places.SearchBox(document.getElementById('foxy-fab-search'), {
            // todo: componentRestrictions are not supported by searchBoxes
            // need to add lat long bounds instead
            componentRestrictions: {
                country: 'IN'
            }
        });

        google.maps.event.addListener(window.autoComplete, 'places_changed', function() {
            const place = window.autoComplete.getPlaces()[0];
            that.locationInput.val(`${place.geometry.location.lat()}x${place.geometry.location.lng()}`);
            if (!that.selectedStoreId) {
                that.search('', 'google');
            }
        })
    }

    search(q = '', initiator) {

        let that = this;
        if (initiator !== 'auto') {
            that.formFields.addClass('hidden').hide();
        }

        let coords;
        let ip;
        if (initiator === 'google' || initiator === 'auto') {
            coords = that.locationInput.val();
            ip = that.ipInput.val();
        } else {
            coords = undefined;
            ip = undefined;
        }

        this.jq.ajax({
            url: `${that.api_host}/api/v1/beauty_stores/search/`,
            method: 'GET',
            data: {
                q: q,
                coords: coords,
                brand_id: that.brand_id,
                ip: ip,
            },
            success: function(results) {
                that.logEvent('store_search_success', that.defaultFirebaseParams);

                // remove all results
                that.searchResultContainer.empty();

                // hide the prompt
                that.detectPrompt.hide();

                // save the search results
                that.storeSearchResults = results;

                // add search results to UI
                if (!initiator || initiator === 'google') {
                    that.jq.each(results.objects.slice(0, 4), function(_index, item) {
                        let template = that.searchResult;
                        let templateHTML = template.html();

                        templateHTML = templateHTML.replace(/{{name}}/g, item.name);
                        templateHTML = templateHTML.replace(/{{address}}/g, item.address);
                        templateHTML = templateHTML.replace(/{{store-id}}/g, item.id);
                        that.searchResultContainer.append(templateHTML);

                        that.jq('.dev-rendered-search-result').on('click', function() {
                            that.selectStore(that.jq(this).data('store-id'));
                        });
                    });
                } else {
                    that.geoLocationInput.show();
                    that.geoLocatingShimmer.hide();
                    let selectedStore = results.objects[0];
                    if (selectedStore) {
                        that.selectStore(selectedStore.id);
                    }
                }
            },
            error: function(results) {
                that.logEvent('store_search_failure', that.defaultFirebaseParams);
            },
            complete: function() {
                that.logEvent('store_search_initiate', that.defaultFirebaseParams);
            }
        });
    }

    selectStore(storeId) {
        let that = this;

        // hide detect prompt text
        this.detectPrompt.hide();

        // show form fields again
        this.formFields.removeClass('hidden').show();
        this.jq.each(this.formFields.find('.foxy-input').not('#dev-otp'), function (_index, item) {
            that.jq(item).parent().show();
        });

        // remove all results
        this.searchResultContainer.empty();

        // hide the search field
        this.searchInput.hide();
        this.searchLabel.hide();

        // hide search results
        this.searchResultContainer.hide();
        this.searchResultTitle.hide();

        // show intro text
        // this.introText.show();

        // find the selected store
        let store = this.jq.grep(this.storeSearchResults.objects, function(item) {
            return item.id === storeId;
        })[0];

        // show the selected store
        let selectedStoreEl = this.jq('#dev-selected-store');
        selectedStoreEl.removeClass('hidden');
        selectedStoreEl.show();
        selectedStoreEl.find('.text').text(`Connecting you to: ${store.name} - ${store.area_name}`);

        this.selectedStoreId = store.id;
        localStorage.setItem('selected-store', store.id);

        that.logEvent('store_select', that.defaultFirebaseParams);
    }

    changeStore() {
        let that = this;

        // remove saved store
        this.selectedStoreId = null;

        // show form fields again
        this.formFields.hide();
        // this.formFields.removeClass('hidden').show();
        this.jq.each(this.jq('.foxy-input').not('#foxy-fab-search'), function(_index, item) {
            that.jq(item).parent().hide();
        });
        this.jq('#foxy-fab-search').parent().show();

        // show detect prompt
        this.detectPrompt.show();
        this.detectPrompt.css('display', 'flex');

        // remove all results
        this.searchResultContainer.empty();

        // show the search field
        this.searchInput.show();
        this.searchLabel.show();

        // hide intro text
        // this.introText.hide();

        // show search results
        // hide search results
        this.searchResultContainer.show();
        this.searchResultTitle.show();

        // remove the selected store
        let selectedStoreEl = this.jq('#dev-selected-store');
        selectedStoreEl.find('.text').text('');
        selectedStoreEl.addClass('hidden');
        selectedStoreEl.hide();

        // empty the search input
        this.searchInput.val('');

        // hide the OTP input if it was visible
        this.otpInput.parent().addClass('hidden');
        this.otpInput.hide();

        // set form state to 1
        this.formStep = 1;

        // get closest stores
        that.search('', 'google');

        this.logEvent('store_change', this.defaultFirebaseParams);
    }

    validateForm1() {
        let that = this;
        let hasErrors = false;

        // check store validity
        if (!this.selectedStoreId) {
            that.searchInput.addClass('error');
            hasErrors = true;
            that.searchInput.data('error-message', 'This field is required');
            that.logEvent('store_input_error', this.defaultFirebaseParams);
        }

        // check name validity
        // todo: this is not dry
        if (!this.nameInput.val() || !this.nameInput.val().replace(/\s/g, '').length) {
            that.nameInput.addClass('error');
            hasErrors = true;
            that.nameInput.data('error-message', 'This field is required');
            that.logEvent('name_input_error', this.defaultFirebaseParams);
        } else {
            // remove error classes and messages
            that.nameInput.removeClass('error');
        }

        // check email validity
        if (this.emailInput.val()) {
            let mailformat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
            if (!this.emailInput.val().match(mailformat)) {
                that.emailInput.addClass('error');
                hasErrors = true;
                that.emailInput.data('error-message', 'Please enter a valid email');
                that.logEvent('email_input_error', this.defaultFirebaseParams);
            } else {
                that.emailInput.removeClass('error');
            }
        }

        // check phone validity
        if (!this.mobileInput.val()) {
            that.mobileInput.addClass('error');
            that.mobileInput.data('error-message', 'This field is required');
            hasErrors = true;
            that.logEvent('phone_number_input_error', this.defaultFirebaseParams);
        } else if (that.mobileInput.val().length !== 10) {
            that.mobileInput.addClass('error');
            that.mobileInput.data(
                'error-message',
                'Please enter a Indian 10 digit mobile number.',
            );
            hasErrors = true;
        } else if (
            !/^[+-]?\d+(\.\d+)?([eE][+-]?\d+)?$/.test(that.mobileInput.val())
        ) {
            that.mobileInput.addClass('error');
            that.mobileInput.data('error-message', 'Please only enter digits.');
            hasErrors = true;
        } else if (
            that.jq.inArray(that.mobileInput.val().slice(0, 1), [
                '0',
                '1',
                '2',
                '3',
                '4',
                '5',
            ]) > -1 &&
            that.jq.inArray(that.mobileInput.val().slice(0, 6), [
                '369900'
            ]) < 0
        ) {
            that.mobileInput.addClass('error');
            that.mobileInput.data(
                'error-message',
                'Phone number should start with 6,7,8,9.',
            );
            hasErrors = true;
            that.logEvent('phone_number_input_error', this.defaultFirebaseParams);
        } else {
            // remove error classes and messages
            that.mobileInput.removeClass('error');
        }

        that.jq.each(that.jq('body').find('.foxy-input'), function(_index, item) {
            let label = that.jq(item).siblings('.label');
            label.removeClass('error');
        });

        that.showErrors();

        return hasErrors;
    }

    showErrors() {
        let that = this;

        // add error class to correct labels
        that.jq.each(that.jq('body').find('.error'), function(_index, item) {
            let label = that.jq(item).siblings('.label');
            label.addClass('error');
        });

        // add error text
        that.jq.each(that.jq('body').find('.foxy-input'), function(_index, item) {
            let errorText = that.jq(item).siblings('.error-text');
            errorText.text(that.jq(item).data('error-message'));
        });
    }

    goToOTPVerification() {
        let that = this;
        that.logEvent('screen_view', {...that.defaultFirebaseParams, ...{
            screen: 'otp_verification'
        }});

        this.jq.each(this.jq('.foxy-input').not('#dev-otp'), function(_index, item) {
            that.jq(item).parent().hide();
        });
        this.jq('#dev-otp').show();
        this.jq('#dev-otp').parent().show();

        that.otpLoader.parent().removeClass('hidden');
        that.otpLoader.removeClass('hidden').show();
        that.otpInput.hide();
        that.startOTPTimer();

        // set OTP validation
        this.jq.each(this.otpInput.find('input'), function(_index, item) {
            that.jq(item).on('keyup', function(e) {
                that.logEvent('otp_input_keypress', that.defaultFirebaseParams);

                // if backspace is pressed, clear input
                if (e.keyCode === 8) {
                    that.jq(item).val();
                    // and go to prev input
                    if (!that.jq(item).hasClass('1')) {
                        let prevInput = that.jq(item).prev();
                        prevInput.focus();
                    }
                }
                // enter a maximum of 1 digit
                if (that.jq(item).val().length > 1) {
                    that.jq(item).val(that.jq(item).val().substr(-1));
                }
                // if the length is 1, proceed to next box
                if (that.jq(item).val().length === 1) {
                    if (!that.jq(item).hasClass('4')) {
                        let nextInput = that.jq(item).next();
                        nextInput.focus();
                    }
                }
                // if all inputs have been filled, submit form
                if (that.jq(item).hasClass('4')) {
                    let values = that.jq.map(that.otpInput.find('input'), function(
                        item,
                    ) {
                        if (that.jq(item).val()) {
                            return that.jq(item).val();
                        }
                    });

                    if (values.length === 4) {
                        // trigger form submit if 4 digits are present
                        that.submitForm1.click();
                        that.logEvent('otp_submit', that.defaultFirebaseParams);
                    }
                }
            });
        });

        that.jq('body').on('click', '#dev-number-change', function() {
            that.logEvent('phone_number_change', that.defaultFirebaseParams);

            // show form fields again
            that.formFields.removeClass('hidden').show();
            that.jq.each(that.jq('.foxy-input').not('#dev-otp'), function(_index, item) {
                that.jq(item).parent().show();
            });

            // hide the OTP input
            that.otpInput.parent().hide();

            // set form state to 1
            that.formStep = 1;
        });
    }

    getOTP() {
        let that = this;

        let otp = '';
        this.jq.each(this.otpInput.find('input'), function(_index, item) {
            otp += that.jq(item).val();
        });

        return otp;
    }

    getLocation() {
        let that = this;

        if (!navigator.geolocation) {
            alert(
                'Your browser does not support geo location. Foxy Live will not work as expected.',
            );
            that.logEvent('geolocation_error', that.defaultFirebaseParams);
        } else {
            that.geoLocationInput.hide();
            that.geoLocatingShimmer.show();

            that.logEvent('permission_trigger', {...that.defaultFirebaseParams, ...{
                permission_name: 'geolocation',
                    screen_name: 'plugin'
            }});
            navigator.geolocation.getCurrentPosition(
                function(location) {
                    that.logEvent('permission_allow', {
                        ...that.defaultFirebaseParams, ...{
                        permission_name: 'geolocation',
                            screen_name: 'plugin'
                    }
                    });

                    const lat = location.coords.latitude;
                    const long = location.coords.longitude;

                    that.jq('body').find('#dev-lat-long').val(`${lat}x${long}`);

                    // find closest store
                    // show searching shimmer
                    that.search('', 'auto');
                },
                function() {
                    that.logEvent('permission_deny', {
                        ...that.defaultFirebaseParams, ...{
                        permission_name: 'geolocation',
                            screen_name: 'plugin'
                    }
                    });

                    // if location was rejected, use IP address as fallback
                    that.logEvent('ip_address_fetch', that.defaultFirebaseParams);
                    that.jq.getJSON('https://api.foxy.in/api/v1/my_ip', function(
                        data,
                    ) {
                        that.jq('body').find('#dev-ip').val(`${data.ip}`);
                        that.search('', 'auto');
                    });
                },
            );
        }
    }

    hideOTPTimer() {
        let that = this;
        that.logEvent('otp_timer_hide', that.defaultFirebaseParams);

        this.timer.addClass('hidden');
        this.resendButton.removeClass('hidden');
        this.whatsappIcon.removeClass('hidden');
        this.whatsappDisabledIcon.addClass('hidden');
        this.resendWhatsappText[0].style.color = '#009688';
        this.resendWhatsapp.removeClass('disabled');
    }

    showOTPTimer() {
        let that = this;
        that.logEvent('otp_timer_show', that.defaultFirebaseParams);

        this.timer.removeClass('hidden');
        this.resendButton.addClass('hidden');
        this.whatsappIcon.addClass('hidden');
        this.whatsappDisabledIcon.removeClass('hidden');
        this.resendWhatsappText[0].style.color = '#979BAA';
        this.resendWhatsapp.addClass('disabled');
    }

    getTime(sec) {
        sec = sec - 1;
        return (sec < 10 ? '0' : '') + sec;
    }

    startOTPTimer() {
        let that = this;
        let seconds = 16;
        let timer = this.jq('#timer');

        this.showOTPTimer();

        let timerId = setTimeout(function otpTimer() {
            timer.text(`00:${that.getTime(seconds)}`);
            seconds = seconds - 1;
            timerId = setTimeout(otpTimer, 1000);

            if (seconds === 0) {
                that.hideOTPTimer();
                clearTimeout(timerId);
            }
        }, 1000);
    }

    resendOtp(via) {
        let that = this;

        that.logEvent('otp_rerequest', {...that.defaultFirebaseParams, ...{
            medium: via
        }});
        that.jq.ajax({
            url: `${that.api_host}/api/v1/users/send_otp`,
            method: 'POST',
            data: {
                user: {
                    phone_number: `${that.mobileInput.val()}`,
                    country_code: '91',
                },
                profile: {
                    name: that.nameInput.val(),
                },
                via: via,
            },
            success: function() {
                that.startOTPTimer();
            },
            error: function(error) {
                that.continueButton.text('Continue');
                console.error(error);
                alert('An error occurred. Please contact customer support.');
                that.logEvent('otp_sending_failure', that.defaultFirebaseParams);
            },
        });
    }

    setUpFirebase() {
        let that = this;

        // get settings
        fetch(`${that.api_host}/api/v1/one_on_one_sessions/settings`, {
            method: 'GET',
            headers: {
                'x-auth-token': localStorage.getItem('auth_token')
            }
        })
            .then((response) => response.json())
            .then((response) => {
                let firebase_settings = response.firebase_events;
                that.firebase = firebase.initializeApp(firebase_settings);
                that.firebase_analytics = that.firebase.analytics();

                localStorage.setItem('places_api_key', response.places_api_key)

                that.logEvent('firebase_init_success', that.defaultFirebaseParams);
            })
            .catch((error) => {
                console.error(error);
            })
    }

    ensureAtleastOneArtist() {
        let that = this;

        return new Promise((resolve, reject) => {
            fetch(`/api/v1/one_on_one_sessions/available_artists/?store_id=${that.selectedStoreId}`, {
                method: 'GET'
            })
                .then((response) => response.json())
                .then((response) => {
                    if (response.available_artists < 1) {
                        let selectedStoreEl = this.jq('#dev-selected-store');
                        that.formFields.hide();
                        that.noArtists.show();
                        that.submitForm1.hide();
                        selectedStoreEl.hide();
                    }

                    resolve(this);
                })
                .catch((error) => {
                    console.error(error);
                    // let the user go ahead even if this call fails
                    resolve(this);
                })
        });
    }

    logEvent(eventName, eventParams) {
        if (this.firebase_analytics) {
            this.firebase_analytics.logEvent(eventName, eventParams);
        } else {
            console.error('Skipping event, firebase not available.')
        }

    }
}

```