"""
Rich display formatting for game state.

Provides formatted console output using the Rich library.

Author: Claude
Date: 2025-10-26
"""
import logging
from typing import Optional
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.text import Text
from rich import box

from app.models.game_models import GameState, DefensiveDecision, OffensiveDecision
from app.core.play_resolver import PlayResult

logger = logging.getLogger(f'{__name__}.display')
console = Console()


def display_game_state(state: GameState) -> None:
    """
    Display current game state in formatted panel.

    Args:
        state: Current game state
    """
    # Status color based on game status
    status_color = {
        "pending": "yellow",
        "active": "green",
        "paused": "yellow",
        "completed": "blue"
    }

    # Build state display
    state_text = Text()
    state_text.append(f"Game ID: {state.game_id}\n", style="bold")
    state_text.append(f"League: {state.league_id.upper()}\n")
    state_text.append(f"Status: ", style="bold")
    state_text.append(f"{state.status}\n", style=status_color.get(state.status, "white"))
    state_text.append("\n")

    # Score
    state_text.append("Score: ", style="bold cyan")
    state_text.append(f"Away {state.away_score} - {state.home_score} Home\n", style="cyan")

    # Inning
    state_text.append("Inning: ", style="bold magenta")
    state_text.append(f"{state.inning} {state.half.capitalize()}\n", style="magenta")

    # Outs
    state_text.append("Outs: ", style="bold yellow")
    state_text.append(f"{state.outs}\n", style="yellow")

    # Runners
    runners = state.get_all_runners()
    if runners:
        state_text.append("\nRunners: ", style="bold green")
        runner_bases = [f"{base}B(#{player.lineup_id})" for base, player in runners]
        state_text.append(f"{', '.join(runner_bases)}\n", style="green")
    else:
        state_text.append("\nBases: ", style="bold")
        state_text.append("Empty\n", style="dim")

    # Current players
    if state.current_batter:
        state_text.append(f"\nBatter: Lineup #{state.current_batter.lineup_id}\n")
    if state.current_pitcher:
        state_text.append(f"Pitcher: Lineup #{state.current_pitcher.lineup_id}\n")
    if state.current_catcher:
        state_text.append(f"Catcher: Lineup #{state.current_catcher.lineup_id}\n")

    # Pending decision - provide clear guidance
    if state.pending_decision:
        state_text.append(f"\n", style="bold")
        state_text.append("⚠️  WAITING FOR ACTION\n", style="bold yellow")
        state_text.append("─" * 40 + "\n", style="dim")

        if state.pending_decision == "defensive":
            state_text.append("The defense needs to submit their decision.\n", style="yellow")
            state_text.append("Run: ", style="bold cyan")
            state_text.append("defensive", style="green")
            state_text.append(" [OPTIONS]\n", style="dim")
        elif state.pending_decision == "offensive":
            state_text.append("The offense needs to submit their decision.\n", style="yellow")
            state_text.append("Run: ", style="bold cyan")
            state_text.append("offensive", style="green")
            state_text.append(" [OPTIONS]\n", style="dim")
        elif state.pending_decision == "result_selection":
            state_text.append("Ready to resolve play - both teams have decided.\n", style="yellow")
            state_text.append("Run: ", style="bold cyan")
            state_text.append("resolve", style="green")
            state_text.append("\n", style="dim")
        else:
            state_text.append(f"Waiting for: {state.pending_decision}\n", style="yellow")

    # Last play result
    if state.last_play_result:
        state_text.append(f"\nLast Play: ", style="bold")
        state_text.append(f"{state.last_play_result}\n", style="italic")

    # Display panel
    panel = Panel(
        state_text,
        title=f"[bold]Game State[/bold]",
        border_style="blue",
        box=box.ROUNDED
    )
    console.print(panel)


