import {useContext, useEffect, useRef, useState, useMemo, useCallback} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import PopupContainer from "../../../../popups/container";
import {GetSettings, UpdateSetting} from "../../../../../rest/settings";
import {handleError} from "../../../../../helpers/notifications";
import {NotificationsContext} from "../../../../contexts/notifications";
import {BackgroundProcessProvider} from "../../../../contexts/background-process";
import Step1 from "./components/step-1";
import Step2 from "./components/step-2";
import Step3 from "./components/step-3";
import confirm from "../../../../../helpers/confirm";
import {GetConfig} from "../../../../../rest/configs";
import {areAllProcessesDone} from "./utils/process";
import {DEFAULT_CHATBOT_SETTINGS_KEY_PREFIX} from "../../../../../data/chatbot/settings";
import Button from "../../../../button/_";
import {NOTIF_QUICK_AUTOCLOSE_TIMEOUT} from "../../../../containers/notification-layout";
import ChatbotPreview, {getChatbotPreviewStorageKey} from "../../containers/content/chatbot-preview";
import {ChatbotPreviewContext} from "../../../../contexts/chatbot-preview";
import {PARAMETERS} from "../../../../../../components/chatbots/includes/constants";
import {launchConfetti} from "../../../../../helpers/confetti";

export const ONBOARDING_KEY_PREFIX = 'lbaic.onboarding.';

const STEPS = [
    {
        label: "1",
        step: 1,
    },
    {
        label: "2",
        step: 2,
    },
    {
        label: "3",
        step: 3,
    }
];

const getTheStepTitle = (step) => {
    switch (step) {
        case 1:
            return __("Connect AI provider", 'limb-chatbot');
        case 2:
            return __("Personalize your chatbot", 'limb-chatbot');
        case 3:
            return __("Feed with knowledge", 'limb-chatbot');
        default:
            return false;
    }
}

const getTheStepDescription = (step) => {
    switch (step) {
        case 1:
            return __("Please choose AI provider that suits you best. Later you can change this setting in the Chatbot → AI Settings", 'limb-chatbot');
        case 2:
            return __("Let us know whom or what is representing the chatbot. Later you can change this setting.", 'limb-chatbot');
        case 3:
            return __("Select the data to include in the learning process", 'limb-chatbot');
        default:
            return false;
    }
}

const POPUP_CHATBOT_GAP = 25;
const POPUP_AROUND_GAP = 32;

/**
 * Check if chatbot fits with popup in available space
 */
const checkChatbotFits = (adminPageRect, popupRect, chatbotWidth) => {
    const totalWidth = popupRect.width + POPUP_CHATBOT_GAP + chatbotWidth + 2 * POPUP_AROUND_GAP;

    return totalWidth <= adminPageRect.width;
};

/**
 * Update positions for onboarding popup and chatbot
 * Centers popup + chatbot together based on #lbaic-admin-page-settings
 */
