"""
Unit tests for help text system.
"""
import pytest
from unittest.mock import patch

from terminal_client.help_text import (
    HelpFormatter,
    get_help_text,
    show_help,
    HELP_DATA
)


class TestHelpData:
    """Tests for help data structure."""

    def test_all_commands_have_help(self):
        """Test that all major commands have help data."""
        required_commands = [
            'new_game', 'defensive', 'offensive', 'resolve',
            'quick_play', 'status', 'use_game', 'list_games'
        ]

        for cmd in required_commands:
            assert cmd in HELP_DATA, f"Missing help data for {cmd}"

    def test_help_data_structure(self):
        """Test that help data has required fields."""
        for cmd, data in HELP_DATA.items():
            assert 'summary' in data, f"{cmd} missing summary"
            assert 'usage' in data, f"{cmd} missing usage"
            assert 'options' in data, f"{cmd} missing options"
            assert 'examples' in data, f"{cmd} missing examples"

            # Validate options structure
            for opt in data['options']:
                assert 'name' in opt, f"{cmd} option missing name"
                assert 'desc' in opt, f"{cmd} option missing desc"

    def test_help_data_has_examples(self):
        """Test that all commands have at least one example."""
        for cmd, data in HELP_DATA.items():
            assert len(data['examples']) > 0, f"{cmd} has no examples"

    def test_get_help_text_valid(self):
        """Test getting help text for valid command."""
        result = get_help_text('new_game')
        assert result is not None
        assert 'summary' in result
        assert 'usage' in result

    def test_get_help_text_invalid(self):
        """Test getting help text for invalid command."""
        result = get_help_text('nonexistent_command')
        assert result == {}


class TestHelpFormatter:
    """Tests for HelpFormatter."""

    @patch('terminal_client.help_text.console')
    def test_show_command_help(self, mock_console):
        """Test showing help for a command."""
        help_data = {
            'summary': 'Test command',
            'usage': 'test [OPTIONS]',
            'options': [
                {'name': '--option', 'type': 'STRING', 'desc': 'Test option'}
            ],
            'examples': ['test --option value']
        }

        HelpFormatter.show_command_help('test', help_data)

        # Verify console.print was called
        assert mock_console.print.called
        assert mock_console.print.call_count >= 3  # Panel, options header, table, examples

    @patch('terminal_client.help_text.console')
    def test_show_command_help_with_notes(self, mock_console):
        """Test showing help with notes field."""
        help_data = {
            'summary': 'Test command',
            'usage': 'test',
            'options': [],
            'examples': ['test'],
            'notes': 'This is a test note'
        }

        HelpFormatter.show_command_help('test', help_data)

        # Verify console.print was called
        assert mock_console.print.called

    @patch('terminal_client.help_text.console')
    def test_show_command_list(self, mock_console):
        """Test showing command list."""
        HelpFormatter.show_command_list()

        # Verify console.print was called multiple times
        # Should have: header, game management section, gameplay section, utilities section
        assert mock_console.print.call_count > 5


class TestShowHelp:
    """Tests for show_help function."""

    @patch('terminal_client.help_text.HelpFormatter.show_command_help')
    def test_show_help_specific_command(self, mock_show):
        """Test showing help for specific command."""
        show_help('new_game')

        mock_show.assert_called_once()
        args = mock_show.call_args[0]
        assert args[0] == 'new_game'
        assert 'summary' in args[1]

    @patch('terminal_client.help_text.HelpFormatter.show_command_list')
    def test_show_help_no_command(self, mock_list):
        """Test showing command list when no command specified."""
        show_help()

        mock_list.assert_called_once()

    @patch('terminal_client.help_text.console')
    def test_show_help_invalid_command(self, mock_console):
        """Test showing help for invalid command."""
        show_help('invalid_command')

        # Should print warning message
        assert mock_console.print.called
        call_args = str(mock_console.print.call_args_list)
        assert 'No help available' in call_args


class TestSpecificCommandHelp:
    """Tests for specific command help data."""

    def test_new_game_help_complete(self):
        """Test new_game help has all expected fields."""
        data = get_help_text('new_game')
        assert data['summary']
        assert data['usage']
        assert len(data['options']) == 3  # --league, --home-team, --away-team
        assert len(data['examples']) >= 2

    def test_defensive_help_complete(self):
        """Test defensive help has all expected fields."""
        data = get_help_text('defensive')
        assert data['summary']
        assert data['usage']
        assert len(data['options']) == 4  # --alignment, --infield, --outfield, --hold
        assert len(data['examples']) >= 3

    def test_offensive_help_complete(self):
        """Test offensive help has all expected fields."""
        data = get_help_text('offensive')
        assert data['summary']
        assert data['usage']
        assert len(data['options']) == 4  # --approach, --steal, --hit-run, --bunt
        assert len(data['examples']) >= 3

    def test_resolve_help_has_notes(self):
        """Test resolve help includes notes about requirements."""
        data = get_help_text('resolve')
        assert 'notes' in data
        assert 'Both defensive and offensive decisions' in data['notes']

    def test_quick_play_help_complete(self):
        """Test quick_play help has all expected fields."""
        data = get_help_text('quick_play')
        assert data['summary']
        assert data['usage']
        assert len(data['options']) == 1  # COUNT
        assert len(data['examples']) >= 3

    def test_use_game_help_mentions_tab_completion(self):
        """Test use_game help mentions tab completion."""
        data = get_help_text('use_game')
        examples = '\n'.join(data['examples'])
        assert 'TAB' in examples or 'tab' in examples.lower()