def display_play_result(result: PlayResult, state: GameState) -> None:
    """
    Display play result with rich formatting.

    Args:
        result: Play result from resolver
        state: Updated game state
    """
    result_text = Text()

    # Outcome
    result_text.append("Outcome: ", style="bold")
    result_text.append(f"{result.outcome.value}\n", style="cyan")

    # Description
    result_text.append("Result: ", style="bold")
    result_text.append(f"{result.description}\n\n", style="white")

    # Dice roll
    result_text.append("Roll: ", style="bold yellow")
    result_text.append(f"{result.ab_roll}\n", style="yellow")

    # Stats
    if result.outs_recorded > 0:
        result_text.append(f"Outs: ", style="bold red")
        result_text.append(f"+{result.outs_recorded}\n", style="red")

    if result.runs_scored > 0:
        result_text.append(f"Runs: ", style="bold green")
        result_text.append(f"+{result.runs_scored}\n", style="green")

    # Runner advancement
    if result.runners_advanced:
        result_text.append(f"\nRunner Movement:\n", style="bold")
        for adv in result.runners_advanced:
            if adv.to_base == 4:
                result_text.append(f"  {adv.from_base}B → SCORES\n", style="green")
            else:
                result_text.append(f"  {adv.from_base}B → {adv.to_base}B\n")

    # Batter result
    if result.batter_result:
        if result.batter_result < 4:
            result_text.append(f"\nBatter: Reaches {result.batter_result}B\n", style="cyan")
        elif result.batter_result == 4:
            result_text.append(f"\nBatter: HOME RUN!\n", style="bold green")

    # Display panel
    panel = Panel(
        result_text,
        title=f"[bold]⚾ Play Result[/bold]",
        border_style="green",
        box=box.HEAVY
    )
    console.print(panel)

    # Show updated score
    console.print(f"\n[bold cyan]Score: Away {state.away_score} - {state.home_score} Home[/bold cyan]")


def display_decision(decision_type: str, decision: Optional[DefensiveDecision | OffensiveDecision]) -> None:
    """
    Display submitted decision.

    Args:
        decision_type: 'defensive' or 'offensive'
        decision: Decision object
    """
    if not decision:
        console.print(f"[yellow]No {decision_type} decision to display[/yellow]")
        return

    decision_text = Text()

    if isinstance(decision, DefensiveDecision):
        decision_text.append(f"Infield Depth: {decision.infield_depth}\n")
        decision_text.append(f"Outfield Depth: {decision.outfield_depth}\n")
        if decision.hold_runners:
            decision_text.append(f"Hold Runners: {decision.hold_runners}\n")
    elif isinstance(decision, OffensiveDecision):
        decision_text.append(f"Action: {decision.action}\n")
        if decision.steal_attempts:
            decision_text.append(f"Steal Attempts: {decision.steal_attempts}\n")

    panel = Panel(
        decision_text,
        title=f"[bold]{decision_type.capitalize()} Decision[/bold]",
        border_style="yellow",
        box=box.ROUNDED
    )
    console.print(panel)


