from __future__ import annotations

from blokus_gym.core.game import BlokusGame

# ANSI color codes for terminal rendering
ANSI_COLORS = {
    0: "\033[90m",  # grey (empty)
    1: "\033[91m",  # red
    2: "\033[94m",  # blue
    3: "\033[93m",  # yellow
    4: "\033[92m",  # green
}
ANSI_RESET = "\033[0m"

# Player names
PLAYER_NAMES = {1: "Red", 2: "Blue", 3: "Yellow", 4: "Green"}


def render_text_board(game: BlokusGame) -> str:
    """Render the board as a text string (no ANSI colors).

    Returns a string representation of the board.
    """
    lines = []
    size = game.board_size

    # Column headers
    header = "  " + " ".join(str(i % 10) for i in range(size))
    lines.append(header)

    for y in range(size):
        row = f"{y % 10} "
        for x in range(size):
            cell = game.board.get_cell(x, y)
            if cell == 0:
                row += ". "
            else:
                row += f"{cell} "
        lines.append(row)

    # Player info
    lines.append("")
    for i, player in enumerate(game.players):
        remaining = len(player.available_pieces)
        total = len(game.piece_set.pieces)
        name = PLAYER_NAMES.get(i + 1, f"Player {i + 1}")
        lines.append(f"{name}: {remaining}/{total} pieces remaining, score: {player.score}")

    cur_name = PLAYER_NAMES.get(game.current_player + 1, game.current_player + 1)
    lines.append(f"Current player: {cur_name}")

    return "\n".join(lines)


def render_ansi_board(game: BlokusGame) -> str:
    """Render the board with ANSI color codes.

    Returns a string with ANSI escape sequences for colored output.
    """
    lines = []
    size = game.board_size

    # Column headers
    header = "  " + " ".join(str(i % 10) for i in range(size))
    lines.append(header)

    for y in range(size):
        row = f"{y % 10} "
        for x in range(size):
            cell = game.board.get_cell(x, y)
            color = ANSI_COLORS.get(cell, ANSI_RESET)
            if cell == 0:
                row += f"{color}. {ANSI_RESET}"
            else:
                row += f"{color}{cell} {ANSI_RESET}"
        lines.append(row)

    # Player info
    lines.append("")
    for i, player in enumerate(game.players):
        remaining = len(player.available_pieces)
        total = len(game.piece_set.pieces)
        name = PLAYER_NAMES.get(i + 1, f"Player {i + 1}")
        color = ANSI_COLORS.get(i + 1, ANSI_RESET)
        lines.append(
            f"{color}{name}{ANSI_RESET}: {remaining}/{total} pieces, "
            f"score: {player.score}"
        )

    lines.append(
        f"Current player: "
        f"{ANSI_COLORS.get(game.current_player + 1, ANSI_RESET)}"
        f"{PLAYER_NAMES.get(game.current_player + 1, game.current_player + 1)}"
        f"{ANSI_RESET}"
    )

    return "\n".join(lines)


def print_board(game: BlokusGame, use_ansi: bool = True) -> None:
    """Print the board to stdout."""
    if use_ansi:
        print(render_ansi_board(game))
    else:
        print(render_text_board(game))
