package thb.jeanluc.adventure.loader;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import thb.jeanluc.adventure.loader.dto.TutorialDto;
import thb.jeanluc.adventure.loader.dto.TutorialStepDto;
import thb.jeanluc.adventure.model.Tutorial;
import thb.jeanluc.adventure.model.TutorialStep;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Loads the optional onboarding tutorial from {@code <base>/tutorial.yaml}.
 * Kept separate from {@link WorldLoader}: the tutorial is onboarding, not world
 * content. Returns {@link Tutorial#none()} when the file is absent.
 */
public class TutorialLoader {

    /** Default classpath base directory. */
    public static final String DEFAULT_BASE = "/world";

    private final ObjectMapper yaml = new ObjectMapper(new YAMLFactory());
    private final String basePath;

    public TutorialLoader() {
        this(DEFAULT_BASE);
    }

    public TutorialLoader(String basePath) {
        this.basePath = basePath;
    }

    /** Reads the tutorial; absent file → {@link Tutorial#none()}. */
    public Tutorial load() {
        String resource = basePath + "/tutorial.yaml";
        try (InputStream in = getClass().getResourceAsStream(resource)) {
            if (in == null) {
                return Tutorial.none();
            }
            TutorialDto dto = yaml.readValue(in, TutorialDto.class);
            if (dto == null) {
                return Tutorial.none();
            }
            List<TutorialStep> steps = new ArrayList<>();
            if (dto.steps() != null) {
                for (TutorialStepDto s : dto.steps()) {
                    steps.add(new TutorialStep(
                            s.instruction(),
                            s.expect(),
                            s.minArgs() == null ? 0 : s.minArgs(),
                            s.confirm(),
                            s.hint()));
                }
            }
            return new Tutorial(dto.intro(), steps, dto.closingTips());
        } catch (IOException e) {
            throw new WorldLoadException("Failed to parse " + resource, e);
        }
    }
}
