"""Tests for interactive prompts module."""

from unittest.mock import patch

from autodebug import prompts


class TestSelectErrorToDebug:
    """Test error selection prompt."""

    def test_returns_none_for_empty_list(self):
        """Test that empty error list returns None."""
        result = prompts.select_error_to_debug([])
        assert result is None

    @patch("autodebug.prompts.questionary.select")
    def test_creates_choices_from_errors(self, mock_select):
        """Test that choices are created from error list."""
        mock_select.return_value.ask.return_value = "err_123"

        errors = [
            {"id": "err_123", "exception_type": "KeyError", "message": "key not found", "count": 5},
            {"id": "err_456", "exception_type": "TypeError", "message": "invalid type", "count": 2},
        ]

        result = prompts.select_error_to_debug(errors)

        assert result == "err_123"
        mock_select.assert_called_once()
        # Verify the function was called with the question as first positional arg
        call_args = mock_select.call_args
        assert "Which error" in call_args[0][0]


class TestSelectMultipleErrors:
    """Test multiple error selection."""

    def test_returns_empty_for_no_errors(self):
        """Test returns empty list when no errors."""
        result = prompts.select_multiple_errors([])
        assert result == []

    @patch("questionary.checkbox")
    def test_returns_selected_ids(self, mock_checkbox):
        """Test returns selected error IDs."""
        mock_checkbox.return_value.ask.return_value = ["err_1", "err_2"]

        errors = [
            {"id": "err_1", "exception_type": "KeyError", "message": "msg1"},
            {"id": "err_2", "exception_type": "ValueError", "message": "msg2"},
            {"id": "err_3", "exception_type": "TypeError", "message": "msg3"},
        ]

        result = prompts.select_multiple_errors(errors)
        assert result == ["err_1", "err_2"]


class TestConfirmFixApplication:
    """Test fix confirmation prompt."""

    @patch("questionary.confirm")
    def test_returns_user_choice(self, mock_confirm):
        """Test returns user's confirmation choice."""
        mock_confirm.return_value.ask.return_value = True

        result = prompts.confirm_fix_application("--- a/file.py\n+++ b/file.py")
        assert result is True

    @patch("questionary.confirm")
    def test_returns_false_on_none(self, mock_confirm):
        """Test returns False when user cancels."""
        mock_confirm.return_value.ask.return_value = None

        result = prompts.confirm_fix_application("diff content")
        assert result is False


class TestSelectFixStrategy:
    """Test fix strategy selection."""

    @patch("questionary.select")
    def test_returns_selected_strategy(self, mock_select):
        """Test returns the selected strategy."""
        mock_select.return_value.ask.return_value = "fix_code"

        result = prompts.select_fix_strategy()
        assert result == "fix_code"

    @patch("questionary.select")
    def test_returns_auto_on_none(self, mock_select):
        """Test returns 'auto' when user cancels."""
        mock_select.return_value.ask.return_value = None

        result = prompts.select_fix_strategy()
        assert result == "auto"


class TestConfirmPRCreation:
    """Test PR creation confirmation."""

    @patch("questionary.confirm")
    def test_includes_title_and_branch(self, mock_confirm):
        """Test prompt includes PR title and branch."""
        mock_confirm.return_value.ask.return_value = True

        prompts.confirm_pr_creation("Fix KeyError", "fix/key-error")

        mock_confirm.assert_called_once()


class TestSelectEnvironment:
    """Test environment selection."""

    @patch("questionary.select")
    def test_includes_all_environments_option(self, mock_select):
        """Test includes 'All environments' option."""
        mock_select.return_value.ask.return_value = None

        prompts.select_environment()

        mock_select.assert_called_once()
        call_args = mock_select.call_args
        choices = call_args[1].get("choices", call_args[0][1] if len(call_args[0]) > 1 else [])
        # Just verify it was called - actual choices are implementation detail


class TestSelectTimeRange:
    """Test time range selection."""

    @patch("questionary.select")
    def test_returns_selected_range(self, mock_select):
        """Test returns selected time range."""
        mock_select.return_value.ask.return_value = "7d"

        result = prompts.select_time_range()
        assert result == "7d"

    @patch("questionary.select")
    def test_defaults_to_24h(self, mock_select):
        """Test defaults to 24h on cancel."""
        mock_select.return_value.ask.return_value = None

        result = prompts.select_time_range()
        assert result == "24h"


class TestSelectModel:
    """Test model selection."""

    @patch("questionary.select")
    def test_returns_selected_model(self, mock_select):
        """Test returns selected model."""
        mock_select.return_value.ask.return_value = "anthropic:claude-sonnet-4"

        result = prompts.select_model()
        assert result == "anthropic:claude-sonnet-4"

    @patch("questionary.select")
    def test_defaults_to_gpt5(self, mock_select):
        """Test defaults to gpt-5 on cancel."""
        mock_select.return_value.ask.return_value = None

        result = prompts.select_model()
        assert result == "openai:gpt-5"


class TestConfirmAction:
    """Test generic confirmation."""

    @patch("questionary.confirm")
    def test_passes_message_and_default(self, mock_confirm):
        """Test passes message and default to confirm."""
        mock_confirm.return_value.ask.return_value = True

        result = prompts.confirm_action("Continue?", default=True)

        assert result is True
        mock_confirm.assert_called_once()


class TestSelectDebugAction:
    """Test debug action selection."""

    @patch("questionary.select")
    def test_returns_selected_action(self, mock_select):
        """Test returns selected debug action."""
        mock_select.return_value.ask.return_value = "replay"

        result = prompts.select_debug_action()
        assert result == "replay"

    @patch("questionary.select")
    def test_defaults_to_exit(self, mock_select):
        """Test defaults to exit on cancel."""
        mock_select.return_value.ask.return_value = None

        result = prompts.select_debug_action()
        assert result == "exit"


class TestInputText:
    """Test text input."""

    @patch("questionary.text")
    def test_returns_user_input(self, mock_text):
        """Test returns user input."""
        mock_text.return_value.ask.return_value = "user entered text"

        result = prompts.input_text("Enter something:")
        assert result == "user entered text"

    @patch("questionary.text")
    def test_returns_default_on_cancel(self, mock_text):
        """Test returns default on cancel."""
        mock_text.return_value.ask.return_value = None

        result = prompts.input_text("Enter something:", default="default value")
        assert result == "default value"


class TestInputPassword:
    """Test password input."""

    @patch("questionary.password")
    def test_returns_password(self, mock_password):
        """Test returns entered password."""
        mock_password.return_value.ask.return_value = "secret123"

        result = prompts.input_password()
        assert result == "secret123"

    @patch("questionary.password")
    def test_returns_empty_on_cancel(self, mock_password):
        """Test returns empty string on cancel."""
        mock_password.return_value.ask.return_value = None

        result = prompts.input_password()
        assert result == ""
