package net.minecraft.data.recipes;

import javax.annotation.Nullable;
import com.google.gson.JsonObject;
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.advancements.RequirementsStrategy;
import net.minecraft.advancements.AdvancementRewards;
import net.minecraft.advancements.critereon.RecipeUnlockedTrigger;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.Registry;
import java.util.function.Consumer;
import net.minecraft.advancements.CriterionTriggerInstance;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.crafting.SimpleCookingSerializer;
import net.minecraft.advancements.Advancement;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.Item;

public class SimpleCookingRecipeBuilder {
    private final Item result;
    private final Ingredient ingredient;
    private final float experience;
    private final int cookingTime;
    private final Advancement.Builder advancement;
    private String group;
    private final SimpleCookingSerializer<?> serializer;
    
    private SimpleCookingRecipeBuilder(final ItemLike bqa, final Ingredient bmr, final float float3, final int integer, final SimpleCookingSerializer<?> bnd) {
        this.advancement = Advancement.Builder.advancement();
        this.result = bqa.asItem();
        this.ingredient = bmr;
        this.experience = float3;
        this.cookingTime = integer;
        this.serializer = bnd;
    }
    
    public static SimpleCookingRecipeBuilder cooking(final Ingredient bmr, final ItemLike bqa, final float float3, final int integer, final SimpleCookingSerializer<?> bnd) {
        return new SimpleCookingRecipeBuilder(bqa, bmr, float3, integer, bnd);
    }
    
    public static SimpleCookingRecipeBuilder blasting(final Ingredient bmr, final ItemLike bqa, final float float3, final int integer) {
        return cooking(bmr, bqa, float3, integer, RecipeSerializer.BLASTING_RECIPE);
    }
    
    public static SimpleCookingRecipeBuilder smelting(final Ingredient bmr, final ItemLike bqa, final float float3, final int integer) {
        return cooking(bmr, bqa, float3, integer, RecipeSerializer.SMELTING_RECIPE);
    }
    
    public SimpleCookingRecipeBuilder unlockedBy(final String string, final CriterionTriggerInstance ae) {
        this.advancement.addCriterion(string, ae);
        return this;
    }
    
    public void save(final Consumer<FinishedRecipe> consumer) {
        this.save(consumer, Registry.ITEM.getKey(this.result));
    }
    
    public void save(final Consumer<FinishedRecipe> consumer, final String string) {
        final ResourceLocation uh4 = Registry.ITEM.getKey(this.result);
        final ResourceLocation uh5 = new ResourceLocation(string);
        if (uh5.equals(uh4)) {
            throw new IllegalStateException("Recipe " + uh5 + " should remove its 'save' argument");
        }
        this.save(consumer, uh5);
    }
    
    public void save(final Consumer<FinishedRecipe> consumer, final ResourceLocation uh) {
        this.ensureValid(uh);
        this.advancement.parent(new ResourceLocation("recipes/root")).addCriterion("has_the_recipe", RecipeUnlockedTrigger.unlocked(uh)).rewards(AdvancementRewards.Builder.recipe(uh)).requirements(RequirementsStrategy.OR);
        consumer.accept(new Result(uh, (this.group == null) ? "" : this.group, this.ingredient, this.result, this.experience, this.cookingTime, this.advancement, new ResourceLocation(uh.getNamespace(), "recipes/" + this.result.getItemCategory().getRecipeFolderName() + "/" + uh.getPath()), this.serializer));
    }
    
    private void ensureValid(final ResourceLocation uh) {
        if (this.advancement.getCriteria().isEmpty()) {
            throw new IllegalStateException("No way of obtaining recipe " + uh);
        }
    }
    
    public static class Result implements FinishedRecipe {
        private final ResourceLocation id;
        private final String group;
        private final Ingredient ingredient;
        private final Item result;
        private final float experience;
        private final int cookingTime;
        private final Advancement.Builder advancement;
        private final ResourceLocation advancementId;
        private final RecipeSerializer<? extends AbstractCookingRecipe> serializer;
        
        public Result(final ResourceLocation uh1, final String string, final Ingredient bmr, final Item bke, final float float5, final int integer, final Advancement.Builder a, final ResourceLocation uh8, final RecipeSerializer<? extends AbstractCookingRecipe> bmw) {
            this.id = uh1;
            this.group = string;
            this.ingredient = bmr;
            this.result = bke;
            this.experience = float5;
            this.cookingTime = integer;
            this.advancement = a;
            this.advancementId = uh8;
            this.serializer = bmw;
        }
        
        @Override
        public void serializeRecipeData(final JsonObject jsonObject) {
            if (!this.group.isEmpty()) {
                jsonObject.addProperty("group", this.group);
            }
            jsonObject.add("ingredient", this.ingredient.toJson());
            jsonObject.addProperty("result", Registry.ITEM.getKey(this.result).toString());
            jsonObject.addProperty("experience", this.experience);
            jsonObject.addProperty("cookingtime", this.cookingTime);
        }
        
        @Override
        public RecipeSerializer<?> getType() {
            return this.serializer;
        }
        
        @Override
        public ResourceLocation getId() {
            return this.id;
        }
        
        @Nullable
        @Override
        public JsonObject serializeAdvancement() {
            return this.advancement.serializeToJson();
        }
        
        @Nullable
        @Override
        public ResourceLocation getAdvancementId() {
            return this.advancementId;
        }
    }
}
