package thb.jeanluc.adventure.loader;

import org.junit.jupiter.api.Test;
import thb.jeanluc.adventure.model.Direction;
import thb.jeanluc.adventure.model.NpcReaction;

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

/**
 * Loads the real, shipped Haunted Manor world (the toy test fixture has been
 * removed, so {@code new WorldLoader().load()} resolves the production YAML).
 * Assertions check form-invariants of the delivered world rather than fragile
 * exact values, so adding flavour rooms/items won't break the suite — but a
 * broken start room, missing core item, or unwired exit will.
 */
class WorldLoaderTest {

    @Test
    void load_happyPath_buildsTheShippedManor() {
        WorldLoader.LoadResult result = new WorldLoader().load();

        assertThat(result.world().getTitle()).isEqualTo("Haunted Manor");
        assertThat(result.world().getRooms()).hasSize(14);
        assertThat(result.world().getRooms().keySet())
                .contains("foyer", "grand_hall", "cellar_stairs", "boiler_room",
                        "grand_staircase", "landing", "chapel");
        assertThat(result.world().getItems().keySet())
                .contains("lamp", "valve_wheel", "valve", "fuse", "generator",
                        "locket", "photograph", "shrine", "front_door", "lit_torch");
        assertThat(result.world().getNpcs().keySet()).contains("old_man");

        assertThat(result.player().getCurrentRoom().getId()).isEqualTo("foyer");
        assertThat(result.player().getGold()).isZero();
    }

    @Test
    void load_resolvesExitsBidirectionally_whenYamlDeclaresThem() {
        var loaded = new WorldLoader().load().world();
        var foyer = loaded.getRooms().get("foyer");
        var grandHall = loaded.getRooms().get("grand_hall");

        assertThat(foyer.getExit(Direction.NORTH)).contains(grandHall);
        assertThat(grandHall.getExit(Direction.SOUTH)).contains(foyer);
    }

    @Test
    void load_resolvesNpcReactionsToItemReferences() {
        var loaded = new WorldLoader().load().world();
        var oldMan = loaded.getNpcs().get("old_man");

        assertThat(oldMan.getReactions()).containsKey("letter");
        NpcReaction r = oldMan.reactionFor("letter").orElseThrow();
        assertThat(r.getConsumes()).isEqualTo(loaded.getItems().get("letter"));
        assertThat(r.getGives()).isNull();
    }
}
