package thb.jeanluc.adventure.model;

import org.junit.jupiter.api.Test;
import thb.jeanluc.adventure.model.item.Item;
import thb.jeanluc.adventure.model.item.PlainItem;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class PlayerTest {

    @Test
    void constructor_nullRoom_throws() {
        assertThatThrownBy(() -> new Player(null, 0))
                .isInstanceOf(IllegalArgumentException.class);
    }

    @Test
    void constructor_negativeGold_throws() {
        Room r = new Room("r", "R", "d");
        assertThatThrownBy(() -> new Player(r, -1))
                .isInstanceOf(IllegalArgumentException.class);
    }

    @Test
    void addItem_andRemoveItem_areConsistent() {
        Player p = new Player(new Room("r", "R", "d"), 0);
        Item it = PlainItem.builder().id("key").name("Key").description("d").build();

        p.addItem(it);
        assertThat(p.hasItem("key")).isTrue();

        assertThat(p.removeItem("key")).contains(it);
        assertThat(p.hasItem("key")).isFalse();
    }

    @Test
    void inventory_preservesInsertionOrder() {
        Player p = new Player(new Room("r", "R", "d"), 0);
        p.addItem(PlainItem.builder().id("a").name("A").description("d").build());
        p.addItem(PlainItem.builder().id("b").name("B").description("d").build());
        p.addItem(PlainItem.builder().id("c").name("C").description("d").build());

        assertThat(p.getInventory().keySet()).containsExactly("a", "b", "c");
    }

    @Test
    void setCurrentRoom_updatesPosition() {
        Room a = new Room("a", "A", "d");
        Room b = new Room("b", "B", "d");
        Player p = new Player(a, 0);

        p.setCurrentRoom(b);

        assertThat(p.getCurrentRoom()).isEqualTo(b);
    }

    @Test
    void startRoomIsVisitedFromTheStart() {
        Room start = new Room("kitchen", "Kitchen", "desc");
        Player p = new Player(start, 0);
        assertThat(p.getVisitedRoomIds()).containsExactly("kitchen");
    }

    @Test
    void movingMarksTheNewRoomVisited() {
        Room start = new Room("kitchen", "Kitchen", "desc");
        Room hall = new Room("hallway", "Hallway", "desc");
        Player p = new Player(start, 0);
        p.setCurrentRoom(hall);
        assertThat(p.getVisitedRoomIds()).containsExactly("kitchen", "hallway");
    }
}
