package reborncore.common.crafting.ingredient;

import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.recipe.Ingredient;
import net.minecraft.tag.ItemTags;
import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.registry.Registry;
import org.apache.commons.lang3.Validate;

import java.util.List;
import java.util.stream.Collectors;

public class TagIngredient extends RebornIngredient {

	private final Identifier tagIdentifier;
	private final Tag<Item> tag;

	public TagIngredient(Identifier tagIdentifier, Tag<Item> tag) {
		super(IngredientManager.TAG_RECIPE_TYPE);
		this.tagIdentifier = tagIdentifier;
		this.tag = tag;
	}

	@Override
	public boolean test(ItemStack itemStack) {
		return itemStack.getItem().isIn(tag);
	}

	@Override
	public Ingredient getPreview() {
		return Ingredient.fromTag(tag);
	}

	@Override
	public List<ItemStack> getPreviewStacks() {
		return tag.values().stream().map(ItemStack::new).collect(Collectors.toList());
	}

	public static RebornIngredient deserialize(JsonObject json) {
		if(json.has("server_sync")){
			Identifier tagIdent = new Identifier(JsonHelper.getString(json, "tag_identifier"));
			Tag.Builder<Item> tagBuilder = Tag.Builder.create();
			for (int i = 0; i < JsonHelper.getInt(json, "items"); i++) {
				Identifier identifier = new Identifier(JsonHelper.getString(json, "item_" + i));
				Item item = Registry.ITEM.get(identifier);
				Validate.isTrue(item != Items.AIR, "item cannot be air");
				tagBuilder.add(item);
			}
			return new TagIngredient(tagIdent, tagBuilder.build(tagIdent));
		}

		Identifier identifier = new Identifier(JsonHelper.getString(json, "tag"));
		Tag<Item> tag = ItemTags.getContainer().get(identifier);
		if (tag == null) {
			throw new JsonSyntaxException("Unknown item tag '" + identifier + "'");
		}
		return new TagIngredient(identifier, tag);
	}

	@Override
	public JsonObject toJson() {
		//Tags are not synced across the server so we sync all the items
		JsonObject jsonObject = new JsonObject();
		jsonObject.addProperty("server_sync", true);

		Item[] items = tag.values().toArray(new Item[0]);
		jsonObject.addProperty("items", items.length);
		for (int i = 0; i < items.length; i++) {
			jsonObject.addProperty("item_" + i, Registry.ITEM.getId(items[i]).toString());
		}

		jsonObject.addProperty("tag_identifier", tagIdentifier.toString());
		return jsonObject;
	}
}

@@ -514,16 +514,43 @@
 l.List;%0A
+import java.util.Optional;%0A
 import j
@@ -703,16 +703,56 @@
 em%3E tag;
+%0A%09private final Optional%3CInteger%3E count;
 %0A%0A%09publi
@@ -806,16 +806,41 @@
 tem%3E tag
+, Optional%3CInteger%3E count
 ) %7B%0A%09%09su
@@ -935,16 +935,38 @@
  = tag;%0A
+%09%09this.count = count;%0A
 %09%7D%0A%0A%09@Ov
@@ -1012,24 +1012,108 @@
 temStack) %7B%0A
+%09%09if(count.isPresent() && count.get() %3E itemStack.getCount())%7B%0A%09%09%09return false;%0A%09%09%7D%0A
 %09%09return ite
@@ -1427,24 +1427,158 @@
 ect json) %7B%0A
+%09%09Optional%3CInteger%3E count = Optional.empty();%0A%09%09if(json.has(%22count%22))%7B%0A%09%09%09count = Optional.of(JsonHelper.getInt(json, %22count%22));%0A%09%09%7D%0A%0A
 %09%09if(json.ha
@@ -2092,16 +2092,23 @@
 agIdent)
+, count
 );%0A%09%09%7D%0A%0A
@@ -2385,16 +2385,23 @@
 ier, tag
+, count
 );%0A%09%7D%0A%0A%09
@@ -2830,16 +2830,88 @@
 );%0A%09%09%7D%0A%0A
+%09%09count.ifPresent(integer -%3E jsonObject.addProperty(%22count%22, integer));%0A
 %09%09jsonOb

Fix tag ingredients not supporting itemstack counts