package thb.jeanluc.adventure.loader;

import org.junit.jupiter.api.Test;
import thb.jeanluc.adventure.loader.dto.CombinationDto;
import thb.jeanluc.adventure.model.Combination;
import thb.jeanluc.adventure.model.item.Item;
import thb.jeanluc.adventure.model.item.PlainItem;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

class CombinationFactoryTest {

    private Map<String, Item> items() {
        Map<String, Item> m = new HashMap<>();
        for (String id : List.of("matches", "torch", "lit_torch")) {
            m.put(id, PlainItem.builder().id(id).name(id).description("d").light(false).build());
        }
        return m;
    }

    @Test
    void buildsCombinationFromDto() {
        CombinationDto dto = new CombinationDto("matches", "torch", null,
                List.of("matches", "torch"), "lit_torch", null, "You light it.", null);
        Combination c = CombinationFactory.fromDto(dto, items());
        assertThat(c.key()).isEqualTo("matches|torch");
        assertThat(c.consume()).containsExactly("matches", "torch");
        assertThat(c.produce()).isEqualTo("lit_torch");
        assertThat(c.response()).isEqualTo("You light it.");
    }

    @Test
    void rejectsUnknownOperandId() {
        CombinationDto dto = new CombinationDto("matches", "ghost", null, null, null, null, "x", null);
        assertThatThrownBy(() -> CombinationFactory.fromDto(dto, items()))
                .isInstanceOf(WorldLoadException.class)
                .hasMessageContaining("ghost");
    }

    @Test
    void rejectsUnknownProduceId() {
        CombinationDto dto = new CombinationDto("matches", "torch", null, null, "phantom", null, "x", null);
        assertThatThrownBy(() -> CombinationFactory.fromDto(dto, items()))
                .isInstanceOf(WorldLoadException.class)
                .hasMessageContaining("phantom");
    }

    @Test
    void rejectsUnknownConsumeId() {
        CombinationDto dto = new CombinationDto("matches", "torch", null,
                List.of("matches", "wraith"), null, null, "x", null);
        assertThatThrownBy(() -> CombinationFactory.fromDto(dto, items()))
                .isInstanceOf(WorldLoadException.class)
                .hasMessageContaining("wraith");
    }

    @Test
    void rejectsSelfCombination() {
        CombinationDto dto = new CombinationDto("torch", "torch", null, null, null, null, "x", null);
        assertThatThrownBy(() -> CombinationFactory.fromDto(dto, items()))
                .isInstanceOf(WorldLoadException.class)
                .hasMessageContaining("itself");
    }
}
