# tests game state + game loop init

from unittest.mock import AsyncMock

from game_loop import GameLoop
from game_state import GameState, PlayerState, SoulgateState, WaveState
from lobby import Lobby, LobbyPlayer


def make_lobby():
    lobby = Lobby(code="TEST01")
    lobby.players = [
        LobbyPlayer(conn_id="c1", username="Alice",   player_class="kael",   is_ready=True, is_host=True),
        LobbyPlayer(conn_id="c2", username="Bob",     player_class="seris",  is_ready=True),
        LobbyPlayer(conn_id="c3", username="Charlie", player_class="aldric", is_ready=True),
    ]
    return lobby


def test_game_state_to_dict():
    state = GameState(
        tick=5, players=[], enemies=[], projectiles=[],
        soulgate=SoulgateState(hp=80, max_hp=100),
        wave=WaveState(number=2, phase=1, enemies_remaining=3, state="combat"),
        effects=[],
    )
    d = state.to_dict()
    assert d["type"] == "game_state"
    assert d["tick"] == 5
    for key in ("players", "enemies", "projectiles", "soulgate", "wave"):
        assert key in d


def test_player_state_to_dict():
    p = PlayerState(id="c1", class_name="kael", username="Alice", x=0.0, y=-10.0, hp=150, max_hp=150, alive=True)
    d = p.to_dict()
    assert d["class"] == "kael"
    assert d["hp"] == 150
    assert "attack" in d["cooldowns"]


def test_game_loop_3_joueurs():
    loop = GameLoop(make_lobby(), AsyncMock())
    assert len(loop.state.players) == 3


def test_hp_par_classe():
    loop = GameLoop(make_lobby(), AsyncMock())
    by_class = {p.class_name: p.max_hp for p in loop.state.players}
    assert by_class["kael"] == 150
    assert by_class["seris"] == 80
    assert by_class["aldric"] == 100


def test_tick_incremente():
    loop = GameLoop(make_lobby(), AsyncMock())
    assert loop.state.tick == 0
    loop._tick()
    assert loop.state.tick == 1
