import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
/**
 * @license
 * Copyright 2026 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { beforeEach, afterEach, describe, it, expect, vi } from 'vitest';
import { render } from '../../test-utils/render.js';
import { Box, Text } from 'ink';
import { useEffect } from 'react';
import { Composer } from './Composer.js';
import { UIStateContext } from '../contexts/UIStateContext.js';
import { UIActionsContext, } from '../contexts/UIActionsContext.js';
import { ConfigContext } from '../contexts/ConfigContext.js';
import { SettingsContext } from '../contexts/SettingsContext.js';
import { createMockSettings } from '../../test-utils/settings.js';
// Mock VimModeContext hook
vi.mock('../contexts/VimModeContext.js', () => ({
    useVimMode: vi.fn(() => ({
        vimEnabled: false,
        vimMode: 'INSERT',
    })),
}));
import { ApprovalMode, tokenLimit, CoreToolCallStatus, } from '@google/gemini-cli-core';
import { StreamingState } from '../types.js';
import { TransientMessageType } from '../../utils/events.js';
const composerTestControls = vi.hoisted(() => ({
    suggestionsVisible: false,
    isAlternateBuffer: false,
}));
// Mock child components
vi.mock('./LoadingIndicator.js', () => ({
    LoadingIndicator: ({ thought, thoughtLabel, }) => {
        const fallbackText = typeof thought === 'string' ? thought : thought?.subject;
        const text = thoughtLabel ?? fallbackText;
        return _jsxs(Text, { children: ["LoadingIndicator", text ? `: ${text}` : ''] });
    },
}));
vi.mock('./StatusDisplay.js', () => ({
    StatusDisplay: () => _jsx(Text, { children: "StatusDisplay" }),
}));
vi.mock('./ToastDisplay.js', () => ({
    ToastDisplay: () => _jsx(Text, { children: "ToastDisplay" }),
    shouldShowToast: (uiState) => uiState.ctrlCPressedOnce ||
        Boolean(uiState.transientMessage) ||
        uiState.ctrlDPressedOnce ||
        (uiState.showEscapePrompt &&
            (uiState.buffer.text.length > 0 || uiState.history.length > 0)) ||
        Boolean(uiState.queueErrorMessage),
}));
vi.mock('./ContextSummaryDisplay.js', () => ({
    ContextSummaryDisplay: () => _jsx(Text, { children: "ContextSummaryDisplay" }),
}));
vi.mock('./HookStatusDisplay.js', () => ({
    HookStatusDisplay: () => _jsx(Text, { children: "HookStatusDisplay" }),
}));
vi.mock('./ApprovalModeIndicator.js', () => ({
    ApprovalModeIndicator: () => _jsx(Text, { children: "ApprovalModeIndicator" }),
}));
vi.mock('./ShellModeIndicator.js', () => ({
    ShellModeIndicator: () => _jsx(Text, { children: "ShellModeIndicator" }),
}));
vi.mock('./ShortcutsHint.js', () => ({
    ShortcutsHint: () => _jsx(Text, { children: "ShortcutsHint" }),
}));
vi.mock('./ShortcutsHelp.js', () => ({
    ShortcutsHelp: () => _jsx(Text, { children: "ShortcutsHelp" }),
}));
vi.mock('./DetailedMessagesDisplay.js', () => ({
    DetailedMessagesDisplay: () => _jsx(Text, { children: "DetailedMessagesDisplay" }),
}));
vi.mock('./InputPrompt.js', () => ({
    InputPrompt: ({ placeholder, onSuggestionsVisibilityChange, }) => {
        useEffect(() => {
            onSuggestionsVisibilityChange?.(composerTestControls.suggestionsVisible);
        }, [onSuggestionsVisibilityChange]);
        return _jsxs(Text, { children: ["InputPrompt: ", placeholder] });
    },
    calculatePromptWidths: vi.fn(() => ({
        inputWidth: 80,
        suggestionsWidth: 40,
        containerWidth: 84,
    })),
}));
vi.mock('../hooks/useAlternateBuffer.js', () => ({
    useAlternateBuffer: () => composerTestControls.isAlternateBuffer,
}));
vi.mock('./Footer.js', () => ({
    Footer: () => _jsx(Text, { children: "Footer" }),
}));
vi.mock('./ShowMoreLines.js', () => ({
    ShowMoreLines: () => _jsx(Text, { children: "ShowMoreLines" }),
}));
vi.mock('./QueuedMessageDisplay.js', () => ({
    QueuedMessageDisplay: ({ messageQueue }) => {
        if (messageQueue.length === 0) {
            return null;
        }
        return (_jsx(_Fragment, { children: messageQueue.map((message, index) => (_jsx(Text, { children: message }, index))) }));
    },
}));
// Mock contexts
vi.mock('../contexts/OverflowContext.js', () => ({
    OverflowProvider: ({ children }) => children,
}));
// Create mock context providers
const createMockUIState = (overrides = {}) => ({
    streamingState: StreamingState.Idle,
    isConfigInitialized: true,
    contextFileNames: [],
    showApprovalModeIndicator: ApprovalMode.DEFAULT,
    messageQueue: [],
    showErrorDetails: false,
    constrainHeight: false,
    isInputActive: true,
    buffer: { text: '' },
    inputWidth: 80,
    suggestionsWidth: 40,
    userMessages: [],
    slashCommands: [],
    commandContext: null,
    shellModeActive: false,
    isFocused: true,
    thought: '',
    currentLoadingPhrase: '',
    elapsedTime: 0,
    ctrlCPressedOnce: false,
    ctrlDPressedOnce: false,
    showEscapePrompt: false,
    shortcutsHelpVisible: false,
    cleanUiDetailsVisible: true,
    ideContextState: null,
    geminiMdFileCount: 0,
    renderMarkdown: true,
    filteredConsoleMessages: [],
    history: [],
    sessionStats: {
        sessionId: 'test-session',
        sessionStartTime: new Date(),
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        metrics: {},
        lastPromptTokenCount: 0,
        promptCount: 0,
    },
    branchName: 'main',
    debugMessage: '',
    corgiMode: false,
    errorCount: 0,
    nightly: false,
    isTrustedFolder: true,
    activeHooks: [],
    isBackgroundShellVisible: false,
    embeddedShellFocused: false,
    quota: {
        userTier: undefined,
        stats: undefined,
        proQuotaRequest: null,
        validationRequest: null,
    },
    ...overrides,
});
const createMockUIActions = () => ({
    handleFinalSubmit: vi.fn(),
    handleClearScreen: vi.fn(),
    setShellModeActive: vi.fn(),
    setCleanUiDetailsVisible: vi.fn(),
    toggleCleanUiDetailsVisible: vi.fn(),
    revealCleanUiDetailsTemporarily: vi.fn(),
    onEscapePromptChange: vi.fn(),
    vimHandleInput: vi.fn(),
    setShortcutsHelpVisible: vi.fn(),
});
const createMockConfig = (overrides = {}) => ({
    getModel: vi.fn(() => 'gemini-1.5-pro'),
    getTargetDir: vi.fn(() => '/test/dir'),
    getDebugMode: vi.fn(() => false),
    getAccessibility: vi.fn(() => ({})),
    getMcpServers: vi.fn(() => ({})),
    isPlanEnabled: vi.fn(() => false),
    getToolRegistry: () => ({
        getTool: vi.fn(),
    }),
    getSkillManager: () => ({
        getSkills: () => [],
        getDisplayableSkills: () => [],
    }),
    getMcpClientManager: () => ({
        getMcpServers: () => ({}),
        getBlockedMcpServers: () => [],
    }),
    ...overrides,
});
const renderComposer = async (uiState, settings = createMockSettings(), config = createMockConfig(), uiActions = createMockUIActions()) => {
    const result = render(_jsx(ConfigContext.Provider, { value: config, children: _jsx(SettingsContext.Provider, { value: settings, children: _jsx(UIStateContext.Provider, { value: uiState, children: _jsx(UIActionsContext.Provider, { value: uiActions, children: _jsx(Composer, {}) }) }) }) }));
    await result.waitUntilReady();
    return result;
};
describe('Composer', () => {
    beforeEach(() => {
        composerTestControls.suggestionsVisible = false;
        composerTestControls.isAlternateBuffer = false;
    });
    afterEach(() => {
        vi.restoreAllMocks();
    });
    describe('Footer Display Settings', () => {
        it('renders Footer by default when hideFooter is false', async () => {
            const uiState = createMockUIState();
            const settings = createMockSettings({ ui: { hideFooter: false } });
            const { lastFrame } = await renderComposer(uiState, settings);
            expect(lastFrame()).toContain('Footer');
        });
        it('does NOT render Footer when hideFooter is true', async () => {
            const uiState = createMockUIState();
            const settings = createMockSettings({ ui: { hideFooter: true } });
            const { lastFrame } = await renderComposer(uiState, settings);
            // Check for content that only appears IN the Footer component itself
            expect(lastFrame()).not.toContain('[NORMAL]'); // Vim mode indicator
            expect(lastFrame()).not.toContain('(main'); // Branch name with parentheses
        });
        it('passes correct props to Footer including vim mode when enabled', async () => {
            const uiState = createMockUIState({
                branchName: 'feature-branch',
                corgiMode: true,
                errorCount: 2,
                sessionStats: {
                    sessionId: 'test-session',
                    sessionStartTime: new Date(),
                    metrics: {
                        models: {},
                        tools: {},
                        files: {},
                    },
                    lastPromptTokenCount: 150,
                    promptCount: 5,
                },
            });
            const config = createMockConfig({
                getModel: vi.fn(() => 'gemini-1.5-flash'),
                getTargetDir: vi.fn(() => '/project/path'),
                getDebugMode: vi.fn(() => true),
            });
            const settings = createMockSettings({
                ui: {
                    hideFooter: false,
                    showMemoryUsage: true,
                },
            });
            // Mock vim mode for this test
            const { useVimMode } = await import('../contexts/VimModeContext.js');
            vi.mocked(useVimMode).mockReturnValueOnce({
                vimEnabled: true,
                vimMode: 'INSERT',
                toggleVimEnabled: vi.fn(),
                setVimMode: vi.fn(),
            });
            const { lastFrame } = await renderComposer(uiState, settings, config);
            expect(lastFrame()).toContain('Footer');
            // Footer should be rendered with all the state passed through
        });
    });
    describe('Loading Indicator', () => {
        it('renders LoadingIndicator with thought when streaming', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                thought: {
                    subject: 'Processing',
                    description: 'Processing your request...',
                },
                currentLoadingPhrase: 'Analyzing',
                elapsedTime: 1500,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('LoadingIndicator: Processing');
        });
        it('renders generic thinking text in loading indicator when full inline thinking is enabled', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                thought: {
                    subject: 'Detailed in-history thought',
                    description: 'Full text is already in history',
                },
            });
            const settings = createMockSettings({
                ui: { inlineThinkingMode: 'full' },
            });
            const { lastFrame } = await renderComposer(uiState, settings);
            const output = lastFrame();
            expect(output).toContain('LoadingIndicator: Thinking ...');
        });
        it('hides shortcuts hint while loading', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                elapsedTime: 1,
                cleanUiDetailsVisible: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('LoadingIndicator');
            expect(output).not.toContain('ShortcutsHint');
        });
        it('renders LoadingIndicator without thought when loadingPhrases is off', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                thought: { subject: 'Hidden', description: 'Should not show' },
            });
            const settings = createMockSettings({
                merged: { ui: { loadingPhrases: 'off' } },
            });
            const { lastFrame } = await renderComposer(uiState, settings);
            const output = lastFrame();
            expect(output).toContain('LoadingIndicator');
            expect(output).not.toContain('Should not show');
        });
        it('does not render LoadingIndicator when waiting for confirmation', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.WaitingForConfirmation,
                thought: {
                    subject: 'Confirmation',
                    description: 'Should not show during confirmation',
                },
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).not.toContain('LoadingIndicator');
        });
        it('does not render LoadingIndicator when a tool confirmation is pending', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                pendingHistoryItems: [
                    {
                        type: 'tool_group',
                        tools: [
                            {
                                callId: 'call-1',
                                name: 'edit',
                                description: 'edit file',
                                status: CoreToolCallStatus.AwaitingApproval,
                                resultDisplay: undefined,
                                confirmationDetails: undefined,
                            },
                        ],
                    },
                ],
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).not.toContain('LoadingIndicator');
            expect(output).not.toContain('esc to cancel');
        });
        it('renders LoadingIndicator when embedded shell is focused but background shell is visible', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                embeddedShellFocused: true,
                isBackgroundShellVisible: true,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('LoadingIndicator');
        });
        it('renders both LoadingIndicator and ApprovalModeIndicator when streaming in full UI mode', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                thought: {
                    subject: 'Thinking',
                    description: '',
                },
                showApprovalModeIndicator: ApprovalMode.PLAN,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('LoadingIndicator: Thinking');
            expect(output).toContain('ApprovalModeIndicator');
        });
        it('does NOT render LoadingIndicator when embedded shell is focused and background shell is NOT visible', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                embeddedShellFocused: true,
                isBackgroundShellVisible: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).not.toContain('LoadingIndicator');
        });
    });
    describe('Message Queue Display', () => {
        it('displays queued messages when present', async () => {
            const uiState = createMockUIState({
                messageQueue: [
                    'First queued message',
                    'Second queued message',
                    'Third queued message',
                ],
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('First queued message');
            expect(output).toContain('Second queued message');
            expect(output).toContain('Third queued message');
        });
        it('renders QueuedMessageDisplay with empty message queue', async () => {
            const uiState = createMockUIState({
                messageQueue: [],
            });
            const { lastFrame } = await renderComposer(uiState);
            // The component should render but return null for empty queue
            // This test verifies that the component receives the correct prop
            const output = lastFrame();
            expect(output).toContain('InputPrompt'); // Verify basic Composer rendering
        });
    });
    describe('Context and Status Display', () => {
        it('shows StatusDisplay and ApprovalModeIndicator in normal state', async () => {
            const uiState = createMockUIState({
                ctrlCPressedOnce: false,
                ctrlDPressedOnce: false,
                showEscapePrompt: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('StatusDisplay');
            expect(output).toContain('ApprovalModeIndicator');
            expect(output).not.toContain('ToastDisplay');
        });
        it('shows ToastDisplay and hides ApprovalModeIndicator when a toast is present', async () => {
            const uiState = createMockUIState({
                ctrlCPressedOnce: true,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('ToastDisplay');
            expect(output).not.toContain('ApprovalModeIndicator');
            expect(output).toContain('StatusDisplay');
        });
        it('shows ToastDisplay for other toast types', async () => {
            const uiState = createMockUIState({
                transientMessage: {
                    text: 'Warning',
                    type: TransientMessageType.Warning,
                },
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('ToastDisplay');
            expect(output).not.toContain('ApprovalModeIndicator');
        });
    });
    describe('Input and Indicators', () => {
        it('hides non-essential UI details in clean mode', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('ShortcutsHint');
            expect(output).toContain('InputPrompt');
            expect(output).not.toContain('Footer');
            expect(output).not.toContain('ApprovalModeIndicator');
            expect(output).not.toContain('ContextSummaryDisplay');
        });
        it('renders InputPrompt when input is active', async () => {
            const uiState = createMockUIState({
                isInputActive: true,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain('InputPrompt');
        });
        it('does not render InputPrompt when input is inactive', async () => {
            const uiState = createMockUIState({
                isInputActive: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('InputPrompt');
        });
        it.each([
            [ApprovalMode.DEFAULT],
            [ApprovalMode.AUTO_EDIT],
            [ApprovalMode.PLAN],
            [ApprovalMode.YOLO],
        ])('shows ApprovalModeIndicator when approval mode is %s and shell mode is inactive', async (mode) => {
            const uiState = createMockUIState({
                showApprovalModeIndicator: mode,
                shellModeActive: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toMatch(/ApprovalModeIndic[\s\S]*ator/);
        });
        it('shows ShellModeIndicator when shell mode is active', async () => {
            const uiState = createMockUIState({
                shellModeActive: true,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toMatch(/ShellModeIndic[\s\S]*tor/);
        });
        it('shows RawMarkdownIndicator when renderMarkdown is false', async () => {
            const uiState = createMockUIState({
                renderMarkdown: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain('raw markdown mode');
        });
        it('does not show RawMarkdownIndicator when renderMarkdown is true', async () => {
            const uiState = createMockUIState({
                renderMarkdown: true,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('raw markdown mode');
        });
        it.each([
            [ApprovalMode.YOLO, 'YOLO'],
            [ApprovalMode.PLAN, 'plan'],
            [ApprovalMode.AUTO_EDIT, 'auto edit'],
        ])('shows minimal mode badge "%s" when clean UI details are hidden', async (mode, label) => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                showApprovalModeIndicator: mode,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain(label);
        });
        it('hides minimal mode badge while loading in clean mode', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                streamingState: StreamingState.Responding,
                elapsedTime: 1,
                showApprovalModeIndicator: ApprovalMode.PLAN,
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('LoadingIndicator');
            expect(output).not.toContain('plan');
            expect(output).not.toContain('ShortcutsHint');
        });
        it('hides minimal mode badge while action-required state is active', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                showApprovalModeIndicator: ApprovalMode.PLAN,
                customDialog: (_jsx(Box, { children: _jsx(Text, { children: "Prompt" }) })),
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).not.toContain('plan');
            expect(output).not.toContain('ShortcutsHint');
        });
        it('shows Esc rewind prompt in minimal mode without showing full UI', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                showEscapePrompt: true,
                history: [{ id: 1, type: 'user', text: 'msg' }],
            });
            const { lastFrame } = await renderComposer(uiState);
            const output = lastFrame();
            expect(output).toContain('ToastDisplay');
            expect(output).not.toContain('ContextSummaryDisplay');
        });
        it('shows context usage bleed-through when over 60%', async () => {
            const model = 'gemini-2.5-pro';
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                currentModel: model,
                sessionStats: {
                    sessionId: 'test-session',
                    sessionStartTime: new Date(),
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    metrics: {},
                    lastPromptTokenCount: Math.floor(tokenLimit(model) * 0.7),
                    promptCount: 0,
                },
            });
            const settings = createMockSettings({
                ui: {
                    footer: { hideContextPercentage: false },
                },
            });
            const { lastFrame } = await renderComposer(uiState, settings);
            expect(lastFrame()).toContain('%');
        });
    });
    describe('Error Details Display', () => {
        it('shows DetailedMessagesDisplay when showErrorDetails is true', async () => {
            const uiState = createMockUIState({
                showErrorDetails: true,
                filteredConsoleMessages: [
                    {
                        type: 'error',
                        content: 'Test error',
                        count: 1,
                    },
                ],
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain('DetailedMessagesDisplay');
            expect(lastFrame()).toContain('ShowMoreLines');
        });
        it('does not show error details when showErrorDetails is false', async () => {
            const uiState = createMockUIState({
                showErrorDetails: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('DetailedMessagesDisplay');
        });
    });
    describe('Vim Mode Placeholders', () => {
        it('shows correct placeholder in INSERT mode', async () => {
            const uiState = createMockUIState({ isInputActive: true });
            const { useVimMode } = await import('../contexts/VimModeContext.js');
            vi.mocked(useVimMode).mockReturnValue({
                vimEnabled: true,
                vimMode: 'INSERT',
                toggleVimEnabled: vi.fn(),
                setVimMode: vi.fn(),
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain("InputPrompt:   Press 'Esc' for NORMAL mode.");
        });
        it('shows correct placeholder in NORMAL mode', async () => {
            const uiState = createMockUIState({ isInputActive: true });
            const { useVimMode } = await import('../contexts/VimModeContext.js');
            vi.mocked(useVimMode).mockReturnValue({
                vimEnabled: true,
                vimMode: 'NORMAL',
                toggleVimEnabled: vi.fn(),
                setVimMode: vi.fn(),
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain("InputPrompt:   Press 'i' for INSERT mode.");
        });
    });
    describe('Shortcuts Hint', () => {
        it('hides shortcuts hint when showShortcutsHint setting is false', async () => {
            const uiState = createMockUIState();
            const settings = createMockSettings({
                ui: {
                    showShortcutsHint: false,
                },
            });
            const { lastFrame } = await renderComposer(uiState, settings);
            expect(lastFrame()).not.toContain('ShortcutsHint');
        });
        it('hides shortcuts hint when a action is required (e.g. dialog is open)', async () => {
            const uiState = createMockUIState({
                customDialog: (_jsxs(Box, { children: [_jsx(Text, { children: "Test Dialog" }), _jsx(Text, { children: "Test Content" })] })),
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('ShortcutsHint');
        });
        it('keeps shortcuts hint visible when no action is required', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain('ShortcutsHint');
        });
        it('shows shortcuts hint when full UI details are visible', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: true,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain('ShortcutsHint');
        });
        it('hides shortcuts hint while loading in minimal mode', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                streamingState: StreamingState.Responding,
                elapsedTime: 1,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('ShortcutsHint');
        });
        it('shows shortcuts help in minimal mode when toggled on', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                shortcutsHelpVisible: true,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain('ShortcutsHelp');
        });
        it('hides shortcuts hint when suggestions are visible above input in alternate buffer', async () => {
            composerTestControls.isAlternateBuffer = true;
            composerTestControls.suggestionsVisible = true;
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                showApprovalModeIndicator: ApprovalMode.PLAN,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('ShortcutsHint');
            expect(lastFrame()).not.toContain('plan');
        });
        it('hides approval mode indicator when suggestions are visible above input in alternate buffer', async () => {
            composerTestControls.isAlternateBuffer = true;
            composerTestControls.suggestionsVisible = true;
            const uiState = createMockUIState({
                cleanUiDetailsVisible: true,
                showApprovalModeIndicator: ApprovalMode.YOLO,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('ApprovalModeIndicator');
        });
        it('keeps shortcuts hint when suggestions are visible below input in regular buffer', async () => {
            composerTestControls.isAlternateBuffer = false;
            composerTestControls.suggestionsVisible = true;
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain('ShortcutsHint');
        });
    });
    describe('Shortcuts Help', () => {
        it('shows shortcuts help in passive state', async () => {
            const uiState = createMockUIState({
                shortcutsHelpVisible: true,
                streamingState: StreamingState.Idle,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toContain('ShortcutsHelp');
        });
        it('hides shortcuts help while streaming', async () => {
            const uiState = createMockUIState({
                shortcutsHelpVisible: true,
                streamingState: StreamingState.Responding,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('ShortcutsHelp');
        });
        it('hides shortcuts help when action is required', async () => {
            const uiState = createMockUIState({
                shortcutsHelpVisible: true,
                customDialog: (_jsx(Box, { children: _jsx(Text, { children: "Dialog content" }) })),
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).not.toContain('ShortcutsHelp');
        });
    });
    describe('Snapshots', () => {
        it('matches snapshot in idle state', async () => {
            const uiState = createMockUIState();
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toMatchSnapshot();
        });
        it('matches snapshot while streaming', async () => {
            const uiState = createMockUIState({
                streamingState: StreamingState.Responding,
                thought: {
                    subject: 'Thinking',
                    description: 'Thinking about the meaning of life...',
                },
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toMatchSnapshot();
        });
        it('matches snapshot in narrow view', async () => {
            const uiState = createMockUIState({
                terminalWidth: 40,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toMatchSnapshot();
        });
        it('matches snapshot in minimal UI mode', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toMatchSnapshot();
        });
        it('matches snapshot in minimal UI mode while loading', async () => {
            const uiState = createMockUIState({
                cleanUiDetailsVisible: false,
                streamingState: StreamingState.Responding,
                elapsedTime: 1000,
            });
            const { lastFrame } = await renderComposer(uiState);
            expect(lastFrame()).toMatchSnapshot();
        });
    });
});
//# sourceMappingURL=Composer.test.js.map