import { storeActions } from "@/constants/store-actions";
import {
    setCookieProperties,
    getDeviceIdValue,
    getSessionIdValue,
    getSessionKeyValue,
} from "@/helpers/heritage-integration/cookie-helper";
import { queryStrings } from "@/constants/query-strings";
import { experimentSettings } from "@/constants/experiments";
import {
    analyticsPageEvents,
    GaCategories,
    GaActions,
    GaLabels,
    GaEvents,
    ValueToLogTypes,
} from "@/constants/analytics";
import { cookieNames } from "@/constants/cookie-names";
import store from "@/store";

import baseMixin from "@/mixins/base-mixin";
import { applicationConfig } from "../constants/application-config";

export default {
    methods: {
        getPageName() {
            return getPageNameByQueryString();
        },

        logPageView(pageEvent) {
            const currentPageName = getPageNameByQueryString();
            var payload = {
                userId: getDeviceIdValue(),
                sessionKey: getSessionKeyValue(),
                pageName: currentPageName,
                sessionId: getSessionIdValue(),
                action: "",
                event: pageEvent,
                shouldUseSessionId: false,
                experimentsForUser: store.getters.applicationUser.experiments,
                referralSequenceNumber: store.getters.order.referralSequenceNumber,
                parentAccountNumber: store.getters.order.payment.parentAccountNumber,
            };

            baseMixin.methods.dispatchStoreAction(storeActions.LOG_PAGE_VIEW, payload, false);
        },

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

            var payload = {
                userId: getDeviceIdValue(),
                sessionKey: getSessionKeyValue(),
                pageName: currentPageName,
                sessionId: getSessionIdValue(),
                category: category,
                action: action,
                label: label,
                value: value,
                shouldUseSessionId: false,
                experimentsForUser: store.getters.applicationUser.experiments,
                referralSequenceNumber: store.getters.order.referralSequenceNumber,
                parentAccountNumber: store.getters.order.payment.parentAccountNumber,
            };

            baseMixin.methods.dispatchStoreAction(storeActions.LOG_CUSTOM_EVENT, payload, false);
        },

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

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

            pushToDataLayerIfDefined(eventToBePushed);

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

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

            pushToDataLayerIfDefined(pageViewEvent);

            this.logPageView(analyticsPageEvents.ENTRY);
        },

        pushExperimentsToDataLayer() {
            const experiments = store.getters.applicationUser.experiments;
            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() {
            const sid = getSessionIdValue();
            const skey = getSessionKeyValue();
            const referrer =
                applicationConfig.CURRENT_ENVIRONMENT != "Localhost" ? document.referrer : null;

            var payload = {
                userId: getDeviceIdValue(),
                sessionId: sid,
                userAgent: navigator.userAgent,
                referrer: referrer,
            };

            const response = await baseMixin.methods.dispatchStoreAction(
                storeActions.INITIALIZE_SESSION,
                payload,
                false
            );

            if (response?.data) {
                if (response?.data.sessionKey && skey === 0) {
                    setCookieProperties(
                        { [cookieNames.SESSION_KEY]: response?.data.sessionKey },
                        {
                            useDefaultFunnelCookieAttributes: false,
                        }
                    );
                }
                if (response?.data.sessionId && sid === "00000000-0000-0000-0000-000000000000") {
                    setCookieProperties(
                        { [cookieNames.SESSION_ID]: response?.data.sessionId },
                        {
                            maxAge: 60 * 30, // 30 minutes
                        }
                    );
                }
            }
        },

        noSession() {
            return (
                getSessionKeyValue() === 0 ||
                getSessionIdValue() === "00000000-0000-0000-0000-000000000000"
            );
        },

        removeParamsFromEndpoint(endpoint) {
            const endpointWithoutParams = endpoint.split("?")[0];
            const numSlashesBeforeParams = 6;
            let splitString = endpointWithoutParams.split("/");
            if (splitString.length > numSlashesBeforeParams) {
                splitString = splitString.slice(0, numSlashesBeforeParams);
                return splitString.join("/");
            } else {
                return endpointWithoutParams;
            }
        },
    },
    computed: {
        analyticsPageEvents() {
            return analyticsPageEvents;
        },
        GaCategories() {
            return GaCategories;
        },
        GaActions() {
            return GaActions;
        },
        GaLabels() {
            return GaLabels;
        },
        ValueToLogTypes() {
            return ValueToLogTypes;
        },
    },
};

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

function getPageNameByQueryString() {
    const params = new URLSearchParams(location.search);

    if (params.has(queryStrings.FMG_PAGE)) {
        return params.get(queryStrings.FMG_PAGE);
    } else {
        return "";
    }
}

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