from unittest.mock import patch
from openhands_cli.agent_chat import run_cli_entry
import pytest


@patch("openhands_cli.agent_chat.print_formatted_text")
@patch("openhands_cli.tui.settings.settings_screen.save_settings_confirmation")
@patch("openhands_cli.tui.settings.settings_screen.prompt_api_key")
@patch("openhands_cli.tui.settings.settings_screen.choose_llm_model")
@patch("openhands_cli.tui.settings.settings_screen.choose_llm_provider")
@patch("openhands_cli.tui.settings.settings_screen.settings_type_confirmation")
@patch("openhands_cli.tui.settings.store.AgentStore.load")
@pytest.mark.parametrize("interrupt_step", ["settings_type", "provider", "model", "api_key", "save"])
def test_first_time_users_can_escape_settings_flow_and_exit_app(
    mock_agentstore_load,
    mock_type,
    mock_provider,
    mock_model,
    mock_api_key,
    mock_save,
    mock_print,
    interrupt_step,
):
    """Test that KeyboardInterrupt is handled at each step of basic settings."""

    # Force first-time user: no saved agent
    mock_agentstore_load.return_value = None

    # Happy path defaults
    mock_type.return_value = "basic"
    mock_provider.return_value = "openai"
    mock_model.return_value = "gpt-4o-mini"
    mock_api_key.return_value = "sk-test"
    mock_save.return_value = True

    # Inject KeyboardInterrupt at the specified step
    if interrupt_step == "settings_type":
        mock_type.side_effect = KeyboardInterrupt()
    elif interrupt_step == "provider":
        mock_provider.side_effect = KeyboardInterrupt()
    elif interrupt_step == "model":
        mock_model.side_effect = KeyboardInterrupt()
    elif interrupt_step == "api_key":
        mock_api_key.side_effect = KeyboardInterrupt()
    elif interrupt_step == "save":
        mock_save.side_effect = KeyboardInterrupt()

    # Run
    run_cli_entry()

    # Assert graceful messaging
    calls = [call.args[0] for call in mock_print.call_args_list]
    assert any("Setup is required" in str(c) for c in calls)
    assert any("Goodbye!" in str(c) for c in calls)
