package p.packer.messages.assets;

import java.util.List;
import java.util.Locale;

public enum OutputFormatCatalog {
    GLYPH_INDEXED_V1(AssetFamilyCatalog.GLYPH_BANK, "GLYPH/indexed_v1", "GLYPH/indexed_v1"),
    SCENE_TILED_V1(AssetFamilyCatalog.SCENE_BANK, "SCENE/tilemap_v1", "SCENE/tilemap_v1"),
    SOUND_V1(AssetFamilyCatalog.SOUND_BANK, "SOUND/v1", "SOUND/v1"),
    UNKNOWN(AssetFamilyCatalog.UNKNOWN, "unknown", "Unknown");

    private final AssetFamilyCatalog assetFamily;
    private final String manifestValue;
    private final String displayName;

    OutputFormatCatalog(AssetFamilyCatalog assetFamily, String manifestValue, String displayName) {
        this.assetFamily = assetFamily;
        this.manifestValue = manifestValue;
        this.displayName = displayName;
    }

    public AssetFamilyCatalog assetFamily() {
        return assetFamily;
    }

    public String manifestValue() {
        return manifestValue;
    }

    public String displayName() {
        return displayName;
    }

    public List<OutputCodecCatalog> availableCodecs() {
        return this == UNKNOWN ? List.of() : List.of(OutputCodecCatalog.NONE);
    }

    public boolean supports(OutputCodecCatalog codec) {
        return availableCodecs().contains(codec);
    }

    public static List<OutputFormatCatalog> supportedFor(AssetFamilyCatalog assetFamily) {
        if (assetFamily == null || assetFamily == AssetFamilyCatalog.UNKNOWN) {
            return List.of();
        }
        return java.util.Arrays.stream(values())
                .filter(candidate -> candidate != UNKNOWN)
                .filter(candidate -> candidate.assetFamily == assetFamily)
                .toList();
    }

    public static OutputFormatCatalog fromManifestValue(String manifestValue) {
        if (manifestValue == null) {
            return UNKNOWN;
        }
        final String normalized = manifestValue.trim().toLowerCase(Locale.ROOT);
        if ("scene/tiled_v1".equals(normalized)) {
            return SCENE_TILED_V1;
        }
        if ("sound/bank_v1".equals(normalized)) {
            return SOUND_V1;
        }
        for (OutputFormatCatalog candidate : values()) {
            if (candidate == UNKNOWN) {
                continue;
            }
            if (candidate.manifestValue.toLowerCase(Locale.ROOT).equals(normalized)) {
                return candidate;
            }
        }
        return UNKNOWN;
    }
}
