import { jsx as _jsx } from "react/jsx-runtime";
/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
/**
 *
 *
 * This test suite covers:
 * - Initial rendering and display state
 * - Keyboard navigation (arrows, vim keys, Tab)
 * - Settings toggling (Enter, Space)
 * - Focus section switching between settings and scope selector
 * - Scope selection and settings persistence across scopes
 * - Restart-required vs immediate settings behavior
 * - VimModeContext integration
 * - Complex user interaction workflows
 * - Error handling and edge cases
 * - Display values for inherited and overridden settings
 *
 */
import { render } from 'ink-testing-library';
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { SettingsDialog } from './SettingsDialog.js';
import { LoadedSettings, SettingScope } from '../../config/settings.js';
import { VimModeProvider } from '../contexts/VimModeContext.js';
import { KeypressProvider } from '../contexts/KeypressContext.js';
import { act } from 'react';
import { getDialogSettingKeys, getSettingDefinition, saveModifiedSettings, TEST_ONLY, } from '../../utils/settingsUtils.js';
import { OUTPUT_LANGUAGE_AUTO } from '../../utils/languageUtils.js';
// Mock the VimModeContext
const mockToggleVimEnabled = vi.fn();
const mockSetVimMode = vi.fn();
// Mock the CompactModeContext
const mockSetCompactMode = vi.fn();
// Mock the UIActionsContext
const mockRefreshStatic = vi.fn();
var TerminalKeys;
(function (TerminalKeys) {
    TerminalKeys["ENTER"] = "\r";
    TerminalKeys["TAB"] = "\t";
    TerminalKeys["UP_ARROW"] = "\u001B[A";
    TerminalKeys["DOWN_ARROW"] = "\u001B[B";
    TerminalKeys["LEFT_ARROW"] = "\u001B[D";
    TerminalKeys["RIGHT_ARROW"] = "\u001B[C";
    TerminalKeys["ESCAPE"] = "\u001B";
})(TerminalKeys || (TerminalKeys = {}));
const createMockSettings = (userSettings = {}, systemSettings = {}, workspaceSettings = {}) => new LoadedSettings({
    settings: { ui: { customThemes: {} }, mcpServers: {}, ...systemSettings },
    originalSettings: {
        ui: { customThemes: {} },
        mcpServers: {},
        ...systemSettings,
    },
    path: '/system/settings.json',
}, {
    settings: {},
    originalSettings: {},
    path: '/system/system-defaults.json',
}, {
    settings: {
        ui: { customThemes: {} },
        mcpServers: {},
        ...userSettings,
    },
    originalSettings: {
        ui: { customThemes: {} },
        mcpServers: {},
        ...userSettings,
    },
    path: '/user/settings.json',
}, {
    settings: {
        ui: { customThemes: {} },
        mcpServers: {},
        ...workspaceSettings,
    },
    originalSettings: {
        ui: { customThemes: {} },
        mcpServers: {},
        ...workspaceSettings,
    },
    path: '/workspace/settings.json',
}, true, new Set());
vi.mock('../../config/settingsSchema.js', async (importOriginal) => {
    const original = await importOriginal();
    return {
        ...original,
        getSettingsSchema: vi.fn(original.getSettingsSchema),
    };
});
vi.mock('../contexts/VimModeContext.js', async () => {
    const actual = await vi.importActual('../contexts/VimModeContext.js');
    return {
        ...actual,
        useVimMode: () => ({
            vimEnabled: false,
            vimMode: 'INSERT',
            toggleVimEnabled: mockToggleVimEnabled,
            setVimMode: mockSetVimMode,
        }),
    };
});
vi.mock('../contexts/CompactModeContext.js', async () => {
    const actual = await vi.importActual('../contexts/CompactModeContext.js');
    return {
        ...actual,
        useCompactMode: () => ({
            compactMode: false,
            setCompactMode: mockSetCompactMode,
        }),
    };
});
vi.mock('../contexts/UIActionsContext.js', async () => {
    const actual = await vi.importActual('../contexts/UIActionsContext.js');
    return {
        ...actual,
        useUIActions: () => ({
            refreshStatic: mockRefreshStatic,
        }),
    };
});
vi.mock('../../utils/settingsUtils.js', async () => {
    const actual = await vi.importActual('../../utils/settingsUtils.js');
    return {
        ...actual,
        saveModifiedSettings: vi.fn(),
    };
});
vi.mock('../../utils/languageUtils.js', async () => {
    const actual = await vi.importActual('../../utils/languageUtils.js');
    return {
        ...actual,
        updateOutputLanguageFile: vi.fn(),
    };
});
// Helper function to simulate key presses (commented out for now)
// const simulateKeyPress = async (keyData: Partial<Key> & { name: string }) => {
//   if (currentKeypressHandler) {
//     const key: Key = {
//       ctrl: false,
//       meta: false,
//       shift: false,
//       paste: false,
//       sequence: keyData.sequence || keyData.name,
//       ...keyData,
//     };
//     currentKeypressHandler(key);
//     // Allow React to process the state update
//     await new Promise(resolve => setTimeout(resolve, 10));
//   }
// };
// Mock console.log to avoid noise in tests
// const originalConsoleLog = console.log;
// const originalConsoleError = console.error;
describe('SettingsDialog', () => {
    // Simple delay function for remaining tests that need gradual migration
    const wait = (ms = 50) => new Promise((resolve) => setTimeout(resolve, ms));
    // Custom waitFor utility for ink testing environment (not compatible with @testing-library/react)
    const waitFor = async (predicate, options = {}) => {
        const { timeout = 1000, interval = 10 } = options;
        const start = Date.now();
        let lastError;
        while (Date.now() - start < timeout) {
            try {
                predicate();
                return;
            }
            catch (e) {
                lastError = e;
            }
            await new Promise((resolve) => setTimeout(resolve, interval));
        }
        if (lastError) {
            throw lastError;
        }
        throw new Error('waitFor timed out');
    };
    beforeEach(() => {
        // Reset keypress mock state (variables are commented out)
        // currentKeypressHandler = null;
        // isKeypressActive = false;
        // console.log = vi.fn();
        // console.error = vi.fn();
        mockToggleVimEnabled.mockResolvedValue(true);
    });
    afterEach(() => {
        TEST_ONLY.clearFlattenedSchema();
        vi.clearAllMocks();
        vi.resetAllMocks();
        // Reset keypress mock state (variables are commented out)
        // currentKeypressHandler = null;
        // isKeypressActive = false;
        // console.log = originalConsoleLog;
        // console.error = originalConsoleError;
    });
    describe('Initial Rendering', () => {
        it('should render the settings dialog with default state', () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            const output = lastFrame();
            expect(output).toContain('Settings');
            // Scope selector is now in a separate view (Tab to switch)
            expect(output).not.toContain('Apply To');
            expect(output).toContain('(Use Enter to select, Tab to configure scope)');
        });
        it('should accept availableTerminalHeight prop without errors', () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect, availableTerminalHeight: 20 }) }));
            const output = lastFrame();
            // Should still render properly with the height prop
            expect(output).toContain('Settings');
            expect(output).toContain('Enter to select');
        });
        it('should show settings list with default values', () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            const output = lastFrame();
            // Should show some default settings
            expect(output).toContain('●'); // Active indicator
        });
        it('should highlight first setting by default', () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            const output = lastFrame();
            // First item should be highlighted with green color and active indicator
            expect(output).toContain('●');
        });
    });
    describe('Settings Navigation', () => {
        it('should navigate down with arrow key', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount, lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Press down arrow
            act(() => {
                stdin.write(TerminalKeys.DOWN_ARROW); // Down arrow
            });
            const secondKey = getDialogSettingKeys()[1];
            expect(secondKey).toBeDefined();
            const secondLabel = secondKey
                ? (getSettingDefinition(secondKey)?.label ?? secondKey)
                : '';
            expect(lastFrame()).toContain(`● ${secondLabel}`);
            // The active index should have changed (tested indirectly through behavior)
            unmount();
        });
        it('should navigate up with arrow key', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // First go down, then up
            stdin.write(TerminalKeys.DOWN_ARROW); // Down arrow
            await wait();
            stdin.write(TerminalKeys.UP_ARROW);
            await wait();
            unmount();
        });
        it('should navigate with vim keys (j/k)', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Navigate with vim keys
            stdin.write('j'); // Down
            await wait();
            stdin.write('k'); // Up
            await wait();
            unmount();
        });
        it('wraps around when at the top of the list', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount, lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Try to go up from first item
            act(() => {
                stdin.write(TerminalKeys.UP_ARROW);
            });
            await wait();
            const lastKey = getDialogSettingKeys().at(-1);
            expect(lastKey).toBeDefined();
            const lastLabel = lastKey
                ? (getSettingDefinition(lastKey)?.label ?? lastKey)
                : '';
            expect(lastFrame()).toContain(`● ${lastLabel}`);
            unmount();
        });
    });
    describe('Settings Toggling', () => {
        it('should toggle setting with Enter key', async () => {
            vi.mocked(saveModifiedSettings).mockClear();
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const component = (_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            const { stdin, unmount, lastFrame } = render(component);
            // Wait for initial render and verify we're on Tool Approval Mode (first setting)
            await waitFor(() => {
                expect(lastFrame()).toContain('● Tool Approval Mode');
            });
            const dialogKeys = getDialogSettingKeys();
            const targetIndex = dialogKeys.indexOf('general.vimMode');
            expect(targetIndex).toBeGreaterThan(0);
            // Navigate to Vim Mode setting and verify we're there
            for (let i = 0; i < targetIndex; i++) {
                act(() => {
                    stdin.write(TerminalKeys.DOWN_ARROW);
                });
                await wait();
            }
            await waitFor(() => {
                expect(lastFrame()).toContain('● Vim Mode');
            });
            // Toggle the setting
            act(() => {
                stdin.write(TerminalKeys.ENTER);
            });
            // Wait for the setting change to be processed
            await waitFor(() => {
                expect(vi.mocked(saveModifiedSettings).mock.calls.length).toBeGreaterThan(0);
            });
            // Wait for the mock to be called
            await waitFor(() => {
                expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
            });
            expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalledWith(new Set(['general.vimMode']), {
                general: {
                    vimMode: true,
                },
            }, expect.any(LoadedSettings), SettingScope.User);
            unmount();
        });
        it('should sync compact mode with CompactModeContext when toggled', async () => {
            vi.mocked(saveModifiedSettings).mockClear();
            mockSetCompactMode.mockClear();
            mockRefreshStatic.mockClear();
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const component = (_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            const { stdin, unmount, lastFrame } = render(component);
            await waitFor(() => {
                expect(lastFrame()).toContain('● Tool Approval Mode');
            });
            const dialogKeys = getDialogSettingKeys();
            const targetIndex = dialogKeys.indexOf('ui.compactMode');
            expect(targetIndex).toBeGreaterThan(0);
            // Navigate to Compact Mode setting
            for (let i = 0; i < targetIndex; i++) {
                act(() => {
                    stdin.write(TerminalKeys.DOWN_ARROW);
                });
                await wait();
            }
            await waitFor(() => {
                expect(lastFrame()).toContain('● Compact Mode');
            });
            // Toggle the setting
            act(() => {
                stdin.write(TerminalKeys.ENTER);
            });
            await waitFor(() => {
                expect(vi.mocked(saveModifiedSettings).mock.calls.length).toBeGreaterThan(0);
            });
            // Verify compact mode context was synced
            expect(mockSetCompactMode).toHaveBeenCalledWith(true);
            // Verify refreshStatic was called to update rendered history
            expect(mockRefreshStatic).toHaveBeenCalled();
            unmount();
        });
        describe('enum values', () => {
            it('toggles enum values with the enter key', async () => {
                vi.mocked(saveModifiedSettings).mockClear();
                // Use real schema - first setting "Tool Approval Mode" is an enum
                const settings = createMockSettings();
                const onSelect = vi.fn();
                const component = (_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
                const { stdin, unmount, lastFrame } = render(component);
                // Verify we're on Tool Approval Mode (first setting, an enum)
                await waitFor(() => {
                    expect(lastFrame()).toContain('● Tool Approval Mode');
                });
                // Press Enter to cycle the enum value
                act(() => {
                    stdin.write(TerminalKeys.ENTER);
                });
                await wait();
                await waitFor(() => {
                    expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
                });
                // Tool Approval Mode cycles through enum values
                expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalledWith(new Set(['tools.approvalMode']), expect.objectContaining({
                    tools: expect.objectContaining({
                        approvalMode: expect.any(String),
                    }),
                }), expect.any(LoadedSettings), SettingScope.User);
                unmount();
            });
            it('loops back when reaching the end of an enum', async () => {
                vi.mocked(saveModifiedSettings).mockClear();
                // Use Tool Approval Mode set to YOLO (last value) to test looping back to first
                const settings = createMockSettings({
                    tools: {
                        approvalMode: 'yolo', // Last enum value
                    },
                });
                const onSelect = vi.fn();
                const component = (_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
                const { stdin, unmount, lastFrame } = render(component);
                // Verify we're on Tool Approval Mode (first setting)
                await waitFor(() => {
                    expect(lastFrame()).toContain('● Tool Approval Mode');
                });
                // Press Enter to cycle - should loop back to first value (Plan)
                act(() => {
                    stdin.write(TerminalKeys.ENTER);
                });
                await wait();
                await waitFor(() => {
                    expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
                });
                // Should loop back to first enum value (Plan)
                expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalledWith(new Set(['tools.approvalMode']), expect.objectContaining({
                    tools: expect.objectContaining({
                        approvalMode: 'plan', // First enum value after YOLO
                    }),
                }), expect.any(LoadedSettings), SettingScope.User);
                unmount();
            });
        });
        it('should toggle setting with Space key', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Press Space to toggle current setting
            stdin.write(' '); // Space key
            await wait();
            unmount();
        });
        it('should handle vim mode setting specially', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Navigate to vim mode setting and toggle it
            // This would require knowing the exact position, so we'll just test that the mock is called
            stdin.write(TerminalKeys.ENTER); // Enter key
            await wait();
            // The mock should potentially be called if vim mode was toggled
            unmount();
        });
    });
    describe('Scope Selection', () => {
        it('should switch between scopes', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Switch to scope focus
            stdin.write(TerminalKeys.TAB); // Tab key
            await wait();
            // Select different scope (numbers 1-3 typically available)
            stdin.write('2'); // Select second scope option
            await wait();
            unmount();
        });
        it('should reset to settings focus when scope is selected', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Wait for initial render
            await waitFor(() => {
                expect(lastFrame()).toContain('Tool Approval Mode');
            });
            // The UI should show settings mode is active (scope is in separate view)
            expect(lastFrame()).toContain('● Tool Approval Mode'); // Settings section active
            expect(lastFrame()).not.toContain('Apply To'); // Scope is in a separate view
            // This test validates the initial state - scope selection is now
            // accessed via Tab key, not shown alongside settings
            unmount();
        });
    });
    describe('Restart Prompt', () => {
        it('should show restart prompt for restart-required settings', async () => {
            const settings = createMockSettings();
            const onRestartRequest = vi.fn();
            const { unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: () => { }, onRestartRequest: onRestartRequest }) }));
            // This test would need to trigger a restart-required setting change
            // The exact steps depend on which settings require restart
            await wait();
            unmount();
        });
        it('should handle restart request when r is pressed', async () => {
            const settings = createMockSettings();
            const onRestartRequest = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: () => { }, onRestartRequest: onRestartRequest }) }));
            // Press 'r' key (this would only work if restart prompt is showing)
            stdin.write('r');
            await wait();
            // If restart prompt was showing, onRestartRequest should be called
            unmount();
        });
    });
    describe('Escape Key Behavior', () => {
        it('should call onSelect with undefined when Escape is pressed', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Wait for initial render
            await waitFor(() => {
                expect(lastFrame()).toContain('Tool Approval Mode');
            });
            // Verify the dialog is rendered properly (scope is in separate view)
            expect(lastFrame()).toContain('Settings');
            expect(lastFrame()).not.toContain('Apply To'); // Scope is in a separate view
            // This test validates rendering - escape key behavior depends on complex
            // keypress handling that's difficult to test reliably in this environment
            unmount();
        });
    });
    describe('Settings Persistence', () => {
        it('should persist settings across scope changes', async () => {
            const settings = createMockSettings({ vimMode: true });
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Switch to scope selector
            stdin.write(TerminalKeys.TAB); // Tab
            await wait();
            // Change scope
            stdin.write('2'); // Select workspace scope
            await wait();
            // Settings should be reloaded for new scope
            unmount();
        });
        it('should show different values for different scopes', () => {
            const settings = createMockSettings({ vimMode: true }, // User settings
            { vimMode: false }, // System settings
            { autoUpdate: false });
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Should show user scope values initially
            const output = lastFrame();
            expect(output).toContain('Settings');
        });
    });
    describe('Error Handling', () => {
        it('should handle vim mode toggle errors gracefully', async () => {
            mockToggleVimEnabled.mockRejectedValue(new Error('Toggle failed'));
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Try to toggle a setting (this might trigger vim mode toggle)
            stdin.write(TerminalKeys.ENTER); // Enter
            await wait();
            // Should not crash
            unmount();
        });
    });
    describe('Complex State Management', () => {
        it('should track modified settings correctly', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Toggle a setting
            stdin.write(TerminalKeys.ENTER); // Enter
            await wait();
            // Toggle another setting
            stdin.write(TerminalKeys.DOWN_ARROW); // Down
            await wait();
            stdin.write(TerminalKeys.ENTER); // Enter
            await wait();
            // Should track multiple modified settings
            unmount();
        });
        it('should handle scrolling when there are many settings', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Navigate down many times to test scrolling
            for (let i = 0; i < 10; i++) {
                stdin.write(TerminalKeys.DOWN_ARROW); // Down arrow
                await wait(10);
            }
            unmount();
        });
    });
    describe('VimMode Integration', () => {
        it('should sync with VimModeContext when vim mode is toggled', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(VimModeProvider, { settings: settings, children: _jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }) }));
            // Navigate to and toggle vim mode setting
            // This would require knowing the exact position of vim mode setting
            stdin.write(TerminalKeys.ENTER); // Enter
            await wait();
            unmount();
        });
    });
    describe('Specific Settings Behavior', () => {
        it('should show correct display values for settings with different states', () => {
            const settings = createMockSettings({ vimMode: true, hideTips: false }, // User settings
            { hideWindowTitle: true }, // System settings
            { ideMode: false });
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            const output = lastFrame();
            // Should contain settings labels
            expect(output).toContain('Settings');
        });
        it('should handle immediate settings save for non-restart-required settings', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Toggle a non-restart-required setting (like hideTips)
            stdin.write(TerminalKeys.ENTER); // Enter - toggle current setting
            await wait();
            // Should save immediately without showing restart prompt
            unmount();
        });
        it('should show restart prompt for restart-required settings', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // This test would need to navigate to a specific restart-required setting
            // Since we can't easily target specific settings, we test the general behavior
            await wait();
            // Should not show restart prompt initially
            expect(lastFrame()).not.toContain('To see changes, HopCode must be restarted');
            unmount();
        });
        it('should keep restart prompt when switching scopes', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, lastFrame, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            await waitFor(() => {
                expect(lastFrame()).toContain('Tool Approval Mode');
            });
            const languageIndex = getDialogSettingKeys().indexOf('general.language');
            expect(languageIndex).toBeGreaterThanOrEqual(0);
            const press = async (key) => {
                act(() => {
                    stdin.write(key);
                });
                await wait();
            };
            // Trigger a restart-required setting change by toggling the UI language setting.
            for (let i = 0; i < languageIndex; i++) {
                await press(TerminalKeys.DOWN_ARROW);
            }
            await press(TerminalKeys.ENTER);
            await waitFor(() => {
                expect(lastFrame()).toContain('To see changes, HopCode must be restarted');
            });
            // Switch scopes; restart prompt should remain visible.
            await press(TerminalKeys.TAB);
            await press('2');
            await waitFor(() => {
                expect(lastFrame()).toContain('To see changes, HopCode must be restarted');
            });
            unmount();
        });
    });
    describe('Settings Display Values', () => {
        it('should show correct values for inherited settings', () => {
            const settings = createMockSettings({}, { vimMode: true, hideWindowTitle: false }, // System settings
            {});
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            const output = lastFrame();
            // Settings should show inherited values
            expect(output).toContain('Settings');
        });
        it('should show override indicator for overridden settings', () => {
            const settings = createMockSettings({ vimMode: false }, // User overrides
            { vimMode: true }, // System default
            {});
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            const output = lastFrame();
            // Should show settings with override indicators
            expect(output).toContain('Settings');
        });
    });
    describe('Output Language', () => {
        it('treats empty output language as auto', async () => {
            const settings = createMockSettings({
                general: { outputLanguage: 'en' },
            });
            const { stdin, unmount, lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: () => { } }) }));
            await waitFor(() => {
                expect(lastFrame()).toContain('Settings');
            });
            // Navigate to the output language setting, start editing, then commit empty.
            // Avoid hard-coding the item index because schema-driven ordering can differ by platform.
            const outputLanguageIndex = getDialogSettingKeys().indexOf('general.outputLanguage');
            expect(outputLanguageIndex).toBeGreaterThanOrEqual(0);
            const press = async (key) => {
                act(() => {
                    stdin.write(key);
                });
                await wait();
            };
            for (let i = 0; i < outputLanguageIndex; i++) {
                await press(TerminalKeys.DOWN_ARROW);
            }
            await press(TerminalKeys.ENTER);
            await press(TerminalKeys.ENTER);
            // Empty input should set 'auto' in settings (rule file is updated on restart)
            await waitFor(() => {
                const outputLanguageCall = vi
                    .mocked(saveModifiedSettings)
                    .mock.calls.find((call) => call[0].has('general.outputLanguage'));
                expect(outputLanguageCall).toBeTruthy();
            });
            const outputLanguageCall = vi
                .mocked(saveModifiedSettings)
                .mock.calls.find((call) => call[0].has('general.outputLanguage'));
            // Should save 'auto' to settings
            expect(outputLanguageCall?.[1]).toMatchObject({
                general: { outputLanguage: OUTPUT_LANGUAGE_AUTO },
            });
            unmount();
        });
    });
    describe('Keyboard Shortcuts Edge Cases', () => {
        it('should handle rapid key presses gracefully', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Rapid navigation
            for (let i = 0; i < 5; i++) {
                stdin.write(TerminalKeys.DOWN_ARROW);
                stdin.write(TerminalKeys.UP_ARROW);
            }
            await wait(100);
            // Should not crash
            unmount();
        });
        it('should handle Ctrl+C to reset current setting to default', async () => {
            const settings = createMockSettings({ vimMode: true }); // Start with vimMode enabled
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Press Ctrl+C to reset current setting to default
            stdin.write('\u0003'); // Ctrl+C
            await wait();
            // Should reset the current setting to its default value
            unmount();
        });
        it('should handle Ctrl+L to reset current setting to default', async () => {
            const settings = createMockSettings({ vimMode: true }); // Start with vimMode enabled
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Press Ctrl+L to reset current setting to default
            stdin.write('\u000C'); // Ctrl+L
            await wait();
            // Should reset the current setting to its default value
            unmount();
        });
        it('should handle navigation when only one setting exists', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Try to navigate when potentially at bounds
            stdin.write(TerminalKeys.DOWN_ARROW);
            await wait();
            stdin.write(TerminalKeys.UP_ARROW);
            await wait();
            unmount();
        });
        it('should properly handle Tab navigation between sections', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Wait for initial render
            await waitFor(() => {
                expect(lastFrame()).toContain('Tool Approval Mode');
            });
            // Verify initial state: settings mode active (scope is in separate view)
            expect(lastFrame()).toContain('● Tool Approval Mode'); // Settings mode active
            expect(lastFrame()).not.toContain('Apply To'); // Scope is in a separate view
            // This test validates the rendered UI structure for tab navigation
            // Tab now switches between settings view and scope view
            unmount();
        });
    });
    describe('Error Recovery', () => {
        it('should handle malformed settings gracefully', () => {
            // Create settings with potentially problematic values
            const settings = createMockSettings({ vimMode: null }, // Invalid value
            {}, {});
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Should still render without crashing
            expect(lastFrame()).toContain('Settings');
        });
        it('should handle missing setting definitions gracefully', () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            // Should not crash even if some settings are missing definitions
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            expect(lastFrame()).toContain('Settings');
        });
    });
    describe('Complex User Interactions', () => {
        it('should handle complete user workflow: navigate, toggle, change scope, exit', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Wait for initial render
            await waitFor(() => {
                expect(lastFrame()).toContain('Tool Approval Mode');
            });
            // Verify the complete UI is rendered (scope is in separate view)
            expect(lastFrame()).toContain('Settings'); // Title
            expect(lastFrame()).toContain('● Tool Approval Mode'); // Active setting
            expect(lastFrame()).not.toContain('Apply To'); // Scope is in a separate view (Tab to access)
            expect(lastFrame()).toContain('(Use Enter to select, Tab to configure scope)'); // Help text
            // This test validates the complete UI structure is available for user workflow
            // Scope selection is now accessed via Tab key (view switching like ThemeDialog)
            unmount();
        });
        it('should allow changing multiple settings without losing pending changes', async () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Toggle first setting (should require restart)
            stdin.write(TerminalKeys.ENTER); // Enter
            await wait();
            // Navigate to next setting and toggle it (should not require restart - e.g., vimMode)
            stdin.write(TerminalKeys.DOWN_ARROW); // Down
            await wait();
            stdin.write(TerminalKeys.ENTER); // Enter
            await wait();
            // Navigate to another setting and toggle it (should also require restart)
            stdin.write(TerminalKeys.DOWN_ARROW); // Down
            await wait();
            stdin.write(TerminalKeys.ENTER); // Enter
            await wait();
            // The test verifies that all changes are preserved and the dialog still works
            // This tests the fix for the bug where changing one setting would reset all pending changes
            unmount();
        });
        it('should maintain state consistency during complex interactions', async () => {
            const settings = createMockSettings({ vimMode: true });
            const onSelect = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Multiple scope changes
            stdin.write(TerminalKeys.TAB); // Tab to scope
            await wait();
            stdin.write('2'); // Workspace
            await wait();
            stdin.write(TerminalKeys.TAB); // Tab to settings
            await wait();
            stdin.write(TerminalKeys.TAB); // Tab to scope
            await wait();
            stdin.write('1'); // User
            await wait();
            // Should maintain consistent state
            unmount();
        });
        it('should handle restart workflow correctly', async () => {
            const settings = createMockSettings();
            const onRestartRequest = vi.fn();
            const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: () => { }, onRestartRequest: onRestartRequest }) }));
            // This would test the restart workflow if we could trigger it
            stdin.write('r'); // Try restart key
            await wait();
            // Without restart prompt showing, this should have no effect
            expect(onRestartRequest).not.toHaveBeenCalled();
            unmount();
        });
    });
    describe('String Settings Editing', () => {
        it('should allow editing and committing a string setting', async () => {
            let settings = createMockSettings({ 'a.string.setting': 'initial' });
            const onSelect = vi.fn();
            const { stdin, unmount, rerender } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Wait for the dialog to render
            await wait();
            // Navigate to the last setting
            for (let i = 0; i < 20; i++) {
                stdin.write('j'); // Down
                await wait(10);
            }
            // Press Enter to start editing
            stdin.write('\r');
            await wait();
            // Type a new value
            stdin.write('new value');
            await wait();
            // Press Enter to commit
            stdin.write('\r');
            await wait();
            settings = createMockSettings({ 'a.string.setting': 'new value' }, {}, {});
            rerender(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            await wait();
            // Press Escape to exit
            stdin.write('\u001B');
            await wait();
            expect(onSelect).toHaveBeenCalledWith(undefined, 'User');
            unmount();
        });
    });
    describe('Snapshot Tests', () => {
        /**
         * Snapshot tests for SettingsDialog component using ink-testing-library.
         * These tests capture the visual output of the component in various states:
         *
         * - Default rendering with no custom settings
         * - Various combinations of boolean settings (enabled/disabled)
         * - Mixed boolean and number settings configurations
         * - Different focus states (settings vs scope selector)
         * - Different scope selections (User, System, Workspace)
         * - Accessibility settings enabled
         * - File filtering configurations
         * - Tools and security settings
         * - All settings disabled state
         *
         * The snapshots help ensure UI consistency and catch unintended visual changes.
         */
        it('should render default state correctly', () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render with various boolean settings enabled', () => {
            const settings = createMockSettings({
                general: {
                    vimMode: true,
                    disableAutoUpdate: true,
                    debugKeystrokeLogging: true,
                },
                ui: {
                    hideWindowTitle: true,
                    hideTips: true,
                    showLineNumbers: true,
                    showCitations: true,
                    accessibility: {
                        disableLoadingPhrases: true,
                        screenReader: true,
                    },
                },
                ide: {
                    enabled: true,
                },
                context: {
                    loadFromIncludeDirectories: true,
                    fileFiltering: {
                        respectGitIgnore: true,
                        respectHopCodeIgnore: true,
                        enableRecursiveFileSearch: true,
                        disableFuzzySearch: false,
                    },
                },
                tools: {
                    enableInteractiveShell: true,
                    autoAccept: true,
                    useRipgrep: true,
                },
                security: {
                    folderTrust: {
                        enabled: true,
                    },
                },
            });
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render with mixed boolean and number settings', () => {
            const settings = createMockSettings({
                general: {
                    vimMode: false,
                    disableAutoUpdate: true,
                },
                ui: {
                    hideWindowTitle: false,
                },
                tools: {
                    truncateToolOutputThreshold: 50000,
                    truncateToolOutputLines: 1000,
                },
                context: {},
                model: {
                    maxSessionTurns: 100,
                    skipNextSpeakerCheck: false,
                },
            });
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render focused on scope selector', () => {
            const settings = createMockSettings();
            const onSelect = vi.fn();
            const { lastFrame, stdin } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Switch focus to scope selector with Tab
            stdin.write('\t');
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render with different scope selected (System)', () => {
            const settings = createMockSettings({}, // userSettings
            {
                // systemSettings
                general: {
                    vimMode: true,
                    disableAutoUpdate: false,
                },
                ui: {},
            });
            const onSelect = vi.fn();
            const { lastFrame, stdin } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Switch to scope selector
            stdin.write('\t');
            // Navigate to System scope
            stdin.write('ArrowDown');
            stdin.write('\r'); // Enter to select
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render with different scope selected (Workspace)', () => {
            const settings = createMockSettings({}, // userSettings
            {}, // systemSettings
            {
                // workspaceSettings
                general: {
                    vimMode: false,
                    debugKeystrokeLogging: true,
                },
                tools: {
                    useRipgrep: true,
                    enableInteractiveShell: false,
                },
            });
            const onSelect = vi.fn();
            const { lastFrame, stdin } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            // Switch to scope selector
            stdin.write('\t');
            // Navigate to Workspace scope (down twice)
            stdin.write('ArrowDown');
            stdin.write('ArrowDown');
            stdin.write('\r'); // Enter to select
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render with accessibility settings enabled', () => {
            const settings = createMockSettings({
                ui: {
                    accessibility: {
                        disableLoadingPhrases: true,
                        screenReader: true,
                    },
                    showLineNumbers: true,
                },
                general: {
                    vimMode: true,
                },
            });
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render with file filtering settings configured', () => {
            const settings = createMockSettings({
                context: {
                    fileFiltering: {
                        respectGitIgnore: false,
                        respectHopCodeIgnore: true,
                        enableRecursiveFileSearch: false,
                        disableFuzzySearch: true,
                    },
                    loadFromIncludeDirectories: true,
                },
            });
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render with tools and security settings', () => {
            const settings = createMockSettings({
                tools: {
                    enableInteractiveShell: true,
                    autoAccept: false,
                    useRipgrep: true,
                    truncateToolOutputThreshold: 25000,
                    truncateToolOutputLines: 500,
                },
                security: {
                    folderTrust: {
                        enabled: true,
                    },
                },
                model: {
                    maxSessionTurns: 50,
                    skipNextSpeakerCheck: true,
                },
            });
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            expect(lastFrame()).toMatchSnapshot();
        });
        it('should render with all boolean settings disabled', () => {
            const settings = createMockSettings({
                general: {
                    vimMode: false,
                    disableAutoUpdate: false,
                    debugKeystrokeLogging: false,
                },
                ui: {
                    hideWindowTitle: false,
                    hideTips: false,
                    showLineNumbers: false,
                    showCitations: false,
                    accessibility: {
                        disableLoadingPhrases: false,
                        screenReader: false,
                    },
                },
                ide: {
                    enabled: false,
                },
                context: {
                    loadFromIncludeDirectories: false,
                    fileFiltering: {
                        respectGitIgnore: false,
                        respectHopCodeIgnore: false,
                        enableRecursiveFileSearch: false,
                        disableFuzzySearch: false,
                    },
                },
                tools: {
                    enableInteractiveShell: false,
                    autoAccept: false,
                    useRipgrep: false,
                },
                security: {
                    folderTrust: {
                        enabled: false,
                    },
                },
            });
            const onSelect = vi.fn();
            const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
            expect(lastFrame()).toMatchSnapshot();
        });
    });
});
//# sourceMappingURL=SettingsDialog.test.js.map