(function () {
    window.AgentFrontendModules = window.AgentFrontendModules || {};

    window.AgentFrontendModules.createSessionStateModule = function createSessionStateModule(deps) {
        const SESSION_PERSIST_KEY = 'ao_active_session_id';

        function isHistoryRunId(runId) {
            return String(runId || '').startsWith('hist_');
        }

        function persistSession(id) {
            try {
                if (id) {
                    sessionStorage.setItem(SESSION_PERSIST_KEY, String(id));
                    localStorage.removeItem(SESSION_PERSIST_KEY);
                } else {
                    sessionStorage.removeItem(SESSION_PERSIST_KEY);
                    localStorage.removeItem(SESSION_PERSIST_KEY);
                }
            } catch (_) {}
        }

        function restoreSession() {
            try {
                const saved = sessionStorage.getItem(SESSION_PERSIST_KEY);
                localStorage.removeItem(SESSION_PERSIST_KEY);
                if (saved) {
                    deps.state.setCurrentSessionId(saved);
                    deps.state.setPreferredConversationSessionId(saved);
                }
            } catch (_) {}
        }

        function parseComposerInput(rawText) {
            const raw = String(rawText || '').trim();
            if (!raw) return { mode: 'run', text: '' };
            if (/^chat\s*:/i.test(raw)) return { mode: 'run', text: raw.replace(/^chat\s*:\s*/i, '').trim() };
            if (/^run\s*:/i.test(raw)) return { mode: 'run', text: raw.replace(/^run\s*:\s*/i, '').trim() };
            return { mode: 'run', text: raw };
        }

        function refreshComposerModeUi() {
            if (!deps.refs.goalModeHint) return;
            if (deps.state.getModelsLoading() && deps.state.getAvailableModels().length === 0) {
                deps.refs.goalModeHint.textContent = 'One moment — spinning up all systems…';
                deps.refs.goalModeHint.classList.add('is-models-loading');
                return;
            }
            deps.refs.goalModeHint.innerHTML = '';
            deps.refs.goalModeHint.classList.remove('is-models-loading');
        }

        function setChatSessionPill(sessionId) {
            if (!deps.refs.chatSessionPill) return;
            if (!sessionId) {
                deps.refs.chatSessionPill.textContent = 'No active chat session';
                return;
            }
            deps.refs.chatSessionPill.textContent = `Session ${String(sessionId).slice(0, 8)}`;
        }

        function sessionIdForRun(runId) {
            const targetRunId = String(runId || '').trim();
            if (!targetRunId) return '';
            const runs = deps.state.getRuns();
            const pendingRunSessionIds = deps.state.getPendingRunSessionIds();
            if (runs.has(targetRunId)) {
                return String(runs.get(targetRunId)?._sessionId || '').trim();
            }
            return String(pendingRunSessionIds.get(targetRunId) || '').trim();
        }

        function bindConversationSession(sessionId, runId = '', syncGlobal = true) {
            const nextSessionId = String(sessionId || '').trim();
            const targetRunId = String(runId || '').trim();
            const runs = deps.state.getRuns();
            const pendingRunSessionIds = deps.state.getPendingRunSessionIds();

            if (targetRunId) {
                if (runs.has(targetRunId)) {
                    runs.get(targetRunId)._sessionId = nextSessionId || null;
                } else if (nextSessionId) {
                    pendingRunSessionIds.set(targetRunId, nextSessionId);
                } else {
                    pendingRunSessionIds.delete(targetRunId);
                }
            }

            if (!nextSessionId || !syncGlobal) return nextSessionId;

            deps.state.setPendingSessionBootstrap(false);
            deps.state.setFreshChatRequested(false);
            deps.state.setCurrentSessionId(nextSessionId);
            deps.state.setPreferredConversationSessionId(nextSessionId);
            persistSession(nextSessionId);
            setChatSessionPill(nextSessionId);

            const queuedBootstrapFollowUps = deps.state.getQueuedBootstrapFollowUps();
            if (queuedBootstrapFollowUps.length > 0) {
                setTimeout(() => {
                    const currentSessionId = deps.state.getCurrentSessionId();
                    const preferredConversationSessionId = deps.state.getPreferredConversationSessionId();
                    const ws = deps.state.getWs();
                    const targetSessionId = String(currentSessionId || preferredConversationSessionId || '').trim();
                    if (!targetSessionId || !ws || ws.readyState !== WebSocket.OPEN || deps.state.getQueuedBootstrapFollowUps().length === 0) {
                        return;
                    }

                    let targetChatRunId = deps.helpers.findRunIdBySessionId(targetSessionId, false);
                    if (targetChatRunId && !deps.state.getRuns().has(targetChatRunId)) {
                        targetChatRunId = deps.helpers.ensureChatLane(targetSessionId);
                    } else if (targetChatRunId && deps.state.getRuns().has(targetChatRunId)) {
                        deps.helpers.setActiveRun(targetChatRunId);
                    }

                    const queued = deps.state.getQueuedBootstrapFollowUps().slice();
                    deps.state.setQueuedBootstrapFollowUps([]);
                    queued.forEach((item) => {
                        ws.send(JSON.stringify({
                            action: 'chat',
                            session_id: targetSessionId,
                            run_id: targetChatRunId,
                            model: item.model,
                            message: item.goal,
                            context: item.context,
                        }));
                    });
                }, 0);
            }
            return nextSessionId;
        }

        function enqueueAnonymousSessionId(sessionId) {
            const nextSessionId = String(sessionId || '').trim();
            if (!nextSessionId) return '';
            const pendingAnonymousSessionIds = deps.state.getPendingAnonymousSessionIds();
            if (pendingAnonymousSessionIds[pendingAnonymousSessionIds.length - 1] !== nextSessionId) {
                pendingAnonymousSessionIds.push(nextSessionId);
            }
            return nextSessionId;
        }

        function takeAnonymousSessionId() {
            const pendingAnonymousSessionIds = deps.state.getPendingAnonymousSessionIds();
            while (pendingAnonymousSessionIds.length > 0) {
                const nextSessionId = String(pendingAnonymousSessionIds.shift() || '').trim();
                if (nextSessionId) return nextSessionId;
            }
            return '';
        }

        function composerPreferredSessionId() {
            return String(deps.state.getCurrentSessionId() || deps.state.getPreferredConversationSessionId() || '').trim();
        }

        function findBindableLiveRunId() {
            const runs = deps.state.getRuns();
            const candidates = [deps.state.getCurrentHandlingRunId(), deps.state.getActiveRunId()];
            for (const candidate of candidates) {
                const runId = String(candidate || '').trim();
                if (!runId || !runs.has(runId) || isHistoryRunId(runId)) continue;
                if (sessionIdForRun(runId)) continue;
                return runId;
            }
            return '';
        }

        return {
            persistSession,
            restoreSession,
            parseComposerInput,
            refreshComposerModeUi,
            setChatSessionPill,
            sessionIdForRun,
            bindConversationSession,
            enqueueAnonymousSessionId,
            takeAnonymousSessionId,
            composerPreferredSessionId,
            findBindableLiveRunId,
        };
    };
})();