using System.Drawing;
using System.Text.Json;
using System.Text.Json.Serialization;

var icons = Directory.GetFiles("H:\\iccocooons\\test\\icons").ToDictionary(f => Path.GetFileNameWithoutExtension(f)!,
    f =>
        new Icon()
        {
            Path = f,
            //Image = new Bitmap(f)
        });

var recipes = Directory.EnumerateFiles("H:\\iccocooons\\test\\recipes", "*.json", SearchOption.AllDirectories)
    .Select(f =>
    {
        var text = File.ReadAllText(f);
        var type = JsonSerializer.Deserialize<RecipeType>(text);
        if (type.Type != "minecraft:crafting_shaped")
            return null;

        //Console.WriteLine(File.ReadAllText(f));
        return JsonSerializer.Deserialize<RecipeRoot>(File.ReadAllText(f))!;
    }).Where(r => r != null);
var count = 0;
foreach (var recipeRoot in recipes)
{
    var keys = recipeRoot.Key;
    if (keys == null)
        continue;

    var good = true;

    if (!recipeRoot.Result.TryGetValue("item", out var resultElement))
        continue;

    var result = resultElement.Deserialize<string>();
    var recipeItems = new Dictionary<char, string>();

    foreach (var (key, value) in recipeRoot.Key)
    {
        string itemName;
        if (value.ValueKind == JsonValueKind.Array)
        {
            var items = value.Deserialize<List<ItemName>>()!;
            if (!items.All(i => i.Item != null))
            {
                good = false;
                break;
            }

            itemName = items.First().Item;
        }
        else
        {
            var item = value.Deserialize<ItemName>()!;
            if (item.Item == null)
            {
                good = false;
                break;
            }

            itemName = item.Item;
        }

        if (itemName.Contains(":"))
            itemName = itemName.Split(":")[1];
        
        if (!icons.ContainsKey(itemName))
        {
            good = false;
            break;
        }

        recipeItems[key] = itemName;
    }

    if (good == false)
        continue;

    var recipeArray = new List<string?>();
    foreach (var patternLine in recipeRoot.Pattern)
    {
        foreach (var patternItem in patternLine)
        {
            if (patternItem == ' ')
            {
                recipeArray.Add(null);
                continue;
            }

            var item = recipeItems[patternItem];
            recipeArray.Add(icons[item].Path);
        }
    }

    //Console.WriteLine(JsonSerializer.Serialize(recipeArray));
    count++;
}

Console.WriteLine(count);

class Icon
{
    public string Path { get; set; }
    public Bitmap Image { get; set; }
}

public class ItemName
{
    [JsonPropertyName("item")]
    public string? Item { get; set; }
}

public class RecipeRoot
{
    [JsonPropertyName("type")] public string Type { get; set; }

    [JsonPropertyName("key")] public Dictionary<char, JsonElement> Key { get; set; }

    [JsonPropertyName("pattern")] public List<string> Pattern { get; set; }

    [JsonPropertyName("result")] public Dictionary<string, JsonElement> Result { get; set; }
}

public class RecipeType
{
    [JsonPropertyName("type")] public string Type { get; set; }
}


extend code to make it merge crafts into 3x3 single image constisting of 16x16 icons, if Icon is null then just empty 16x16