def display_box_score(box_score: dict) -> None:
    """
    Display complete box score with game stats, batting stats, and pitching stats.

    Args:
        box_score: Box score data with keys:
            - game_stats: Team totals and linescore
            - batting_stats: List of player batting lines
            - pitching_stats: List of player pitching lines
    """
    game_stats = box_score.get('game_stats', {})
    batting_stats = box_score.get('batting_stats', [])
    pitching_stats = box_score.get('pitching_stats', [])

    # Team Totals Section
    totals_table = Table(title="[bold]Game Summary[/bold]", box=box.ROUNDED)
    totals_table.add_column("Team", style="cyan")
    totals_table.add_column("Runs", justify="right", style="bold green")
    totals_table.add_column("Hits", justify="right", style="yellow")
    totals_table.add_column("Errors", justify="right", style="red")

    totals_table.add_row(
        "Away",
        str(game_stats.get('away_runs', 0)),
        str(game_stats.get('away_hits', 0)),
        str(game_stats.get('away_errors', 0))
    )
    totals_table.add_row(
        "Home",
        str(game_stats.get('home_runs', 0)),
        str(game_stats.get('home_hits', 0)),
        str(game_stats.get('home_errors', 0))
    )

    console.print(totals_table)

    # Linescore Section
    home_linescore = game_stats.get('home_linescore', [])
    away_linescore = game_stats.get('away_linescore', [])

    if home_linescore or away_linescore:
        console.print()
        linescore_table = Table(title="[bold]Linescore[/bold]", box=box.SIMPLE)
        linescore_table.add_column("Team", style="cyan")

        # Add inning columns (1-9 or however many innings)
        num_innings = max(len(home_linescore), len(away_linescore))
        for inning in range(1, num_innings + 1):
            linescore_table.add_column(str(inning), justify="center")

        # Away linescore
        away_row = ["Away"] + [str(away_linescore[i]) if i < len(away_linescore) else "-" for i in range(num_innings)]
        linescore_table.add_row(*away_row)

        # Home linescore
        home_row = ["Home"] + [str(home_linescore[i]) if i < len(home_linescore) else "-" for i in range(num_innings)]
        linescore_table.add_row(*home_row)

        console.print(linescore_table)

    # Batting Stats Section
    if batting_stats:
        console.print()
        batting_table = Table(title="[bold]Batting Stats[/bold]", box=box.ROUNDED)
        batting_table.add_column("Lineup", style="cyan", width=6)
        batting_table.add_column("Card", style="yellow", width=6)
        batting_table.add_column("PA", justify="right", width=4)
        batting_table.add_column("AB", justify="right", width=4)
        batting_table.add_column("R", justify="right", width=4)
        batting_table.add_column("H", justify="right", width=4)
        batting_table.add_column("2B", justify="right", width=4)
        batting_table.add_column("3B", justify="right", width=4)
        batting_table.add_column("HR", justify="right", width=4, style="bold green")
        batting_table.add_column("RBI", justify="right", width=4)
        batting_table.add_column("BB", justify="right", width=4)
        batting_table.add_column("SO", justify="right", width=4)

        for batter in batting_stats:
            batting_table.add_row(
                str(batter.get('lineup_id', '')),
                str(batter.get('player_card_id', '')),
                str(batter.get('pa', 0)),
                str(batter.get('ab', 0)),
                str(batter.get('run', 0)),
                str(batter.get('hit', 0)),
                str(batter.get('double', 0)),
                str(batter.get('triple', 0)),
                str(batter.get('hr', 0)),
                str(batter.get('rbi', 0)),
                str(batter.get('bb', 0)),
                str(batter.get('so', 0))
            )

        console.print(batting_table)

    # Pitching Stats Section
    if pitching_stats:
        console.print()
        pitching_table = Table(title="[bold]Pitching Stats[/bold]", box=box.ROUNDED)
        pitching_table.add_column("Lineup", style="cyan", width=6)
        pitching_table.add_column("Card", style="yellow", width=6)
        pitching_table.add_column("IP", justify="right", width=6)
        pitching_table.add_column("BF", justify="right", width=4)
        pitching_table.add_column("H", justify="right", width=4)
        pitching_table.add_column("R", justify="right", width=4)
        pitching_table.add_column("ER", justify="right", width=4)
        pitching_table.add_column("BB", justify="right", width=4)
        pitching_table.add_column("SO", justify="right", width=4, style="bold green")
        pitching_table.add_column("HR", justify="right", width=4)

        for pitcher in pitching_stats:
            # Format IP to show fractional innings (e.g., 5.1 for 5 1/3 innings)
            ip = pitcher.get('ip', 0.0)
            ip_str = f"{ip:.1f}" if ip else "0.0"

            pitching_table.add_row(
                str(pitcher.get('lineup_id', '')),
                str(pitcher.get('player_card_id', '')),
                ip_str,
                str(pitcher.get('batters_faced', 0)),
                str(pitcher.get('hit_allowed', 0)),
                str(pitcher.get('run_allowed', 0)),
                str(pitcher.get('erun', 0)),
                str(pitcher.get('bb', 0)),
                str(pitcher.get('so', 0)),
                str(pitcher.get('hr_allowed', 0))
            )

        console.print(pitching_table)


def print_success(message: str) -> None:
    """Print success message."""
    console.print(f"✓ [green]{message}[/green]")


def print_error(message: str) -> None:
    """Print error message."""
    console.print(f"✗ [red]{message}[/red]")


def print_info(message: str) -> None:
    """Print info message."""
    console.print(f"[blue]ℹ {message}[/blue]")


def print_warning(message: str) -> None:
    """Print warning message."""
    console.print(f"[yellow]⚠ {message}[/yellow]")