export const updateOnboardingPositions = () => {
    const adminPageElement = document.getElementById('lbaic-admin-page-settings');
    if (!adminPageElement) {
        return;
    }

    const adminPageRect = adminPageElement.getBoundingClientRect();
    const popup = document.querySelector('.lbaic-settings-popup');

    if (!popup) {
        return;
    }

    const popupRect = popup.getBoundingClientRect();

    // Find chatbot preview containers
    const previewContainer = document.getElementById('lbaic-chatbot-preview');
    if (!previewContainer) {
        return;
    }

    const chatbotGrid = previewContainer?.querySelector('.lbaic-grid');
    const chatbotRect = chatbotGrid?.getBoundingClientRect();
    const rightChatbotElement = previewContainer.querySelector('#lbaic.lbaic-right');
    const leftChatbotElement = previewContainer.querySelector('#lbaic.lbaic-left');
    const chatbotElement = rightChatbotElement || leftChatbotElement;

    if (!chatbotElement) {
        return;
    }

    const isLargeScreen = window.innerWidth >= 768;

    // Determine if chatbot is positioned on right or left
    const isRightPosition = !!rightChatbotElement;
    const isLeftPosition = !!leftChatbotElement;

    const chatbotTriggerEl = chatbotElement.querySelector('.lbaic-trigger');
    const chatbotTriggerRect = chatbotTriggerEl?.getBoundingClientRect();
    const chatbotTriggerWidth = chatbotTriggerRect?.width;
    const chatbotGridWidth = chatbotRect?.width;

    // Check if chatbot trigger fits
    const chatbotTriggerFits = checkChatbotFits(
        adminPageRect,
        popupRect,
        chatbotTriggerWidth || 60
    );

    if (!isLargeScreen || !chatbotTriggerFits) {
        // Popup
        popup.style.position = '';
        popup.style.left = '';
        popup.style.top = '';
        popup.style.marginLeft = '';
        popup.style.marginTop = '';
        popup.style.marginRight = '';
        popup.style.marginBottom = '';
        // Chatbot
        let b = PARAMETERS.position[isLeftPosition ? 'left' : 'right'].bottom;
        if (document.querySelector('#chatbot-meta-box #lbaic-single-chatbot')) {
            b += 10;
        }
        if (document.querySelector('#lbaic-admin-page-settings')) {
            b -= 8;
        }
        rightChatbotElement?.style.setProperty('--lbaic-r', `${PARAMETERS.position.right.right - 8}px`);
        rightChatbotElement?.style.setProperty('--lbaic-l', '');
        rightChatbotElement?.style.setProperty('--lbaic-b', `${b}px`);
        rightChatbotElement?.style.setProperty('--lbaic-t', '');
        leftChatbotElement?.style.setProperty('--lbaic-l', `${PARAMETERS.position.left.left - 8}px`);
        leftChatbotElement?.style.setProperty('--lbaic-r', '');
        leftChatbotElement?.style.setProperty('--lbaic-b', `${b}px`);
        leftChatbotElement?.style.setProperty('--lbaic-t', '');

        return;
    }

    // Check if chatbot fits
    const chatbotFits = checkChatbotFits(
        adminPageRect,
        popupRect,
        chatbotGridWidth
    );

    // Calculate total width needed: popup width + 16px gap + chatbot width
    const popupWidth = popupRect.width;
    const chatbotWidth = Math.max(chatbotTriggerWidth || 60, chatbotGridWidth);
    const totalWidth = popupWidth + POPUP_CHATBOT_GAP + chatbotWidth;

    // Calculate center position based on admin page element (viewport coordinates)
    const centerX = adminPageRect.width / 2;
    const centerY = adminPageRect.height / 2;

    // Position popup: center the combined popup + chatbot
    // If chatbot is on left, popup should be positioned to the right of center
    // If chatbot is on right, popup should be positioned to the left of center
    let popupLeft;
    if (!chatbotGridWidth || chatbotFits) {
        if (isLeftPosition) {
            // Chatbot on left, popup on right: centerX is at center of (chatbot + gap + popup)
            // So popup left = centerX - totalWidth/2 + chatbotWidth + gap
            popupLeft = centerX - totalWidth / 2 + chatbotWidth + POPUP_CHATBOT_GAP;
        } else {
            // Chatbot on right, popup on left: centerX is at center of (popup + gap + chatbot)
            // So popup left = centerX - totalWidth/2
            popupLeft = centerX - totalWidth / 2;
        }
    } else {
        popupLeft = centerX - popupWidth / 2;
    }

    const popupTop = centerY - popupRect.height / 2;

    popup.style.position = 'absolute';
    popup.style.left = `${popupLeft}px`;
    popup.style.top = `${popupTop}px`;
    popup.style.marginLeft = '0';
    popup.style.marginTop = '0';
    popup.style.marginRight = 'auto';
    popup.style.marginBottom = 'auto';

    // Bottom position
    if (isLargeScreen) {
        const bottomPosition = window.innerHeight - adminPageRect.top - popupTop - popupRect.height;
        rightChatbotElement?.style.setProperty('--lbaic-b', `${bottomPosition}px`);
        rightChatbotElement?.style.removeProperty('--lbaic-t');
        leftChatbotElement?.style.setProperty('--lbaic-b', `${bottomPosition}px`);
        leftChatbotElement?.style.removeProperty('--lbaic-t');
    } else {
        let b = PARAMETERS.position[isLeftPosition ? 'left' : 'right'].bottom;
        if (document.querySelector('#chatbot-meta-box #lbaic-single-chatbot')) {
            b += 10;
        }
        if (document.querySelector('#lbaic-admin-page-settings')) {
            b -= 8;
        }
        rightChatbotElement?.style.setProperty('--lbaic-b', `${b}px`);
        leftChatbotElement?.style.setProperty('--lbaic-b', `${b}px`);
    }

    // Apply chatbot positions (using viewport coordinates)
    // Right
    if (rightChatbotElement) {
        const r = chatbotFits ? window.innerWidth - adminPageRect.left - popupLeft - popupRect.width - POPUP_CHATBOT_GAP - (chatbotTriggerWidth || 60) : 32;
        rightChatbotElement.style.setProperty('--lbaic-r', `${r}px`);
        rightChatbotElement.style.setProperty('--lbaic-l', '');

        // Chatbot grid positioning for right: relative position from trigger
        // Grid appears to the left of trigger, so positive value means left offset
        if (chatbotGrid && chatbotRect.width > 0) {
            if (isLargeScreen) {
                const gridR = chatbotFits ? ((chatbotTriggerWidth || 60) - chatbotGridWidth) : 0;
                chatbotGrid.style.setProperty('--lbaic-grid-r', `${gridR}px`);
                chatbotGrid.style.setProperty('--lbaic-grid-l', '');
            } else {
                chatbotGrid.style.setProperty('--lbaic-grid-r', '0px');
                chatbotGrid.style.setProperty('--lbaic-grid-l', '');
            }
        }
    }
    // Left
    if (leftChatbotElement) {
        // Left positioned chatbot: --lbaic-l is distance from left edge of viewport
        const l = chatbotFits ? adminPageRect.left + (adminPageRect.width - totalWidth) / 2 : PARAMETERS.position.left.left - 8;
        leftChatbotElement.style.setProperty('--lbaic-l', `${l}px`);
        leftChatbotElement.style.setProperty('--lbaic-r', '');

        // Chatbot grid positioning for left: relative position from trigger
        // Grid appears to the left of trigger, so negative value means left offset
        if (chatbotGrid && chatbotRect.width > 0) {
            if (isLargeScreen) {
                chatbotGrid.style.setProperty('--lbaic-grid-l', `0px`);
                chatbotGrid.style.setProperty('--lbaic-grid-r', '');
            } else {
                chatbotGrid.style.setProperty('--lbaic-grid-l', '');
                chatbotGrid.style.setProperty('--lbaic-grid-r', '');
            }
        }
    }
};

