from __future__ import annotations

from catan.cli import CLIController
from catan.game import Game, GameConfig, Phase
from catan.ml.agents import RandomAgent

from tests.utils import find_initial_spot


def _resolve_robber(controller: CLIController) -> None:
    game = controller.game
    board = game.board
    for hex_id, tile in board.hexes.items():
        if hex_id == board.robber_hex:
            continue
        victims = {
            board.corners[corner].owner
            for corner in tile.corners
            if board.corners[corner].owner and board.corners[corner].owner != game.current_player.name
        }
        victim = next(iter(victims)) if victims else None
        game.move_robber(hex_id, victim)
        return


def test_human_vs_random_bot_session() -> None:
    controller = CLIController(
        Game(GameConfig(player_names=["Human", "Bot", "Companion"], seed=9)),
        bots={"Bot": RandomAgent(seed=3), "Companion": RandomAgent(seed=5)},
    )

    # Complete setup: human manually places, bot uses random agent.
    while controller.game.phase != Phase.MAIN:
        current = controller.game.current_player.name
        if current == "Human":
            corner, road = find_initial_spot(controller.game)
            controller.handle_command(f"place {corner} {road}")
        else:
            controller._run_bot_turn(current)  # noqa: SLF001 - exercising CLI internals

    # Play a few rounds: human rolls and ends, bots play automatically.
    for _ in range(2):
        assert controller.game.current_player.name == "Human"
        controller.handle_command("roll")
        if controller.game.robber_move_required:
            _resolve_robber(controller)
        controller.handle_command("end")
        for name in ("Bot", "Companion"):
            assert controller.game.current_player.name == name
            controller._run_bot_turn(name)  # noqa: SLF001

    # Ensure bot activity is recorded in history.
    assert any(log.player in {"Bot", "Companion"} for log in controller.game.history)
