var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import { doesSurveyUrlMatch } from '../posthog-surveys';
import { SurveyQuestionBranchingType, SurveyQuestionType, SurveySchedule, SurveyType, SurveyWidgetType, } from '../posthog-surveys-types';
import { addEventListener } from '../utils';
import * as Preact from 'preact';
import { useContext, useEffect, useMemo, useRef, useState } from 'preact/hooks';
import { document as _document, window as _window } from '../utils/globals';
import { createLogger } from '../utils/logger';
import { isNull, isNumber } from '../utils/type-utils';
import { createWidgetShadow, createWidgetStyle } from './surveys-widget';
import { ConfirmationMessage } from './surveys/components/ConfirmationMessage';
import { Cancel } from './surveys/components/QuestionHeader';
import { LinkQuestion, MultipleChoiceQuestion, OpenTextQuestion, RatingQuestion, } from './surveys/components/QuestionTypes';
import { createShadow, defaultSurveyAppearance, dismissedSurveyEvent, getContrastingTextColor, getDisplayOrderQuestions, getSurveyResponseKey, getSurveySeen, hasWaitPeriodPassed, sendSurveyEvent, style, SURVEY_DEFAULT_Z_INDEX, SurveyContext, } from './surveys/surveys-utils';
import { prepareStylesheet } from './utils/stylesheet-loader';
var logger = createLogger('[Surveys]');
// We cast the types here which is dangerous but protected by the top level generateSurveys call
var window = _window;
var document = _document;
function getPosthogWidgetClass(surveyId) {
    return ".PostHogWidget".concat(surveyId);
}
var DISPATCH_FEEDBACK_WIDGET_EVENT = 'ph:show_survey_widget';
function getRatingBucketForResponseValue(responseValue, scale) {
    if (scale === 3) {
        if (responseValue < 1 || responseValue > 3) {
            throw new Error('The response must be in range 1-3');
        }
        return responseValue === 1 ? 'negative' : responseValue === 2 ? 'neutral' : 'positive';
    }
    else if (scale === 5) {
        if (responseValue < 1 || responseValue > 5) {
            throw new Error('The response must be in range 1-5');
        }
        return responseValue <= 2 ? 'negative' : responseValue === 3 ? 'neutral' : 'positive';
    }
    else if (scale === 7) {
        if (responseValue < 1 || responseValue > 7) {
            throw new Error('The response must be in range 1-7');
        }
        return responseValue <= 3 ? 'negative' : responseValue === 4 ? 'neutral' : 'positive';
    }
    else if (scale === 10) {
        if (responseValue < 0 || responseValue > 10) {
            throw new Error('The response must be in range 0-10');
        }
        return responseValue <= 6 ? 'detractors' : responseValue <= 8 ? 'passives' : 'promoters';
    }
    throw new Error('The scale must be one of: 3, 5, 7, 10');
}
export function getNextSurveyStep(survey, currentQuestionIndex, response) {
    var _a, _b, _c, _d, _e;
    var question = survey.questions[currentQuestionIndex];
    var nextQuestionIndex = currentQuestionIndex + 1;
    if (!((_a = question.branching) === null || _a === void 0 ? void 0 : _a.type)) {
        if (currentQuestionIndex === survey.questions.length - 1) {
            return SurveyQuestionBranchingType.End;
        }
        return nextQuestionIndex;
    }
    if (question.branching.type === SurveyQuestionBranchingType.End) {
        return SurveyQuestionBranchingType.End;
    }
    else if (question.branching.type === SurveyQuestionBranchingType.SpecificQuestion) {
        if (Number.isInteger(question.branching.index)) {
            return question.branching.index;
        }
    }
    else if (question.branching.type === SurveyQuestionBranchingType.ResponseBased) {
        // Single choice
        if (question.type === SurveyQuestionType.SingleChoice) {
            // :KLUDGE: for now, look up the choiceIndex based on the response
            // TODO: once QuestionTypes.MultipleChoiceQuestion is refactored, pass the selected choiceIndex into this method
            var selectedChoiceIndex = question.choices.indexOf("".concat(response));
            if ((_c = (_b = question.branching) === null || _b === void 0 ? void 0 : _b.responseValues) === null || _c === void 0 ? void 0 : _c.hasOwnProperty(selectedChoiceIndex)) {
                var nextStep = question.branching.responseValues[selectedChoiceIndex];
                // Specific question
                if (Number.isInteger(nextStep)) {
                    return nextStep;
                }
                if (nextStep === SurveyQuestionBranchingType.End) {
                    return SurveyQuestionBranchingType.End;
                }
                return nextQuestionIndex;
            }
        }
        else if (question.type === SurveyQuestionType.Rating) {
            if (typeof response !== 'number' || !Number.isInteger(response)) {
                throw new Error('The response type must be an integer');
            }
            var ratingBucket = getRatingBucketForResponseValue(response, question.scale);
            if ((_e = (_d = question.branching) === null || _d === void 0 ? void 0 : _d.responseValues) === null || _e === void 0 ? void 0 : _e.hasOwnProperty(ratingBucket)) {
                var nextStep = question.branching.responseValues[ratingBucket];
                // Specific question
                if (Number.isInteger(nextStep)) {
                    return nextStep;
                }
                if (nextStep === SurveyQuestionBranchingType.End) {
                    return SurveyQuestionBranchingType.End;
                }
                return nextQuestionIndex;
            }
        }
        return nextQuestionIndex;
    }
    logger.warn('Falling back to next question index due to unexpected branching type');
    return nextQuestionIndex;
}
var SurveyManager = /** @class */ (function () {
    function SurveyManager(posthog) {
        var _this = this;
        this.surveyTimeouts = new Map();
        this.widgetSelectorListeners = new Map();
        this.canShowNextEventBasedSurvey = function () {
            var _a;
            // with event based surveys, we need to show the next survey without reloading the page.
            // A simple check for div elements with the class name pattern of PostHogSurvey_xyz doesn't work here
            // because preact leaves behind the div element for any surveys responded/dismissed with a <style> node.
            // To alleviate this, we check the last div in the dom and see if it has any elements other than a Style node.
            // if the last PostHogSurvey_xyz div has only one style node, we can show the next survey in the queue
            // without reloading the page.
            var surveyPopups = document.querySelectorAll("div[class^=PostHogSurvey]");
            if (surveyPopups.length > 0) {
                return ((_a = surveyPopups[surveyPopups.length - 1].shadowRoot) === null || _a === void 0 ? void 0 : _a.childElementCount) === 1;
            }
            return true;
        };
        this.handlePopoverSurvey = function (survey) {
            var _a, _b;
            var surveyWaitPeriodInDays = (_a = survey.conditions) === null || _a === void 0 ? void 0 : _a.seenSurveyWaitPeriodInDays;
            var lastSeenSurveyDate = localStorage.getItem("lastSeenSurveyDate");
            if (!hasWaitPeriodPassed(lastSeenSurveyDate, surveyWaitPeriodInDays)) {
                return;
            }
            var surveySeen = getSurveySeen(survey);
            if (!surveySeen) {
                _this.clearSurveyTimeout(survey.id);
                _this.addSurveyToFocus(survey.id);
                var delaySeconds = ((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.surveyPopupDelaySeconds) || 0;
                var shadow_1 = createShadow(style(survey === null || survey === void 0 ? void 0 : survey.appearance), survey.id, undefined, _this.posthog);
                if (delaySeconds <= 0) {
                    return Preact.render(<SurveyPopup key={'popover-survey'} posthog={_this.posthog} survey={survey} removeSurveyFromFocus={_this.removeSurveyFromFocus} isPopup={true}/>, shadow_1);
                }
                var timeoutId = setTimeout(function () {
                    if (!doesSurveyUrlMatch(survey)) {
                        return _this.removeSurveyFromFocus(survey.id);
                    }
                    // rendering with surveyPopupDelaySeconds = 0 because we're already handling the timeout here
                    Preact.render(<SurveyPopup key={'popover-survey'} posthog={_this.posthog} survey={__assign(__assign({}, survey), { appearance: __assign(__assign({}, survey.appearance), { surveyPopupDelaySeconds: 0 }) })} removeSurveyFromFocus={_this.removeSurveyFromFocus} isPopup={true}/>, shadow_1);
                }, delaySeconds * 1000);
                _this.surveyTimeouts.set(survey.id, timeoutId);
            }
        };
        this.handleWidget = function (survey) {
            // Ensure widget container exists if it doesn't
            if (document.querySelectorAll(getPosthogWidgetClass(survey.id)).length === 0) {
                var shadow = createWidgetShadow(survey, _this.posthog);
                var stylesheetContent = style(survey.appearance);
                var stylesheet = prepareStylesheet(document, stylesheetContent, _this.posthog);
                if (stylesheet) {
                    shadow.appendChild(stylesheet);
                }
                Preact.render(<FeedbackWidget key={'feedback-survey-' + survey.id} // Use unique key
                 posthog={_this.posthog} survey={survey} removeSurveyFromFocus={_this.removeSurveyFromFocus}/>, shadow);
            }
        };
        this.removeWidgetSelectorListener = function (surveyId) {
            var existing = _this.widgetSelectorListeners.get(surveyId);
            if (existing) {
                existing.element.removeEventListener('click', existing.listener);
                existing.element.removeAttribute('PHWidgetSurveyClickListener');
                _this.widgetSelectorListeners.delete(surveyId);
                logger.info("Removed click listener for survey ".concat(surveyId));
            }
        };
        this.manageWidgetSelectorListener = function (survey) {
            var _a;
            var selector = (_a = survey.appearance) === null || _a === void 0 ? void 0 : _a.widgetSelector;
            if (!selector) {
                return;
            }
            var currentElement = document.querySelector(selector);
            var existingListenerData = _this.widgetSelectorListeners.get(survey.id);
            if (!currentElement) {
                // Element not found, remove listener if it exists
                if (existingListenerData) {
                    _this.removeWidgetSelectorListener(survey.id);
                }
                return;
            }
            // Ensure the base widget is rendered first if needed
            _this.handleWidget(survey);
            if (existingListenerData) {
                // Listener exists, check if element changed
                if (currentElement !== existingListenerData.element) {
                    logger.info("Selector element changed for survey ".concat(survey.id, ". Re-attaching listener."));
                    _this.removeWidgetSelectorListener(survey.id);
                    // Continue to attach listener to the new element below
                }
                else {
                    // Element is the same, listener already attached, do nothing
                    return;
                }
            }
            // Element found, and no listener attached (or it was just removed from old element)
            if (!currentElement.hasAttribute('PHWidgetSurveyClickListener')) {
                var listener = function (event) {
                    var _a, _b;
                    event.stopPropagation(); // Prevent bubbling
                    var buttonRect = event.currentTarget.getBoundingClientRect();
                    var viewportHeight = window.innerHeight;
                    var viewportWidth = window.innerWidth;
                    var surveyWidth = parseInt(((_a = survey.appearance) === null || _a === void 0 ? void 0 : _a.maxWidth) || '300');
                    var estimatedMinSurveyHeight = 250; // Keep this estimation
                    var buttonCenterX = buttonRect.left + buttonRect.width / 2;
                    var left = buttonCenterX - surveyWidth / 2;
                    var horizontalPadding = 20;
                    if (left + surveyWidth > viewportWidth - horizontalPadding) {
                        left = viewportWidth - surveyWidth - horizontalPadding;
                    }
                    if (left < horizontalPadding) {
                        left = horizontalPadding;
                    }
                    var spacing = 12;
                    var spaceBelow = viewportHeight - buttonRect.bottom;
                    var spaceAbove = buttonRect.top;
                    var showAbove = spaceBelow < estimatedMinSurveyHeight && spaceAbove > spaceBelow;
                    var positionStyles = {
                        position: 'fixed',
                        top: showAbove ? 'auto' : "".concat(buttonRect.bottom + spacing, "px"),
                        left: "".concat(left, "px"),
                        right: 'auto',
                        bottom: showAbove ? "".concat(viewportHeight - buttonRect.top + spacing, "px") : 'auto',
                        boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
                        borderBottom: "1.5px solid ".concat(((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.borderColor) || '#c9c6c6'),
                        borderRadius: '10px',
                        zIndex: SURVEY_DEFAULT_Z_INDEX,
                    };
                    // Dispatch event for the FeedbackWidget to catch
                    window.dispatchEvent(new CustomEvent(DISPATCH_FEEDBACK_WIDGET_EVENT, {
                        detail: { surveyId: survey.id, position: positionStyles },
                    }));
                };
                addEventListener(currentElement, 'click', listener);
                currentElement.setAttribute('PHWidgetSurveyClickListener', 'true');
                _this.widgetSelectorListeners.set(survey.id, { element: currentElement, listener: listener });
                logger.info("Attached click listener for survey ".concat(survey.id));
            }
        };
        /**
         * Checks the feature flags associated with this Survey to see if the survey can be rendered.
         * @param survey
         * @param instance
         */
        this.canRenderSurvey = function (survey) {
            var renderReason = {
                visible: false,
            };
            if (survey.end_date) {
                renderReason.disabledReason = "survey was completed on ".concat(survey.end_date);
                return renderReason;
            }
            if (survey.type != SurveyType.Popover) {
                renderReason.disabledReason = "Only Popover survey types can be rendered";
                return renderReason;
            }
            var linkedFlagCheck = survey.linked_flag_key
                ? _this.posthog.featureFlags.isFeatureEnabled(survey.linked_flag_key)
                : true;
            if (!linkedFlagCheck) {
                renderReason.disabledReason = "linked feature flag ".concat(survey.linked_flag_key, " is false");
                return renderReason;
            }
            var targetingFlagCheck = survey.targeting_flag_key
                ? _this.posthog.featureFlags.isFeatureEnabled(survey.targeting_flag_key)
                : true;
            if (!targetingFlagCheck) {
                renderReason.disabledReason = "targeting feature flag ".concat(survey.targeting_flag_key, " is false");
                return renderReason;
            }
            var internalTargetingFlagCheck = survey.internal_targeting_flag_key
                ? _this.posthog.featureFlags.isFeatureEnabled(survey.internal_targeting_flag_key)
                : true;
            if (!internalTargetingFlagCheck) {
                renderReason.disabledReason = "internal targeting feature flag ".concat(survey.internal_targeting_flag_key, " is false");
                return renderReason;
            }
            renderReason.visible = true;
            return renderReason;
        };
        this.renderSurvey = function (survey, selector) {
            Preact.render(<SurveyPopup key={'popover-survey'} posthog={_this.posthog} survey={survey} removeSurveyFromFocus={_this.removeSurveyFromFocus} isPopup={false}/>, selector);
        };
        this.callSurveysAndEvaluateDisplayLogic = function (forceReload) {
            var _a;
            if (forceReload === void 0) { forceReload = false; }
            (_a = _this.posthog) === null || _a === void 0 ? void 0 : _a.getActiveMatchingSurveys(function (surveys) {
                var nonAPISurveys = surveys.filter(function (survey) { return survey.type !== 'api'; });
                // Create a queue of surveys sorted by their appearance delay.  We will evaluate the display logic
                // for each survey in the queue in order, and only display one survey at a time.
                var nonAPISurveyQueue = _this.sortSurveysByAppearanceDelay(nonAPISurveys);
                // Keep track of surveys processed this cycle to remove listeners for inactive ones
                var activeSelectorSurveyIds = new Set();
                nonAPISurveyQueue.forEach(function (survey) {
                    var _a, _b, _c;
                    // Widget Type Logic
                    if (survey.type === SurveyType.Widget) {
                        if (((_a = survey.appearance) === null || _a === void 0 ? void 0 : _a.widgetType) === SurveyWidgetType.Tab) {
                            // Render tab widget if not already present
                            _this.handleWidget(survey);
                        }
                        else if (((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.widgetType) === SurveyWidgetType.Selector &&
                            ((_c = survey.appearance) === null || _c === void 0 ? void 0 : _c.widgetSelector)) {
                            activeSelectorSurveyIds.add(survey.id);
                            // Manage the listener attachment/detachment dynamically
                            _this.manageWidgetSelectorListener(survey);
                        }
                    }
                    // Popover Type Logic (only one shown at a time)
                    if (isNull(_this.surveyInFocus) &&
                        survey.type === SurveyType.Popover &&
                        _this.canShowNextEventBasedSurvey()) {
                        _this.handlePopoverSurvey(survey);
                    }
                });
                // Clean up listeners for surveys that are no longer active or matched
                _this.widgetSelectorListeners.forEach(function (_, surveyId) {
                    if (!activeSelectorSurveyIds.has(surveyId)) {
                        _this.removeWidgetSelectorListener(surveyId);
                    }
                });
            }, forceReload);
        };
        this.addSurveyToFocus = function (id) {
            if (!isNull(_this.surveyInFocus)) {
                logger.error("Survey ".concat(__spreadArray([], __read(_this.surveyInFocus), false), " already in focus. Cannot add survey ").concat(id, "."));
            }
            _this.surveyInFocus = id;
        };
        this.removeSurveyFromFocus = function (id) {
            if (_this.surveyInFocus !== id) {
                logger.error("Survey ".concat(id, " is not in focus. Cannot remove survey ").concat(id, "."));
            }
            _this.clearSurveyTimeout(id);
            _this.surveyInFocus = null;
        };
        this.posthog = posthog;
        // This is used to track the survey that is currently in focus. We only show one survey at a time.
        this.surveyInFocus = null;
    }
    SurveyManager.prototype.clearSurveyTimeout = function (surveyId) {
        var timeout = this.surveyTimeouts.get(surveyId);
        if (timeout) {
            clearTimeout(timeout);
            this.surveyTimeouts.delete(surveyId);
        }
    };
    /**
     * Sorts surveys by their appearance delay in ascending order. If a survey does not have an appearance delay,
     * it is considered to have a delay of 0.
     * @param surveys
     * @returns The surveys sorted by their appearance delay
     */
    SurveyManager.prototype.sortSurveysByAppearanceDelay = function (surveys) {
        return surveys.sort(function (a, b) {
            var _a, _b;
            var aIsAlways = a.schedule === SurveySchedule.Always;
            var bIsAlways = b.schedule === SurveySchedule.Always;
            if (aIsAlways && !bIsAlways) {
                return 1; // a comes after b
            }
            if (!aIsAlways && bIsAlways) {
                return -1; // a comes before b
            }
            // If both are Always or neither is Always, sort by delay
            return (((_a = a.appearance) === null || _a === void 0 ? void 0 : _a.surveyPopupDelaySeconds) || 0) - (((_b = b.appearance) === null || _b === void 0 ? void 0 : _b.surveyPopupDelaySeconds) || 0);
        });
    };
    // Expose internal state and methods for testing
    SurveyManager.prototype.getTestAPI = function () {
        return {
            addSurveyToFocus: this.addSurveyToFocus,
            removeSurveyFromFocus: this.removeSurveyFromFocus,
            surveyInFocus: this.surveyInFocus,
            surveyTimeouts: this.surveyTimeouts,
            canShowNextEventBasedSurvey: this.canShowNextEventBasedSurvey,
            handleWidget: this.handleWidget,
            handlePopoverSurvey: this.handlePopoverSurvey,
            manageWidgetSelectorListener: this.manageWidgetSelectorListener,
            sortSurveysByAppearanceDelay: this.sortSurveysByAppearanceDelay,
        };
    };
    return SurveyManager;
}());
export { SurveyManager };
export var renderSurveysPreview = function (_a) {
    var _b, _c;
    var survey = _a.survey, parentElement = _a.parentElement, previewPageIndex = _a.previewPageIndex, forceDisableHtml = _a.forceDisableHtml, onPreviewSubmit = _a.onPreviewSubmit, posthog = _a.posthog;
    var stylesheetContent = style(survey.appearance);
    var stylesheet = prepareStylesheet(document, stylesheetContent, posthog);
    // Remove previously attached <style>
    Array.from(parentElement.children).forEach(function (child) {
        if (child instanceof HTMLStyleElement) {
            parentElement.removeChild(child);
        }
    });
    if (stylesheet) {
        parentElement.appendChild(stylesheet);
    }
    var textColor = getContrastingTextColor(((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.backgroundColor) || defaultSurveyAppearance.backgroundColor || 'white');
    Preact.render(<SurveyPopup key="surveys-render-preview" survey={survey} forceDisableHtml={forceDisableHtml} style={{
            position: 'relative',
            right: 0,
            borderBottom: "1px solid ".concat((_c = survey.appearance) === null || _c === void 0 ? void 0 : _c.borderColor),
            borderRadius: 10,
            color: textColor,
        }} onPreviewSubmit={onPreviewSubmit} previewPageIndex={previewPageIndex} removeSurveyFromFocus={function () { }} isPopup={true}/>, parentElement);
};
export var renderFeedbackWidgetPreview = function (_a) {
    var _b;
    var survey = _a.survey, root = _a.root, forceDisableHtml = _a.forceDisableHtml, posthog = _a.posthog;
    var stylesheetContent = createWidgetStyle((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.widgetColor);
    var stylesheet = prepareStylesheet(document, stylesheetContent, posthog);
    if (stylesheet) {
        root.appendChild(stylesheet);
    }
    Preact.render(<FeedbackWidget key={'feedback-render-preview'} forceDisableHtml={forceDisableHtml} survey={survey} readOnly={true} removeSurveyFromFocus={function () { }}/>, root);
};
// This is the main exported function
export function generateSurveys(posthog) {
    // NOTE: Important to ensure we never try and run surveys without a window environment
    if (!document || !window) {
        return;
    }
    var surveyManager = new SurveyManager(posthog);
    surveyManager.callSurveysAndEvaluateDisplayLogic(true);
    // recalculate surveys every second to check if URL or selectors have changed
    setInterval(function () {
        surveyManager.callSurveysAndEvaluateDisplayLogic(false);
    }, 1000);
    return surveyManager;
}
/**
 * This hook handles URL-based survey visibility after the initial mount.
 * The initial URL check is handled by the `getActiveMatchingSurveys` method in  the `PostHogSurveys` class,
 * which ensures the URL matches before displaying a survey for the first time.
 * That is the method that is called every second to see if there's a matching survey.
 *
 * This separation of concerns means:
 * 1. Initial URL matching is done by `getActiveMatchingSurveys` before displaying the survey
 * 2. Subsequent URL changes are handled here to hide the survey as the user navigates
 */
export function useHideSurveyOnURLChange(_a) {
    var survey = _a.survey, removeSurveyFromFocus = _a.removeSurveyFromFocus, setSurveyVisible = _a.setSurveyVisible, _b = _a.isPreviewMode, isPreviewMode = _b === void 0 ? false : _b;
    useEffect(function () {
        var _a;
        if (isPreviewMode || !((_a = survey.conditions) === null || _a === void 0 ? void 0 : _a.url)) {
            return;
        }
        var checkUrlMatch = function () {
            var urlCheck = doesSurveyUrlMatch(survey);
            if (!urlCheck) {
                setSurveyVisible(false);
                return removeSurveyFromFocus(survey.id);
            }
        };
        // Listen for browser back/forward browser history changes
        addEventListener(window, 'popstate', checkUrlMatch);
        // Listen for hash changes, for SPA frameworks that use hash-based routing
        // The hashchange event is fired when the fragment identifier of the URL has changed (the part of the URL beginning with and following the # symbol).
        addEventListener(window, 'hashchange', checkUrlMatch);
        // Listen for SPA navigation
        var originalPushState = window.history.pushState;
        var originalReplaceState = window.history.replaceState;
        window.history.pushState = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            originalPushState.apply(this, args);
            checkUrlMatch();
        };
        window.history.replaceState = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            originalReplaceState.apply(this, args);
            checkUrlMatch();
        };
        return function () {
            window.removeEventListener('popstate', checkUrlMatch);
            window.removeEventListener('hashchange', checkUrlMatch);
            window.history.pushState = originalPushState;
            window.history.replaceState = originalReplaceState;
        };
    }, [isPreviewMode, survey, removeSurveyFromFocus, setSurveyVisible]);
}
export function usePopupVisibility(survey, posthog, millisecondDelay, isPreviewMode, removeSurveyFromFocus) {
    var _a = __read(useState(isPreviewMode || millisecondDelay === 0), 2), isPopupVisible = _a[0], setIsPopupVisible = _a[1];
    var _b = __read(useState(false), 2), isSurveySent = _b[0], setIsSurveySent = _b[1];
    useEffect(function () {
        if (!posthog) {
            logger.error('usePopupVisibility hook called without a PostHog instance.');
            return;
        }
        if (isPreviewMode) {
            return;
        }
        var handleSurveyClosed = function () {
            removeSurveyFromFocus(survey.id);
            setIsPopupVisible(false);
        };
        var handleSurveySent = function () {
            var _a, _b;
            if (!((_a = survey.appearance) === null || _a === void 0 ? void 0 : _a.displayThankYouMessage)) {
                removeSurveyFromFocus(survey.id);
                setIsPopupVisible(false);
            }
            else {
                setIsSurveySent(true);
                removeSurveyFromFocus(survey.id);
                if ((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.autoDisappear) {
                    setTimeout(function () {
                        setIsPopupVisible(false);
                    }, 5000);
                }
            }
        };
        var showSurvey = function () {
            var _a;
            // check if the url is still matching, necessary for delayed surveys, as the URL may have changed
            if (!doesSurveyUrlMatch(survey)) {
                return;
            }
            setIsPopupVisible(true);
            window.dispatchEvent(new Event('PHSurveyShown'));
            posthog.capture('survey shown', {
                $survey_name: survey.name,
                $survey_id: survey.id,
                $survey_iteration: survey.current_iteration,
                $survey_iteration_start_date: survey.current_iteration_start_date,
                sessionRecordingUrl: (_a = posthog.get_session_replay_url) === null || _a === void 0 ? void 0 : _a.call(posthog),
            });
            localStorage.setItem('lastSeenSurveyDate', new Date().toISOString());
            setTimeout(function () {
                var _a, _b;
                var inputField = (_b = (_a = document
                    .querySelector(getPosthogWidgetClass(survey.id))) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('textarea, input[type="text"]');
                if (inputField) {
                    inputField.focus();
                }
            }, 100);
        };
        addEventListener(window, 'PHSurveyClosed', handleSurveyClosed);
        addEventListener(window, 'PHSurveySent', handleSurveySent);
        if (millisecondDelay > 0) {
            // This path is only used for direct usage of SurveyPopup,
            // not for surveys managed by SurveyManager
            var timeoutId_1 = setTimeout(showSurvey, millisecondDelay);
            return function () {
                clearTimeout(timeoutId_1);
                window.removeEventListener('PHSurveyClosed', handleSurveyClosed);
                window.removeEventListener('PHSurveySent', handleSurveySent);
            };
        }
        else {
            // This is the path used for surveys managed by SurveyManager
            showSurvey();
            return function () {
                window.removeEventListener('PHSurveyClosed', handleSurveyClosed);
                window.removeEventListener('PHSurveySent', handleSurveySent);
            };
        }
    }, []);
    useHideSurveyOnURLChange({
        survey: survey,
        removeSurveyFromFocus: removeSurveyFromFocus,
        setSurveyVisible: setIsPopupVisible,
        isPreviewMode: isPreviewMode,
    });
    return { isPopupVisible: isPopupVisible, isSurveySent: isSurveySent, setIsPopupVisible: setIsPopupVisible };
}
export function SurveyPopup(_a) {
    var _b, _c, _d, _e;
    var survey = _a.survey, forceDisableHtml = _a.forceDisableHtml, posthog = _a.posthog, style = _a.style, previewPageIndex = _a.previewPageIndex, removeSurveyFromFocus = _a.removeSurveyFromFocus, isPopup = _a.isPopup, _f = _a.onPreviewSubmit, onPreviewSubmit = _f === void 0 ? function () { } : _f, _g = _a.onPopupSurveyDismissed, onPopupSurveyDismissed = _g === void 0 ? function () { } : _g, _h = _a.onCloseConfirmationMessage, onCloseConfirmationMessage = _h === void 0 ? function () { } : _h;
    var isPreviewMode = Number.isInteger(previewPageIndex);
    // NB: The client-side code passes the millisecondDelay in seconds, but setTimeout expects milliseconds, so we multiply by 1000
    var surveyPopupDelayMilliseconds = ((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.surveyPopupDelaySeconds)
        ? survey.appearance.surveyPopupDelaySeconds * 1000
        : 0;
    var _j = usePopupVisibility(survey, posthog, surveyPopupDelayMilliseconds, isPreviewMode, removeSurveyFromFocus), isPopupVisible = _j.isPopupVisible, isSurveySent = _j.isSurveySent, setIsPopupVisible = _j.setIsPopupVisible;
    var shouldShowConfirmation = isSurveySent || previewPageIndex === survey.questions.length;
    var confirmationBoxLeftStyle = (style === null || style === void 0 ? void 0 : style.left) && isNumber(style === null || style === void 0 ? void 0 : style.left) ? { left: style.left - 40 } : {};
    if (isPreviewMode) {
        style = style || {};
        style.left = 'unset';
        style.right = 'unset';
        style.transform = 'unset';
    }
    return isPopupVisible ? (<SurveyContext.Provider value={{
            isPreviewMode: isPreviewMode,
            previewPageIndex: previewPageIndex,
            onPopupSurveyDismissed: function () {
                dismissedSurveyEvent(survey, posthog, isPreviewMode);
                onPopupSurveyDismissed();
            },
            isPopup: isPopup || false,
            onPreviewSubmit: onPreviewSubmit,
        }}>
            {!shouldShowConfirmation ? (<Questions survey={survey} forceDisableHtml={!!forceDisableHtml} posthog={posthog} styleOverrides={style}/>) : (<ConfirmationMessage header={((_c = survey.appearance) === null || _c === void 0 ? void 0 : _c.thankYouMessageHeader) || 'Thank you!'} description={((_d = survey.appearance) === null || _d === void 0 ? void 0 : _d.thankYouMessageDescription) || ''} forceDisableHtml={!!forceDisableHtml} contentType={(_e = survey.appearance) === null || _e === void 0 ? void 0 : _e.thankYouMessageDescriptionContentType} appearance={survey.appearance || defaultSurveyAppearance} styleOverrides={__assign(__assign({}, style), confirmationBoxLeftStyle)} onClose={function () {
                setIsPopupVisible(false);
                onCloseConfirmationMessage();
            }}/>)}
        </SurveyContext.Provider>) : null;
}
export function Questions(_a) {
    var _b, _c;
    var survey = _a.survey, forceDisableHtml = _a.forceDisableHtml, posthog = _a.posthog, styleOverrides = _a.styleOverrides;
    var textColor = getContrastingTextColor(((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.backgroundColor) || defaultSurveyAppearance.backgroundColor);
    var _d = __read(useState({}), 2), questionsResponses = _d[0], setQuestionsResponses = _d[1];
    var _e = useContext(SurveyContext), previewPageIndex = _e.previewPageIndex, onPopupSurveyDismissed = _e.onPopupSurveyDismissed, isPopup = _e.isPopup, onPreviewSubmit = _e.onPreviewSubmit;
    var _f = __read(useState(previewPageIndex || 0), 2), currentQuestionIndex = _f[0], setCurrentQuestionIndex = _f[1];
    var surveyQuestions = useMemo(function () { return getDisplayOrderQuestions(survey); }, [survey]);
    // Sync preview state
    useEffect(function () {
        setCurrentQuestionIndex(previewPageIndex !== null && previewPageIndex !== void 0 ? previewPageIndex : 0);
    }, [previewPageIndex]);
    var onNextButtonClick = function (_a) {
        var _b, _c;
        var res = _a.res, displayQuestionIndex = _a.displayQuestionIndex, questionId = _a.questionId;
        if (!posthog) {
            logger.error('onNextButtonClick called without a PostHog instance.');
            return;
        }
        if (!questionId) {
            logger.error('onNextButtonClick called without a questionId.');
            return;
        }
        var responseKey = getSurveyResponseKey(questionId);
        setQuestionsResponses(__assign(__assign({}, questionsResponses), (_b = {}, _b[responseKey] = res, _b)));
        var nextStep = getNextSurveyStep(survey, displayQuestionIndex, res);
        if (nextStep === SurveyQuestionBranchingType.End) {
            sendSurveyEvent(__assign(__assign({}, questionsResponses), (_c = {}, _c[responseKey] = res, _c)), survey, posthog);
        }
        else {
            setCurrentQuestionIndex(nextStep);
        }
    };
    return (<form className="survey-form" style={isPopup
            ? __assign({ color: textColor, borderColor: (_c = survey.appearance) === null || _c === void 0 ? void 0 : _c.borderColor }, styleOverrides) : {}}>
            {surveyQuestions.map(function (question, displayQuestionIndex) {
            var _a;
            var isVisible = currentQuestionIndex === displayQuestionIndex;
            return (isVisible && (<div className="survey-box" style={isPopup
                    ? {
                        backgroundColor: ((_a = survey.appearance) === null || _a === void 0 ? void 0 : _a.backgroundColor) ||
                            defaultSurveyAppearance.backgroundColor,
                    }
                    : {}}>
                            {isPopup && (<Cancel onClick={function () {
                        onPopupSurveyDismissed();
                    }}/>)}
                            {getQuestionComponent({
                    question: question,
                    forceDisableHtml: forceDisableHtml,
                    displayQuestionIndex: displayQuestionIndex,
                    appearance: survey.appearance || defaultSurveyAppearance,
                    onSubmit: function (res) {
                        return onNextButtonClick({
                            res: res,
                            displayQuestionIndex: displayQuestionIndex,
                            questionId: question.id,
                        });
                    },
                    onPreviewSubmit: onPreviewSubmit,
                })}
                        </div>));
        })}
        </form>);
}
export function FeedbackWidget(_a) {
    var _b, _c, _d, _e, _f;
    var survey = _a.survey, forceDisableHtml = _a.forceDisableHtml, posthog = _a.posthog, readOnly = _a.readOnly, removeSurveyFromFocus = _a.removeSurveyFromFocus;
    var _g = __read(useState(true), 2), isFeedbackButtonVisible = _g[0], setIsFeedbackButtonVisible = _g[1];
    var _h = __read(useState(false), 2), showSurvey = _h[0], setShowSurvey = _h[1];
    var _j = __read(useState({}), 2), styleOverrides = _j[0], setStyleOverrides = _j[1];
    var widgetRef = useRef(null);
    useEffect(function () {
        var _a, _b;
        if (!posthog) {
            logger.error('FeedbackWidget called without a PostHog instance.');
            return;
        }
        if (readOnly) {
            return;
        }
        if (((_a = survey.appearance) === null || _a === void 0 ? void 0 : _a.widgetType) === 'tab') {
            if (widgetRef.current) {
                var widgetPos = widgetRef.current.getBoundingClientRect();
                setStyleOverrides({
                    top: '50%',
                    left: parseInt("".concat(widgetPos.right - 360)),
                    bottom: 'auto',
                    borderRadius: 10,
                    borderBottom: "1.5px solid ".concat(((_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.borderColor) || '#c9c6c6'),
                });
            }
        }
        var handleShowSurvey = function (event) {
            var _a;
            var customEvent = event;
            // Check if the event is for this specific survey instance
            if (((_a = customEvent.detail) === null || _a === void 0 ? void 0 : _a.surveyId) === survey.id) {
                logger.info("Received show event for survey ".concat(survey.id));
                setStyleOverrides(customEvent.detail.position || {});
                setShowSurvey(true); // Show the survey popup
            }
        };
        addEventListener(window, DISPATCH_FEEDBACK_WIDGET_EVENT, handleShowSurvey);
        // Cleanup listener on component unmount
        return function () {
            window.removeEventListener(DISPATCH_FEEDBACK_WIDGET_EVENT, handleShowSurvey);
        };
    }, [
        posthog,
        readOnly,
        survey.id,
        (_b = survey.appearance) === null || _b === void 0 ? void 0 : _b.widgetType,
        (_c = survey.appearance) === null || _c === void 0 ? void 0 : _c.widgetSelector,
        (_d = survey.appearance) === null || _d === void 0 ? void 0 : _d.borderColor,
    ]);
    useHideSurveyOnURLChange({
        survey: survey,
        removeSurveyFromFocus: removeSurveyFromFocus,
        setSurveyVisible: setIsFeedbackButtonVisible,
    });
    if (!isFeedbackButtonVisible) {
        return null;
    }
    var resetShowSurvey = function () {
        setShowSurvey(false);
    };
    return (<Preact.Fragment>
            {((_e = survey.appearance) === null || _e === void 0 ? void 0 : _e.widgetType) === 'tab' && (<div className="ph-survey-widget-tab" ref={widgetRef} onClick={function () { return !readOnly && setShowSurvey(!showSurvey); }} style={{ color: getContrastingTextColor(survey.appearance.widgetColor) }}>
                    <div className="ph-survey-widget-tab-icon"></div>
                    {((_f = survey.appearance) === null || _f === void 0 ? void 0 : _f.widgetLabel) || ''}
                </div>)}
            {showSurvey && (<SurveyPopup key={'feedback-widget-survey'} posthog={posthog} survey={survey} forceDisableHtml={forceDisableHtml} style={styleOverrides} removeSurveyFromFocus={removeSurveyFromFocus} isPopup={true} onPopupSurveyDismissed={resetShowSurvey} onCloseConfirmationMessage={resetShowSurvey}/>)}
        </Preact.Fragment>);
}
var getQuestionComponent = function (_a) {
    var _b, _c;
    var question = _a.question, forceDisableHtml = _a.forceDisableHtml, displayQuestionIndex = _a.displayQuestionIndex, appearance = _a.appearance, onSubmit = _a.onSubmit, onPreviewSubmit = _a.onPreviewSubmit;
    var questionComponents = (_b = {},
        _b[SurveyQuestionType.Open] = OpenTextQuestion,
        _b[SurveyQuestionType.Link] = LinkQuestion,
        _b[SurveyQuestionType.Rating] = RatingQuestion,
        _b[SurveyQuestionType.SingleChoice] = MultipleChoiceQuestion,
        _b[SurveyQuestionType.MultipleChoice] = MultipleChoiceQuestion,
        _b);
    var commonProps = {
        question: question,
        forceDisableHtml: forceDisableHtml,
        appearance: appearance,
        onPreviewSubmit: function (res) {
            onPreviewSubmit(res);
        },
        onSubmit: function (res) {
            onSubmit(res);
        },
    };
    var additionalProps = (_c = {},
        _c[SurveyQuestionType.Open] = {},
        _c[SurveyQuestionType.Link] = {},
        _c[SurveyQuestionType.Rating] = { displayQuestionIndex: displayQuestionIndex },
        _c[SurveyQuestionType.SingleChoice] = { displayQuestionIndex: displayQuestionIndex },
        _c[SurveyQuestionType.MultipleChoice] = { displayQuestionIndex: displayQuestionIndex },
        _c);
    var Component = questionComponents[question.type];
    var componentProps = __assign(__assign({}, commonProps), additionalProps[question.type]);
    return <Component {...componentProps}/>;
};
//# sourceMappingURL=surveys.jsx.map