import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class PlayerTest {
    private final Song a = new Song("A", "x", 100);
    private final Song b = new Song("B", "y", 50);
    private final List<PlayerEvent> events = new ArrayList<>();
    private Player player;

    @BeforeEach
    void setUp() {
        player = new Player(List.of(a, b));
        player.addListener(events::add);          // un spy hecho con una referencia a método
    }

    private String lastMessage() {
        return events.get(events.size() - 1).message();
    }

    @Test
    void startsStopped() {
        assertEquals(State.STOPPED, player.state());
    }

    @Test
    void playMeansDifferentThingsInEachState() {
        player.play();
        assertEquals("suena", lastMessage());
        player.play();
        assertEquals("ya está sonando", lastMessage());
        player.pause();
        player.play();
        assertEquals("continúa", lastMessage());
        assertEquals(State.PLAYING, player.state());
    }

    @Test
    void pauseOnlyWorksWhilePlaying() {
        player.pause();
        assertEquals(State.STOPPED, player.state());
        assertEquals("no hay nada que pausar", lastMessage());
        player.play();
        player.pause();
        assertEquals(State.PAUSED, player.state());
    }

    @Test
    void tickAdvancesWhenTheSongEnds() {
        player.play();
        player.tick(99);
        assertEquals(a, player.current());
        player.tick(1);
        assertEquals(b, player.current());
        assertEquals(State.PLAYING, player.state());
    }

    @Test
    void tickIsIgnoredWhilePaused() {
        player.play();
        player.pause();
        player.tick(500);
        assertEquals(a, player.current());
        assertEquals(State.PAUSED, player.state());
    }

    @Test
    void nextAfterTheLastSongStops() {
        player.play();
        player.next();
        player.next();
        assertEquals(State.STOPPED, player.state());
        assertEquals("fin de la lista", lastMessage());
        assertEquals(b, events.get(events.size() - 1).song());
        assertEquals(a, player.current());
    }

    @Test
    void emptyQueueIsRejected() {
        assertThrows(IllegalArgumentException.class, () -> new Player(List.of()));
    }
}