export default function Onboarding({settings, onClose, userId, chatbotPreview, setChatbotPreview}) {
    const notifications = useContext(NotificationsContext);

    const [loading, setLoading] = useState(1);
    const [step, setStep] = useState(0);
    const [initialStep, setInitialStep] = useState(0);
    const [isTheStepReady, setIsTheStepReady] = useState(false);
    const [isTheStepDataReady, setIsTheStepDataReady] = useState({});
    const [isInitialStepDataReady, setIsInitialStepDataReady] = useState(false);
    const [collectingKnowledge, setCollectingKnowledge] = useState(false);
    const [completingOnboarding, setCompletingOnboarding] = useState(false);
    const [allProcessesDone, setAllProcessesDone] = useState(false);
    const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
    const [savingStep, setSavingStep] = useState(false);

    const [learnButton, setLearnButton] = useState(null);

    const [showChatbotPreview, setShowChatbotPreview] = useState(() => {
        const storedValue = localStorage.getItem(getChatbotPreviewStorageKey(userId));
        return storedValue === 'true' || storedValue === null;
    });

    // Memoize title and description to prevent unnecessary recalculations
    const title = useMemo(() => getTheStepTitle(step), [step]);
    const description = useMemo(() => getTheStepDescription(step), [step]);

    const [config, setConfig] = useState(null);

    const step1Ref = useRef(null);
    const step2Ref = useRef(null);
    const step3Ref = useRef(null);
    const isStep2Done = useRef(false);

    const processesStateRef = useRef(null);

    // Memoize computed values to prevent unnecessary recalculations
    const prevButtonDisabled = useMemo(() => {
        return loading > 0 || step <= 1 || collectingKnowledge || completingOnboarding;
    }, [loading, step, collectingKnowledge, completingOnboarding]);

    const nextButtonDisabled = useMemo(() => {
        // For steps 1 and 2, don't disable based on isTheStepReady - validation happens on click
        // For step 3, keep the existing behavior
        const stepReadyCheck = step === 3 ? !isTheStepReady : false;
        return loading > 0 || stepReadyCheck || (step === 3 ? !allProcessesDone : collectingKnowledge) || completingOnboarding;
    }, [loading, isTheStepReady, step, allProcessesDone, collectingKnowledge, completingOnboarding]);

    const isStepsButtonsDisabled = useMemo(() => {
        return loading > 0 || collectingKnowledge || completingOnboarding;
    }, [loading, collectingKnowledge, completingOnboarding]);

    useEffect(() => {
        checkOnboardingSettings(settings);
    }, [settings]);

    // Update allProcessesDone state when step changes
    useEffect(() => {
        if (step === 3) {
            setAllProcessesDone(areAllProcessesDone(processesStateRef));
        } else {
            setAllProcessesDone(true);
        }
    }, [step]);

    // Reset learnButton when navigating away from step 3
    useEffect(() => {
        if (step !== 3) {
            setLearnButton(null);
        }
    }, [step]);

    // Reset savingStep when step changes
    useEffect(() => {
        setSavingStep(false);
    }, [step]);

    // Handle positioning of popup and chatbot for onboarding
    useEffect(() => {
        if (!step || !isTheStepDataReady['step' + step]) {
            return;
        }

        if (!showChatbotPreview) {
            const popup = document.querySelector('.lbaic-settings-popup');
            if (popup) {
                // Reset popup applied styles
                popup.style.position = '';
                popup.style.left = '';
                popup.style.top = '';
                popup.style.marginLeft = '';
                popup.style.marginTop = '';
                popup.style.marginRight = '';
                popup.style.marginBottom = '';
            }

            return;
        }

        updateOnboardingPositions();
    }, [step, isTheStepDataReady, showChatbotPreview]);

    useEffect(() => {
        // Listen to chatbot size change WordPress hook to recalculate positions
        LimbChatbot.Hooks.addAction('lbaic.settings.chatbots.init', 'lbaic/settings/onboarding/chatbots-initialized', () => {
            window.requestAnimationFrame(updateOnboardingPositions)
        });

        // Also listen to window resize to update viewport-dependent values
        window.addEventListener('resize', updateOnboardingPositions);

        return () => {
            LimbChatbot.Hooks.removeAction('lbaic.settings.chatbots.init', 'lbaic/settings/onboarding/chatbots-initialized');
            window.removeEventListener('resize', updateOnboardingPositions);
        };
    }, []);

    /**
     * Check onboarding settings
     *
     * @return {Promise<void>}
     */
    const checkOnboardingSettings = async (data) => {
        if (!Array.isArray(data)) {
            handleError({
                message: "Invalid state of onboarding settings.",
                data,
            }, notifications.set, {
                title: __("Invalid state of onboarding settings.", 'limb-chatbot'),
                description: __("Please check and try again.", 'limb-chatbot'),
            });
            return;
        }
        setLoading(prev => prev + 1);
        // Processes state - must be an array, otherwise treat as empty
        const processesState = data.find(item => item.key === ONBOARDING_KEY_PREFIX + 'processes')?.value;

        // If processes state exists and is an array, use it; otherwise use empty array
        processesStateRef.current = Array.isArray(processesState) ? processesState : [];
        // Check config
        const configId = data.find(item => item.key === DEFAULT_CHATBOT_SETTINGS_KEY_PREFIX + 'config_id')?.value;
        if (configId) {
            // Get config
            let config;
            try {
                config = await GetConfig(LimbChatbot.rest.url, LimbChatbot.rest.nonce, configId);
            } catch (e) {
                handleError(e);
            }
            if (config?.id) {
                setConfig(config);
                // Check step 2 state
                const step2State = data.find(item => item.key === ONBOARDING_KEY_PREFIX + 'step_2.status')?.value;
                isStep2Done.current = step2State === 1;
                if (step2State !== 1) {
                    // Show step 2
                    setStep(2);
                    setInitialStep(2);
                } else {
                    // Show step 3
                    setStep(3);
                    setInitialStep(3);
                }
            } else {
                setStep(1);
                setInitialStep(1);
            }
        } else {
            setStep(1);
            setInitialStep(1);
        }
        setLoading(prev => prev - 2); // Since the loading from the very beginning is 1
    }

    /**
     * Go to step
     *
     * @param {number} newStep New step
     * @return {Promise<void>}
     */
    const goToStep = async (newStep) => {
        // Prev step
        if (step >= newStep && !prevButtonDisabled) {
            setIsTheStepReady(false);
            setIsTheStepDataReady(prev => ({...prev, ['step' + newStep]: false}));
            setHasUnsavedChanges(false);
            setStep(newStep);
            return;
        }
        // Next step
        if (nextButtonDisabled) {
            return;
        }
        setLoading(prev => prev + 1);

        // Go to next step
        let ref;
        switch (step) {
            case 1:
                ref = step1Ref.current;
                break;
            case 2:
                ref = step2Ref.current;
                break;
            case 3:
                ref = step3Ref.current;
                break;
            default:
                break;
        }

        // For steps 1 and 2, validate on click before proceeding
        if (step === 1) {
            // Step 1: validate using getData
            setSavingStep(true);
            if (typeof ref?.getData === 'function') {
                const data = await ref.getData();
                if (!data) {
                    // Validation failed, don't proceed
                    setSavingStep(false);
                    setLoading(prev => prev - 1);
                    return;
                }
                // Keep step data
                if (data.config?.id) {
                    setConfig(data?.config);
                }
            }
            setSavingStep(false);
        } else if (step === 2) {
            // Step 2: validate using beforeNextStep
            setSavingStep(true);
            if (typeof ref?.beforeNextStep === 'function') {
                if (!await ref.beforeNextStep()) {
                    // Validation failed, don't proceed
                    setSavingStep(false);
                    setLoading(prev => prev - 1);
                    return;
                }
                isStep2Done.current = true;
            }
            setSavingStep(false);
        } else {
            // Step 3: keep existing behavior (validation happens via isTheStepReady state)
            // Step 3 doesn't have beforeNextStep or getData methods, so no validation needed here
        }

        // When want to jump on some steps
        if (step === 1 && newStep > 2) {
            // If step 2 isn't done then go to the step 2
            if (!isStep2Done.current) {
                setHasUnsavedChanges(false);
                setStep(2);
                setIsTheStepReady(false);
                setIsTheStepDataReady(prev => ({...prev, step2: false}));
                setLoading(prev => prev - 1);
                return;
            }
        }
        // Go to the next step
        setIsTheStepDataReady(prev => ({...prev, ['step' + newStep]: false}));
        setIsTheStepReady(false);
        setHasUnsavedChanges(false);
        setStep(newStep);

        setLoading(prev => prev - 1);
    }

    /**
     * Close popup
     */
    const closePopup = useCallback(() => {
        onClose();
    }, [onClose]);

    /**
     * Complete onboarding the close
     *
     * @return {Promise<void>}
     */
    const completeOnboardingAndClose = useCallback(async (callback) => {
        setCompletingOnboarding(true);
        try {
            // Set onboarding status to complete
            await UpdateSetting(LimbChatbot.rest.url, LimbChatbot.rest.nonce, ONBOARDING_KEY_PREFIX + 'status', 'complete');

            // Close all notifications
            notifications.set(prevState => prevState.map(item => ({
                ...item,
                autoClose: true,
                timeout: NOTIF_QUICK_AUTOCLOSE_TIMEOUT
            })));

            // Callback before closing the popup
            if (typeof callback === 'function') {
                callback();
            }

            // Close the popup
            closePopup();

            // Launch confetti celebration after popup closes
            setTimeout(() => {
                launchConfetti(3);
            }, 100);
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to complete onboarding.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check and try again.", 'limb-chatbot'),
            });
        } finally {
            setCompletingOnboarding(false);
        }
    }, [notifications, closePopup]);

    /**
     * Discard changes for current step
     */
    const discardChanges = useCallback(() => {
        let ref;
        switch (step) {
            case 1:
                ref = step1Ref.current;
                break;
            case 2:
                ref = step2Ref.current;
                break;
            case 3:
                ref = step3Ref.current;
                break;
            default:
                return;
        }

        if (ref && typeof ref.discardChanges === 'function') {
            ref.discardChanges();
            // Reset hasUnsavedChanges after discarding
            setHasUnsavedChanges(false);
        }
    }, [step]);

    /**
     * Cancel onboarding
     *
     * @return {Promise<void>}
     */
    const cancelOnboarding = useCallback(async () => {
        if (collectingKnowledge) {
            if (!await confirm(__("Are you sure you want to cancel the learning process?", 'limb-chatbot'))) {
                return;
            }
        } else {
            if (!await confirm(__("Are you sure you want to cancel onboarding?", 'limb-chatbot'))) {
                return;
            }
        }
        // Check and stop processes if any
        setLoading(prev => prev + 1);
        if (step === 3) {
            if (typeof step3Ref.current?.checkAndStopProcesses === 'function') {
                if (!await step3Ref.current.checkAndStopProcesses()) {
                    setLoading(prev => prev - 1);
                    return;
                }
            }
        }
        // Update onboarding status
        try {
            await UpdateSetting(LimbChatbot.rest.url, LimbChatbot.rest.nonce, ONBOARDING_KEY_PREFIX + 'status', 'cancel');
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to cancel onboarding.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check and try again.", 'limb-chatbot'),
            });
        }
        setLoading(prev => prev - 1);
        // Close popup
        closePopup();
    }, [collectingKnowledge, step, notifications, closePopup]);

    const nextButton = learnButton || (
        <Button
            type="primary"
            label={step === STEPS[STEPS.length - 1].step
                ? (completingOnboarding ? __("Completing...", 'limb-chatbot') : __("Done", 'limb-chatbot'))
                : __("Next", 'limb-chatbot')
            }
            onClick={() => step === STEPS[STEPS.length - 1].step ? completeOnboardingAndClose() : goToStep(step + 1)}
            loading={savingStep}
            disabled={nextButtonDisabled}
        />
    );

    if (!step) {
        return null;
    }

    return (
        <>
            <PopupContainer
                title={title}
                description={description}
                loading={loading > 0}
                showLoadingContainer={!isTheStepDataReady['step' + step]}
                popupClassName='lbaic-settings-mp-popup'
                footer={
                    <div className='lbaic-settings-popup-footer-in'>
                        <Button
                            type="secondary"
                            label={__("Prev", 'limb-chatbot')}
                            onClick={() => goToStep(step - 1)}
                            disabled={prevButtonDisabled}
                        />
                        <div className={`lbaic-settings-steps${collectingKnowledge ? ' lbaic-settings-disabled' : ''}`}>
                            {STEPS.map((item) => (
                                <div key={item.step}
                                     className={`lbaic-settings-step${step === item.step ? ' active' : ''}${item.step < step ? ' done' : ''}`}
                                     onClick={() => !isStepsButtonsDisabled && item.step < step && goToStep(item.step)}>
                                    <span className='lbaic-settings-step-label'>{item.label}</span>
                                </div>))}
                        </div>
                        <div className="lbaic-settings-mp-popup-steps-actions">
                            {!collectingKnowledge && (
                                <Button
                                    type="secondary"
                                    label={__("Discard", 'limb-chatbot')}
                                    onClick={discardChanges}
                                    disabled={isStepsButtonsDisabled || !hasUnsavedChanges}
                                />
                            )}
                            {nextButton}
                        </div>
                    </div>
                }
                headerActions={
                    <button
                        className="lbaic-settings-popup-header-action"
                        onClick={cancelOnboarding}
                    >
                        <svg
                            className='lbaic-settings-popup-header-action-i'
                            xmlns='http://www.w3.org/2000/svg'
                            fill='none'
                            viewBox='0 0 24 24'
                        >
                            <use href='#lbaic-settings-close'/>
                        </svg>
                    </button>
                }
                checkChatbotPreviewPosition={false}
            >
                <div className="lbaic-settings-popup-wrapper">
                    {step === 1 && (
                        <Step1
                            ref={step1Ref}
                            config={config}
                            setIsReady={setIsTheStepReady}
                            setIsDataReady={(value) => {
                                setIsTheStepDataReady(prev => ({...prev, step1: value}));
                                if (!isInitialStepDataReady && initialStep === 1) {
                                    setIsInitialStepDataReady(value);
                                }
                            }}
                            setHasUnsavedChanges={setHasUnsavedChanges}
                            notifications={notifications}
                        />
                    )}
                    {step === 2 && (
                        <Step2
                            ref={step2Ref}
                            setIsReady={setIsTheStepReady}
                            setIsDataReady={(value) => {
                                setIsTheStepDataReady(prev => ({...prev, step2: value}));
                                if (!isInitialStepDataReady && initialStep === 2) {
                                    setIsInitialStepDataReady(value);
                                }
                            }}
                            setLoading={setLoading}
                            setHasUnsavedChanges={setHasUnsavedChanges}
                            notifications={notifications}
                            setChatbotPreview={setChatbotPreview}
                        />
                    )}
                    {step === 3 && (
                        <BackgroundProcessProvider notifications={notifications} pageSlug="onboarding">
                            <Step3
                                ref={step3Ref}
                                config={config}
                                processesStateRef={processesStateRef}
                                setIsReady={setIsTheStepReady}
                                setIsDataReady={(value) => {
                                    setIsTheStepDataReady(prev => ({...prev, step3: value}));
                                    if (!isInitialStepDataReady && initialStep === 3) {
                                        setIsInitialStepDataReady(value);
                                    }
                                }}
                                collecting={collectingKnowledge}
                                setCollecting={setCollectingKnowledge}
                                setLoading={setLoading}
                                setLearnButton={setLearnButton}
                                close={completeOnboardingAndClose}
                                setAllProcessesDone={setAllProcessesDone}
                                hasUnsavedChanges={hasUnsavedChanges}
                                setHasUnsavedChanges={setHasUnsavedChanges}
                                notifications={notifications}
                            />
                        </BackgroundProcessProvider>
                    )}
                </div>
            </PopupContainer>
            {/*Onboarding chatbot preview*/}
            {isInitialStepDataReady && (
                <ChatbotPreviewContext.Provider
                    value={chatbotPreview}
                >
                    <ChatbotPreview
                        open
                        userId={userId}
                        chatbotPreviewToggled={setShowChatbotPreview}
                    />
                </ChatbotPreviewContext.Provider>
            )}
        </>
    );
}