package thb.jeanluc.adventure.loader;

import thb.jeanluc.adventure.loader.dto.ItemDto;
import thb.jeanluc.adventure.model.item.Item;
import thb.jeanluc.adventure.model.item.PlainItem;
import thb.jeanluc.adventure.model.item.ReadableItem;
import thb.jeanluc.adventure.model.item.SwitchableItem;

/**
 * Converts {@link ItemDto} instances coming from YAML into concrete
 * {@link Item} subclasses. The {@code type} discriminator picks the
 * subclass; unknown types fail fast with {@link WorldLoadException}.
 */
public final class ItemFactory {

    private ItemFactory() {
    }

    /**
     * Builds the appropriate {@link Item} subclass for the given DTO.
     *
     * @param dto data read from {@code items.yaml}; must not be null
     * @return the freshly built item
     * @throws WorldLoadException if {@code dto.type} is missing or unknown
     */
    public static Item fromDto(ItemDto dto) {
        String type = dto.type() == null ? "plain" : dto.type().toLowerCase();
        return switch (type) {
            case "plain" -> PlainItem.builder()
                    .id(dto.id())
                    .name(dto.name())
                    .description(dto.description())
                    .light(Boolean.TRUE.equals(dto.light()))
                    .build();
            case "readable" -> ReadableItem.builder()
                    .id(dto.id())
                    .name(dto.name())
                    .description(dto.description())
                    .readText(dto.readText())
                    .light(Boolean.TRUE.equals(dto.light()))
                    .build();
            case "switchable" -> SwitchableItem.builder()
                    .id(dto.id())
                    .name(dto.name())
                    .description(dto.description())
                    .state(Boolean.TRUE.equals(dto.initialState()))
                    .onText(dto.onText())
                    .offText(dto.offText())
                    .effects(thb.jeanluc.adventure.loader.dto.EffectDto.toModelList(dto.effects()))
                    .light(Boolean.TRUE.equals(dto.light()))
                    .build();
            default -> throw new WorldLoadException(
                    "Unknown item type '" + dto.type() + "' on item '" + dto.id() + "'");
        };
    }
}
