import { jsx as _jsx } from "react/jsx-runtime";
/**
 * @license
 * Copyright 2025 Vybestack LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { render as inkRender } from 'ink-testing-library';
import React, { act, createContext, useContext } from 'react';
import { LoadedSettings } from '../config/settings.js';
import { KeypressProvider } from '../ui/contexts/KeypressContext.js';
import { SettingsContext } from '../ui/contexts/SettingsContext.js';
import { UIStateContext } from '../ui/contexts/UIStateContext.js';
import { StreamingState } from '../ui/types.js';
// Wrapper around ink-testing-library's render that ensures act() is called
// This fixes React 18+ warnings about state updates not being wrapped in act()
export const render = (tree) => {
    let renderResult = undefined;
    act(() => {
        renderResult = inkRender(tree);
    });
    const originalUnmount = renderResult.unmount;
    const originalRerender = renderResult.rerender;
    return {
        ...renderResult,
        unmount: () => {
            act(() => {
                originalUnmount();
            });
        },
        rerender: (newTree) => {
            act(() => {
                originalRerender(newTree);
            });
        },
    };
};
const mockSettings = new LoadedSettings({ path: '', settings: {} }, { path: '', settings: {} }, { path: '', settings: { ui: { useAlternateBuffer: true } } }, { path: '', settings: {} }, true);
export const createMockSettings = (overrides) => {
    const settings = overrides;
    return new LoadedSettings({ path: '', settings: {} }, { path: '', settings: {} }, { path: '', settings }, { path: '', settings: {} }, true);
};
// A minimal mock UIState to satisfy the context provider.
// Tests that need specific UIState values should provide their own.
const baseMockUiState = {
    streamingState: StreamingState.Idle,
    mainAreaWidth: 100,
    terminalWidth: 120,
    terminalBackgroundColor: undefined,
};
const mockRuntimeApi = {
    getEphemeralSetting: () => true, // Default to showing thinking blocks
    switchActiveProvider: async () => { },
    listProviders: () => [],
    getActiveProviderName: () => 'mock-provider',
    setActiveModel: async () => { },
    listAvailableModels: () => [],
    getActiveModelName: () => 'mock-model',
    getActiveProviderStatus: () => ({ status: 'ready' }),
    getActiveModelParams: () => ({}),
    getEphemeralSettings: () => ({}),
    setEphemeralSetting: () => { },
    setActiveModelParam: () => { },
    clearActiveModelParam: () => { },
    saveProfileSnapshot: async () => { },
    saveLoadBalancerProfile: async () => { },
    loadProfileByName: async () => { },
    deleteProfileByName: async () => { },
    listSavedProfiles: () => [],
    setDefaultProfileName: () => { },
    updateActiveProviderApiKey: async () => { },
    updateActiveProviderBaseUrl: async () => { },
    setActiveToolFormatOverride: () => { },
    getActiveToolFormatState: () => ({ format: 'default', isOverridden: false }),
    getActiveProviderMetrics: () => ({}),
    getRuntimeDiagnosticsSnapshot: () => ({}),
    registerCliProviderInfrastructure: () => { },
    getCliProviderManager: () => null,
    getCliOAuthManager: () => null,
    getCliRuntimeServices: () => null,
    getSessionTokenUsage: () => ({ inputTokens: 0, outputTokens: 0 }),
    getLoadBalancerStats: () => null,
    getLoadBalancerLastSelected: () => null,
    getAllLoadBalancerStats: () => [],
};
const mockRuntimeBridge = {
    runtimeId: 'test-runtime',
    metadata: {},
    api: mockRuntimeApi,
    runWithScope: function runWithScope(callback) {
        return callback();
    },
    enterScope: () => { },
};
const MockRuntimeContext = createContext(mockRuntimeBridge);
// Mock RuntimeContextProvider for tests
const MockRuntimeContextProvider = ({ children, }) => (_jsx(MockRuntimeContext.Provider, { value: mockRuntimeBridge, children: children }));
// Export mock hooks that tests can use
export const useMockRuntimeApi = () => {
    const context = useContext(MockRuntimeContext);
    if (!context) {
        throw new Error('MockRuntimeContext not found');
    }
    return context.api;
};
export const renderWithProviders = (component, { settings = mockSettings, uiState = baseMockUiState, } = {}) => render(_jsx(SettingsContext.Provider, { value: settings, children: _jsx(UIStateContext.Provider, { value: uiState, children: _jsx(MockRuntimeContextProvider, { children: _jsx(KeypressProvider, { children: component }) }) }) }));
export function renderHook(hook, options) {
    const result = { current: undefined };
    function TestComponent({ hookProps }) {
        result.current = hook(hookProps);
        return null;
    }
    const Wrapper = options?.wrapper ?? React.Fragment;
    let root;
    act(() => {
        root = render(React.createElement(Wrapper, null, React.createElement(TestComponent, {
            hookProps: options?.initialProps,
        })));
    });
    return {
        result,
        rerender: (props) => {
            act(() => {
                root.rerender(React.createElement(Wrapper, null, React.createElement(TestComponent, { hookProps: props })));
            });
        },
        unmount: () => {
            act(() => {
                root.unmount();
            });
        },
    };
}
export function cleanup() {
    // ink-testing-library manages its own cleanup
    // This is a no-op for compatibility
}
// Simple waitFor implementation - polls until callback succeeds or timeout
export const waitFor = async (callback, options) => {
    const timeout = options?.timeout ?? 1000;
    const interval = options?.interval ?? 50;
    const start = Date.now();
    while (Date.now() - start < timeout) {
        try {
            await callback();
            return;
        }
        catch {
            await new Promise((resolve) => setTimeout(resolve, interval));
        }
    }
    // Final attempt - let it throw if it fails
    await callback();
};
//# sourceMappingURL=render.js.map