/* eslint-disable import/no-cycle */
import {
    areAllSessionCookiesSet,
    getDeviceIdValue,
    getSessionIdValue,
    getSessionKeyValue,
    getUserIdValue,
    regenerateUserId,
    regenerateDeviceId,
    setSessionIdIfUnset,
    setSessionKeyIfUnset
} from '@/helpers/cookie-helper';
import applicationConfig from '@/constants/application-config';
import queryStrings from '@/constants/query-strings';
import { experimentSettings } from '@/constants/experiments';
import {
    analyticsPageEvents,
    GaCategories,
    GaActions,
    GaLabels,
    GaEvents,
    ValueToLogTypes
} from '@/constants/analytics';
import { useMainStore } from '@/store';

function pushToDataLayerIfDefined(data) {
    if (window.dataLayer !== undefined) {
        window.dataLayer.push(data);
    }
}

function getValueToLog(value, valueToLogType) {
    if (valueToLogType != null && valueToLogType === ValueToLogTypes.LAST_5) {
        return value.slice(-5);
    }
    return value;
}

export default {
    methods: {
        getPageNameByQueryString() {
            const params = new URLSearchParams(location.search);

            if (params.has(queryStrings.ISS_PAGE)) {
                return params.get(queryStrings.ISS_PAGE);
            }
            return '';
        },
        logPageView(pageEvent) {
            const currentPageName = this.getPageNameByQueryString();
            const payload = {
                userId: getDeviceIdValue(),
                sessionKey: getSessionKeyValue(),
                pageName: currentPageName,
                sessionId: getSessionIdValue(),
                action: '',
                event: pageEvent,
                shouldUseSessionId: false,
                experimentsForUser: useMainStore().applicationUser.experiments
            };

            useMainStore().logPageView(payload);
        },

        logCustomEvent(category, action, label, value) {
            const currentPageName = this.getPageNameByQueryString();

            const payload = {
                userId: getDeviceIdValue(),
                sessionKey: getSessionKeyValue(),
                pageName: currentPageName,
                sessionId: getSessionIdValue(),
                category,
                action,
                label,
                value,
                shouldUseSessionId: false,
                experimentsForUser: useMainStore().applicationUser.experiments
            };

            useMainStore().logCustomEvent(payload);
        },

        pushEventToGA(category, action, label, pushToLogApp = false, valueToLogType = null) {
            const currentPageName = this.getPageNameByQueryString();
            const labelToLog = getValueToLog(label, valueToLogType);

            const eventToBePushed = {
                event: GaEvents.GENERIC_EVENT,
                category,
                action,
                label: labelToLog,
                value: undefined,
                path: `/iss/?${queryStrings.ISS_PAGE}=${currentPageName}`
            };

            pushToDataLayerIfDefined(eventToBePushed);

            if (pushToLogApp) {
                this.logCustomEvent(category, action, labelToLog, undefined);
            }
        },

        pushPageViewToGA() {
            const currentPageName = this.getPageNameByQueryString();
            const pageViewEvent = {
                event: GaEvents.PAGE_VIEW_EVENT,
                pagePath: `/iss/?${queryStrings.ISS_PAGE}=${currentPageName}`,
                pageTitle: currentPageName
            };

            pushToDataLayerIfDefined(pageViewEvent);

            this.logPageView(analyticsPageEvents.ENTRY);
        },

        pushValueToGA() {
            pushToDataLayerIfDefined({
                siteType: useMainStore().issConfig.siteType
            });
        },

        pushExperimentsToDataLayer() {
            const { experiments } = useMainStore().applicationUser;
            experiments?.forEach((exp) => {
                // Set Google Dimension Index based on experiment settings.
                let googleDimensionIndex = 99;

                if (exp.settings[experimentSettings.GOOGLE_CUSTOM_DIMENSION_INDEX] !== undefined) {
                    googleDimensionIndex = exp.settings[experimentSettings.GOOGLE_CUSTOM_DIMENSION_INDEX];
                }

                // Create object with dimension index and value.
                const experimentWithDimension = {
                    [`experimentId_${googleDimensionIndex}`]: exp.universeId,
                    [`variationId_${googleDimensionIndex}`]: exp.variationId,
                    [`experimentName_${googleDimensionIndex}`]: exp.universeName,
                    [`variationName_${googleDimensionIndex}`]: exp.variationName,
                    [`customDimension_${googleDimensionIndex}`]:
                        `${exp.universeId}_${exp.variationId}_${exp.universeName}_${exp.variationName}`
                };

                // Push to the data layer with the Google Custom Dimension Index.
                pushToDataLayerIfDefined(experimentWithDimension);
            });
        },

        prependActionToMethod(object, method, actionToPrepend) {
            const baseMethodName = method.name.startsWith('bound ')
                ? method.name.substring(6)
                : method.name;
            const baseMethod = object[baseMethodName];
            object[baseMethodName] = function () {
                actionToPrepend.apply(this, arguments);
                return baseMethod.apply(object, arguments);
            };
        },

        async initSession() {
            regenerateDeviceId();
            regenerateUserId();

            const deviceId = getDeviceIdValue(); // cookieNames.DXDEV
            const userId = getUserIdValue(); // cookieNames.ISS_USER_ID
            const sid = getSessionIdValue(); // cookieNames.SESSION_ID
            // const skey = getSessionKeyValue();
            const referrer = applicationConfig.CURRENT_ENVIRONMENT !== 'Localhost' ? document.referrer : null;
            const payload = {
                deviceId,
                referrer,
                sessionId: sid,
                userId,
                userAgent: navigator.userAgent
            };

            const response = await useMainStore().initializeSession(payload);

            if (response?.data) {
                if (response?.data.sessionKey) {
                    setSessionKeyIfUnset(response.data.sessionKey);
                }
                if (response?.data.sessionId) {
                    setSessionIdIfUnset(response.data.sessionId);
                }
            }
        },

        noSession() {
            return !areAllSessionCookiesSet();
        }
    },
    computed: {
        analyticsPageEvents() {
            return analyticsPageEvents;
        },
        GaCategories() {
            return GaCategories;
        },
        GaActions() {
            return GaActions;
        },
        GaLabels() {
            return GaLabels;
        },
        ValueToLogTypes() {
            return ValueToLogTypes;
        }
    }
};
