package thb.jeanluc.adventure.model.item;

import org.junit.jupiter.api.Test;
import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.io.TestIO;
import thb.jeanluc.adventure.model.Player;
import thb.jeanluc.adventure.model.Room;

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

class ItemTest {

    private GameContext newCtx(TestIO io) {
        Player p = new Player(new Room("r", "R", "d"), 0);
        return new GameContext(null, p, io);
    }

    @Test
    void readableItem_use_writesReadText() {
        TestIO io = new TestIO();
        ReadableItem letter = ReadableItem.builder()
                .id("letter").name("Letter").description("d")
                .readText("hello world").build();

        letter.use(newCtx(io));

        assertThat(io.lastOutput()).isEqualTo("hello world");
    }

    @Test
    void switchableItem_use_togglesAndPrintsAppropriateText() {
        TestIO io = new TestIO();
        SwitchableItem lamp = SwitchableItem.builder()
                .id("lamp").name("Lamp").description("d")
                .state(false).onText("on").offText("off").build();

        lamp.use(newCtx(io));
        assertThat(lamp.isOn()).isTrue();
        assertThat(io.outputs()).containsExactly("on");

        lamp.use(newCtx(io));
        assertThat(lamp.isOn()).isFalse();
        assertThat(io.outputs()).endsWith("off");
    }

    @Test
    void switchableItem_initialStateTrue_startsOn() {
        SwitchableItem lamp = SwitchableItem.builder()
                .id("lamp").name("Lamp").description("d")
                .state(true).onText("on").offText("off").build();

        assertThat(lamp.isOn()).isTrue();
    }

    @Test
    void plainItem_use_writesGenericMessage() {
        TestIO io = new TestIO();
        PlainItem shovel = PlainItem.builder()
                .id("shovel").name("Shovel").description("d").build();

        shovel.use(newCtx(io));

        assertThat(io.lastOutput()).contains("Shovel");
        assertThat(io.lastOutput()).contains("can't use");
    }
}
