package com.acethewildfire.acesbs.datagen;

import com.acethewildfire.acesbs.AcesBS;
import com.acethewildfire.acesbs.block.FireOakBlocks;
import com.acethewildfire.acesbs.block.LemonWoodBlocks;
import com.acethewildfire.acesbs.block.ModBlocks;
import com.acethewildfire.acesbs.item.*;
import com.acethewildfire.acesbs.trim.ModTrimPatterns;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.fabricmc.fabric.api.tag.convention.v2.ConventionalItemTags;
import net.minecraft.block.Blocks;
import net.minecraft.data.recipe.RecipeExporter;
import net.minecraft.data.recipe.RecipeGenerator;
import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items;
import net.minecraft.recipe.*;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.Identifier;

import java.util.concurrent.CompletableFuture;

public class ModRecipeProvider extends FabricRecipeProvider {
    public ModRecipeProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
        super(output, registriesFuture);
    }

    @Override
    protected RecipeGenerator getRecipeGenerator(RegistryWrapper.WrapperLookup wrapperLookup, RecipeExporter recipeExporter) {
        return new RecipeGenerator(wrapperLookup, recipeExporter) {
            @Override
            public void generate() {
                TagKey<Item> PLANKS = TagKey.of(RegistryKeys.ITEM, Identifier.ofVanilla( "planks"));
//        List<ItemConvertible> ENTROPY_SMELTABLES = List.of(ModItems.RAW_ENTROPY, ModBlocks.ENTROPY_ORE, ModBlocks.DEEPSLATE_ENTROPY_ORE);
//        List<ItemConvertible> ENDTROPY_SMELTABLES = List.of(ModItems.RAW_ENDTROPY, ModBlocks.ENDTROPY_ORE);
//
//        offerBlasting(recipeExporter, ENTROPY_SMELTABLES, RecipeCategory.MISC, ModItems.STABLE_ENTROPY, 0.5f, 2000, "stable_entropy");
//        offerBlasting(recipeExporter, ENDTROPY_SMELTABLES, RecipeCategory.MISC, ModItems.STABLE_ENDTROPY, 0.5f, 2000, "stable_endtropy");

                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, ModItems.RAW_ENTROPY, RecipeCategory.DECORATIONS, ModBlocks.RAW_ENTROPY_BLOCK);
                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, ModItems.STABLE_ENTROPY, RecipeCategory.DECORATIONS, ModBlocks.STABLE_ENTROPY_BLOCK);
                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, ModItems.RAW_ENDTROPY, RecipeCategory.DECORATIONS, ModBlocks.RAW_ENDTROPY_BLOCK);
                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, ModItems.STABLE_ENDTROPY, RecipeCategory.DECORATIONS, ModBlocks.STABLE_ENDTROPY_BLOCK);

                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, PrismaSteelItems.PRISMA_STEEL, RecipeCategory.DECORATIONS, ModBlocks.PRISMA_STEEL_BLOCK);
                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, AshenSteelItems.ASHEN_STEEL, RecipeCategory.DECORATIONS, ModBlocks.ASHEN_STEEL_BLOCK);
                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, FractalDiamondItems.FRACTAL_DIAMOND, RecipeCategory.DECORATIONS, ModBlocks.FRACTAL_DIAMOND_BLOCK);
                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, HellfireDiamondItems.HELLFIRE_DIAMOND, RecipeCategory.DECORATIONS, ModBlocks.HELLFIRE_DIAMOND_BLOCK);
                offerReversibleCompactingRecipes(RecipeCategory.BUILDING_BLOCKS, ModItems.INFERNAL_ASHES, RecipeCategory.DECORATIONS, ModBlocks.INFERNAL_ASHES_BLOCK);


                offerAllFoodCookingRecipes(200, ModItems.LEMON, ModItems.COOKED_LEMON, 0.35F);

                createShaped(RecipeCategory.COMBAT, ModItems.ORACLE_LEMON, 4)
                        .pattern("###")
                        .pattern("#L#")
                        .pattern("###")
                        .input('#', ModItems.STABLE_ENTROPY)
                        .input('L', ModItems.LEMON)
                        .criterion(hasItem(ModItems.LEMON), conditionsFromItem(ModItems.LEMON))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.COMBAT, ModItems.THOT_BEGONE, 1)
                        .pattern("  P")
                        .pattern(" P ")
                        .pattern("S  ")
                        .input('S', Items.STICK)
                        .input('P', PLANKS)
                        .criterion(hasItem(Items.STICK), conditionsFromItem(Items.STICK))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.COMBAT, ModItems.BERSERKERS_PAULDRON, 1)
                        .pattern("ISB")
                        .pattern("ICS")
                        .pattern("EEE")
                        .input('I', ConventionalItemTags.IRON_INGOTS)
                        .input('S', Items.STRING)
                        .input('B', Items.BONE)
                        .input('C', Items.LEATHER_CHESTPLATE)
                        .input('E', ModItems.STABLE_ENTROPY)
                        .criterion(hasItem(Items.BONE), conditionsFromItem(Items.BONE))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.COMBAT, ModItems.SOVS_PLATE_CARRIER, 1)
                        .pattern(" S ")
                        .pattern("SCS")
                        .pattern(" S ")
                        .input('S', PrismaSteelItems.PRISMA_STEEL)
                        .input('C', Items.IRON_CHESTPLATE)
                        .criterion(hasItem(PrismaSteelItems.PRISMA_STEEL), conditionsFromItem(PrismaSteelItems.PRISMA_STEEL))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.COMBAT, ModItems.WILDFIRE_BOOTS, 1)
                        .pattern("   ")
                        .pattern("A A")
                        .pattern("ABA")
                        .input('A', ModItems.INFERNAL_ASHES)
                        .input('B', Items.IRON_BOOTS)
                        .criterion(hasItem(ModItems.INFERNAL_ASHES), conditionsFromItem(ModItems.INFERNAL_ASHES))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.FOOD, ModItems.BRICKED_UP, 1)
                        .input(Items.BRICK, 1)
                        .input(ModItems.STABLE_ENDTROPY, 1)
                        .criterion(hasItem(ModItems.STABLE_ENDTROPY), conditionsFromItem(ModItems.STABLE_ENDTROPY))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.FOOD, ModItems.CIGARETTE, 1)
                        .input(Items.PAPER, 1)
                        .input(ModItems.TOBACCO, 1)
                        .criterion(hasItem(ModItems.TOBACCO), conditionsFromItem(ModItems.TOBACCO))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.FOOD, ModItems.CIGARETTE_LEMON, 1)
                        .input(ModItems.CIGARETTE, 1)
                        .input(ModItems.COMBUSTIBLE_LEMON, 1)
                        .criterion(hasItem(ModItems.CIGARETTE), conditionsFromItem(ModItems.CIGARETTE))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.FOOD, ModItems.CIGARETTE_FUNNY, 1)
                        .input(ModItems.CIGARETTE, 1)
                        .input(ModItems.INFERNAL_ASHES, 1)
                        .criterion(hasItem(ModItems.CIGARETTE), conditionsFromItem(ModItems.CIGARETTE))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.DECORATIONS, ModBlocks.CRYSTAL_ENTROPY, 8)
                        .pattern("###")
                        .pattern("#S#")
                        .pattern("###")
                        .input('#', Blocks.GLASS)
                        .input('S', ModItems.STABLE_ENTROPY)
                        .criterion(hasItem(ModItems.STABLE_ENTROPY), conditionsFromItem(ModItems.STABLE_ENTROPY))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "crystal_entropy_from_stable_and_glass")));

                createShaped(RecipeCategory.MISC, ModBlocks.ENTROPIC_STABILIZER, 1)
                        .pattern("IRI")
                        .pattern("IBI")
                        .pattern("III")
                        .input('I', Items.IRON_INGOT)
                        .input('R', ModItems.RAW_ENTROPY)
                        .input('B', Blocks.BLUE_ICE)
                        .criterion(hasItem(ModItems.RAW_ENTROPY), conditionsFromItem(ModItems.RAW_ENTROPY))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.MISC, ModBlocks.ENTROPIC_EVISCERATOR, 1)
                        .pattern("III")
                        .pattern("SES")
                        .pattern("III")
                        .input('I', Items.IRON_INGOT)
                        .input('S', Blocks.STONECUTTER)
                        .input('E', ModItems.STABLE_ENTROPY)
                        .criterion(hasItem(Blocks.STONECUTTER), conditionsFromItem(Blocks.STONECUTTER))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.MISC, ModBlocks.ENTROPIC_ENTANGLER, 1)
                        .pattern("ISI")
                        .pattern("BGB")
                        .pattern("ISI")
                        .input('I', Items.IRON_INGOT)
                        .input('S', ModItems.STABLE_ENTROPY)
                        .input('B', Items.BUCKET)
                        .input('G', Blocks.GOLD_BLOCK)
                        .criterion(hasItem(ModItems.RAW_ENTROPY), conditionsFromItem(ModItems.RAW_ENTROPY))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.COMBAT, ModItems.COMBUSTIBLE_LEMON, 1)
                        .input(ModItems.LEMON, 1)
                        .input(Items.FIRE_CHARGE, 1)
                        .input(Items.GUNPOWDER, 1)
                        .criterion(hasItem(ModItems.LEMON), conditionsFromItem(ModItems.LEMON))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.DECORATIONS, ModBlocks.CRYSTAL_ENTROPY_PANE, 16)
                        .pattern("###")
                        .pattern("###")
                        .input('#', ModBlocks.CRYSTAL_ENTROPY)
                        .criterion(hasItem(ModBlocks.CRYSTAL_ENTROPY), conditionsFromItem(ModBlocks.CRYSTAL_ENTROPY))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.BUILDING_BLOCKS, ModBlocks.LIZARD_PLANKS, 4)
                        .input(Blocks.BIRCH_PLANKS, 4)
                        .input(ModItems.RAW_ENTROPY, 1)
                        .input(Items.GREEN_DYE, 1)
                        .criterion(hasItem(Items.GREEN_DYE), conditionsFromItem(Items.GREEN_DYE))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.REDSTONE, ModBlocks.LIZARD_BUTTON, 1)
                        .input(ModBlocks.LIZARD_PLANKS, 1)
                        .criterion(hasItem(ModBlocks.LIZARD_PLANKS), conditionsFromItem(ModBlocks.LIZARD_PLANKS))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.FOOD, ModItems.BUBBLE_PIPE, 1)
                        .pattern("  #")
                        .pattern("PPP")
                        .pattern("   ")
                        .input('#', Items.IRON_INGOT)
                        .input('P', Blocks.BIRCH_PLANKS)
                        .criterion(hasItem(Blocks.BIRCH_PLANKS), conditionsFromItem(Blocks.BIRCH_PLANKS))
                        .offerTo(recipeExporter);

//                createShapeless(RecipeCategory.DECORATIONS, LemonWoodBlocks.LEMONWOOD_SAPLING, 1)
//                        .input(Blocks.BIRCH_SAPLING, 1)
//                        .input(ModItems.LEMON, 1)
//                        .criterion(hasItem(ModItems.LEMON), conditionsFromItem(ModItems.LEMON))
//                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.BUILDING_BLOCKS, LemonWoodBlocks.LEMONWOOD_PLANKS, 4)
                        .input(LemonWoodBlocks.LEMONWOOD_LOG, 1)
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_LOG), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_LOG))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "lemonwood_planks_from_lemonwood_log")));

                createShapeless(RecipeCategory.BUILDING_BLOCKS, LemonWoodBlocks.LEMONWOOD_PLANKS, 4)
                        .input(LemonWoodBlocks.STRIPPED_LEMONWOOD_LOG, 1)
                        .criterion(hasItem(LemonWoodBlocks.STRIPPED_LEMONWOOD_LOG), conditionsFromItem(LemonWoodBlocks.STRIPPED_LEMONWOOD_LOG))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "lemonwood_planks_from_stripped_lemonwood_log")));

                createShapeless(RecipeCategory.BUILDING_BLOCKS, LemonWoodBlocks.LEMONWOOD_PLANKS, 4)
                        .input(LemonWoodBlocks.LEMONWOOD_WOOD, 1)
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_WOOD), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_WOOD))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "lemonwood_planks_from_lemonwood_wood")));

                createShapeless(RecipeCategory.BUILDING_BLOCKS, LemonWoodBlocks.LEMONWOOD_PLANKS, 4)
                        .input(LemonWoodBlocks.STRIPPED_LEMONWOOD_WOOD, 1)
                        .criterion(hasItem(LemonWoodBlocks.STRIPPED_LEMONWOOD_WOOD), conditionsFromItem(LemonWoodBlocks.STRIPPED_LEMONWOOD_WOOD))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "lemonwood_planks_from_stripped_lemonwood_wood")));

                createShaped(RecipeCategory.BUILDING_BLOCKS, LemonWoodBlocks.LEMONWOOD_WOOD, 3)
                        .pattern("## ")
                        .pattern("## ")
                        .pattern("   ")
                        .input('#', LemonWoodBlocks.LEMONWOOD_LOG)
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_LOG), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_LOG))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.BUILDING_BLOCKS, LemonWoodBlocks.STRIPPED_LEMONWOOD_WOOD, 3)
                        .pattern("## ")
                        .pattern("## ")
                        .pattern("   ")
                        .input('#', LemonWoodBlocks.STRIPPED_LEMONWOOD_LOG)
                        .criterion(hasItem(LemonWoodBlocks.STRIPPED_LEMONWOOD_LOG), conditionsFromItem(LemonWoodBlocks.STRIPPED_LEMONWOOD_LOG))
                        .offerTo(recipeExporter);

                createStairsRecipe(LemonWoodBlocks.LEMONWOOD_STAIRS, Ingredient.ofItems(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_PLANKS), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .offerTo(recipeExporter);
                createSlabRecipe(RecipeCategory.BUILDING_BLOCKS, LemonWoodBlocks.LEMONWOOD_SLAB, Ingredient.ofItems(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_PLANKS), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.REDSTONE, LemonWoodBlocks.LEMONWOOD_BUTTON, 1)
                        .input(LemonWoodBlocks.LEMONWOOD_PLANKS, 1)
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_PLANKS), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .offerTo(recipeExporter);
                createPressurePlateRecipe(RecipeCategory.REDSTONE, LemonWoodBlocks.LEMONWOOD_PRESSURE_PLATE, Ingredient.ofItems(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_PLANKS), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .offerTo(recipeExporter);

                createFenceRecipe(LemonWoodBlocks.LEMONWOOD_FENCE, Ingredient.ofItems(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_PLANKS), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .offerTo(recipeExporter);
                createFenceGateRecipe(LemonWoodBlocks.LEMONWOOD_FENCE_GATE, Ingredient.ofItems(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_PLANKS), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .offerTo(recipeExporter);
                offerWallRecipe(RecipeCategory.BUILDING_BLOCKS, LemonWoodBlocks.LEMONWOOD_WALL, LemonWoodBlocks.LEMONWOOD_PLANKS);

                createDoorRecipe(LemonWoodBlocks.LEMONWOOD_DOOR, Ingredient.ofItems(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_PLANKS), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .offerTo(recipeExporter);
                createTrapdoorRecipe(LemonWoodBlocks.LEMONWOOD_TRAPDOOR, Ingredient.ofItems(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .criterion(hasItem(LemonWoodBlocks.LEMONWOOD_PLANKS), conditionsFromItem(LemonWoodBlocks.LEMONWOOD_PLANKS))
                        .offerTo(recipeExporter);


                createShapeless(RecipeCategory.BUILDING_BLOCKS, FireOakBlocks.FIRE_OAK_PLANKS, 4)
                        .input(FireOakBlocks.FIRE_OAK_LOG, 1)
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_LOG), conditionsFromItem(FireOakBlocks.FIRE_OAK_LOG))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "fire_oak_planks_from_fire_oak_log")));

                createShapeless(RecipeCategory.BUILDING_BLOCKS, FireOakBlocks.FIRE_OAK_PLANKS, 4)
                        .input(FireOakBlocks.STRIPPED_FIRE_OAK_LOG, 1)
                        .criterion(hasItem(FireOakBlocks.STRIPPED_FIRE_OAK_LOG), conditionsFromItem(FireOakBlocks.STRIPPED_FIRE_OAK_LOG))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "fire_oak_planks_from_stripped_fire_oak_log")));

                createShapeless(RecipeCategory.BUILDING_BLOCKS, FireOakBlocks.FIRE_OAK_PLANKS, 4)
                        .input(FireOakBlocks.FIRE_OAK_WOOD, 1)
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_WOOD), conditionsFromItem(FireOakBlocks.FIRE_OAK_WOOD))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "fire_oak_planks_from_fire_oak_wood")));

                createShapeless(RecipeCategory.BUILDING_BLOCKS, FireOakBlocks.FIRE_OAK_PLANKS, 4)
                        .input(FireOakBlocks.STRIPPED_FIRE_OAK_WOOD, 1)
                        .criterion(hasItem(FireOakBlocks.STRIPPED_FIRE_OAK_WOOD), conditionsFromItem(FireOakBlocks.STRIPPED_FIRE_OAK_WOOD))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "fire_oak_planks_from_stripped_fire_oak_wood")));

                createShaped(RecipeCategory.BUILDING_BLOCKS, FireOakBlocks.FIRE_OAK_WOOD, 3)
                        .pattern("## ")
                        .pattern("## ")
                        .pattern("   ")
                        .input('#', FireOakBlocks.FIRE_OAK_LOG)
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_LOG), conditionsFromItem(FireOakBlocks.FIRE_OAK_LOG))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.BUILDING_BLOCKS, FireOakBlocks.STRIPPED_FIRE_OAK_WOOD, 3)
                        .pattern("## ")
                        .pattern("## ")
                        .pattern("   ")
                        .input('#', FireOakBlocks.STRIPPED_FIRE_OAK_LOG)
                        .criterion(hasItem(FireOakBlocks.STRIPPED_FIRE_OAK_LOG), conditionsFromItem(FireOakBlocks.STRIPPED_FIRE_OAK_LOG))
                        .offerTo(recipeExporter);

                createStairsRecipe(FireOakBlocks.FIRE_OAK_STAIRS, Ingredient.ofItems(FireOakBlocks.FIRE_OAK_PLANKS))
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_PLANKS), conditionsFromItem(FireOakBlocks.FIRE_OAK_PLANKS))
                        .offerTo(recipeExporter);
                createSlabRecipe(RecipeCategory.BUILDING_BLOCKS, FireOakBlocks.FIRE_OAK_SLAB, Ingredient.ofItems(FireOakBlocks.FIRE_OAK_PLANKS))
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_PLANKS), conditionsFromItem(FireOakBlocks.FIRE_OAK_PLANKS))
                        .offerTo(recipeExporter);

                createShapeless(RecipeCategory.REDSTONE, FireOakBlocks.FIRE_OAK_BUTTON, 1)
                        .input(FireOakBlocks.FIRE_OAK_PLANKS, 1)
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_PLANKS), conditionsFromItem(FireOakBlocks.FIRE_OAK_PLANKS))
                        .offerTo(recipeExporter);
                createPressurePlateRecipe(RecipeCategory.REDSTONE, FireOakBlocks.FIRE_OAK_PRESSURE_PLATE, Ingredient.ofItems(FireOakBlocks.FIRE_OAK_PLANKS))
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_PLANKS), conditionsFromItem(FireOakBlocks.FIRE_OAK_PLANKS))
                        .offerTo(recipeExporter);

                createFenceRecipe(FireOakBlocks.FIRE_OAK_FENCE, Ingredient.ofItems(FireOakBlocks.FIRE_OAK_PLANKS))
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_PLANKS), conditionsFromItem(FireOakBlocks.FIRE_OAK_PLANKS))
                        .offerTo(recipeExporter);
                createFenceGateRecipe(FireOakBlocks.FIRE_OAK_FENCE_GATE, Ingredient.ofItems(FireOakBlocks.FIRE_OAK_PLANKS))
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_PLANKS), conditionsFromItem(FireOakBlocks.FIRE_OAK_PLANKS))
                        .offerTo(recipeExporter);
                offerWallRecipe(RecipeCategory.BUILDING_BLOCKS, FireOakBlocks.FIRE_OAK_WALL, FireOakBlocks.FIRE_OAK_PLANKS);

                createDoorRecipe(FireOakBlocks.FIRE_OAK_DOOR, Ingredient.ofItems(FireOakBlocks.FIRE_OAK_PLANKS))
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_PLANKS), conditionsFromItem(FireOakBlocks.FIRE_OAK_PLANKS))
                        .offerTo(recipeExporter);
                createTrapdoorRecipe(FireOakBlocks.FIRE_OAK_TRAPDOOR, Ingredient.ofItems(FireOakBlocks.FIRE_OAK_PLANKS))
                        .criterion(hasItem(FireOakBlocks.FIRE_OAK_PLANKS), conditionsFromItem(FireOakBlocks.FIRE_OAK_PLANKS))
                        .offerTo(recipeExporter);

                SwordRecipeJsonBuilder(recipeExporter, PrismaSteelItems.PRISMA_STEEL_SWORD, PrismaSteelItems.PRISMA_STEEL, Items.STICK, PrismaSteelItems.PRISMA_STEEL);
                PickaxeRecipeJsonBuilder(recipeExporter, PrismaSteelItems.PRISMA_STEEL_PICKAXE, PrismaSteelItems.PRISMA_STEEL, Items.STICK, PrismaSteelItems.PRISMA_STEEL);
                HammerRecipeJsonBuilder(recipeExporter, PrismaSteelItems.PRISMA_STEEL_HAMMER, PrismaSteelItems.PRISMA_STEEL, ModBlocks.PRISMA_STEEL_BLOCK, Items.STICK, PrismaSteelItems.PRISMA_STEEL);
                AxeRecipeJsonBuilder(recipeExporter, PrismaSteelItems.PRISMA_STEEL_AXE, PrismaSteelItems.PRISMA_STEEL, Items.STICK, PrismaSteelItems.PRISMA_STEEL);
                ShovelRecipeJsonBuilder(recipeExporter, PrismaSteelItems.PRISMA_STEEL_SHOVEL, PrismaSteelItems.PRISMA_STEEL, Items.STICK, PrismaSteelItems.PRISMA_STEEL);
                HoeRecipeJsonBuilder(recipeExporter, PrismaSteelItems.PRISMA_STEEL_HOE, PrismaSteelItems.PRISMA_STEEL, Items.STICK, PrismaSteelItems.PRISMA_STEEL);

                SwordRecipeJsonBuilder(recipeExporter, AshenSteelItems.ASHEN_STEEL_SWORD, AshenSteelItems.ASHEN_STEEL, Items.STICK, AshenSteelItems.ASHEN_STEEL);
                PickaxeRecipeJsonBuilder(recipeExporter, AshenSteelItems.ASHEN_STEEL_PICKAXE, AshenSteelItems.ASHEN_STEEL, Items.STICK, AshenSteelItems.ASHEN_STEEL);
                HammerRecipeJsonBuilder(recipeExporter, AshenSteelItems.ASHEN_STEEL_HAMMER, AshenSteelItems.ASHEN_STEEL, ModBlocks.ASHEN_STEEL_BLOCK, Items.STICK, AshenSteelItems.ASHEN_STEEL);
                AxeRecipeJsonBuilder(recipeExporter, AshenSteelItems.ASHEN_STEEL_AXE, AshenSteelItems.ASHEN_STEEL, Items.STICK, AshenSteelItems.ASHEN_STEEL);
                ShovelRecipeJsonBuilder(recipeExporter, AshenSteelItems.ASHEN_STEEL_SHOVEL, AshenSteelItems.ASHEN_STEEL, Items.STICK, AshenSteelItems.ASHEN_STEEL);
                HoeRecipeJsonBuilder(recipeExporter, AshenSteelItems.ASHEN_STEEL_HOE, AshenSteelItems.ASHEN_STEEL, Items.STICK, AshenSteelItems.ASHEN_STEEL);

                ModArmorRecipeJsonBuilder(recipeExporter, PrismaSteelItems.PRISMA_STEEL_HELMET, PrismaSteelItems.PRISMA_STEEL_CHESTPLATE, PrismaSteelItems.PRISMA_STEEL_LEGGINGS, PrismaSteelItems.PRISMA_STEEL_BOOTS, PrismaSteelItems.PRISMA_STEEL, PrismaSteelItems.PRISMA_STEEL);
                ModArmorRecipeJsonBuilder(recipeExporter, AshenSteelItems.ASHEN_STEEL_HELMET, AshenSteelItems.ASHEN_STEEL_CHESTPLATE, AshenSteelItems.ASHEN_STEEL_LEGGINGS, AshenSteelItems.ASHEN_STEEL_BOOTS, AshenSteelItems.ASHEN_STEEL, AshenSteelItems.ASHEN_STEEL);
                ModArmorRecipeJsonBuilder(recipeExporter, FractalDiamondItems.FRACTAL_DIAMOND_HELMET, FractalDiamondItems.FRACTAL_DIAMOND_CHESTPLATE, FractalDiamondItems.FRACTAL_DIAMOND_LEGGINGS, FractalDiamondItems.FRACTAL_DIAMOND_BOOTS, FractalDiamondItems.FRACTAL_DIAMOND, FractalDiamondItems.FRACTAL_DIAMOND);
                ModArmorRecipeJsonBuilder(recipeExporter, HellfireDiamondItems.HELLFIRE_DIAMOND_HELMET, HellfireDiamondItems.HELLFIRE_DIAMOND_CHESTPLATE, HellfireDiamondItems.HELLFIRE_DIAMOND_LEGGINGS, HellfireDiamondItems.HELLFIRE_DIAMOND_BOOTS, HellfireDiamondItems.HELLFIRE_DIAMOND, HellfireDiamondItems.HELLFIRE_DIAMOND);

                offerSmithingTrimRecipe(PrismaSteelItems.PRISMA_SMITHING_TEMPLATE, ModTrimPatterns.PRISMA, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "prisma")));
                offerSmithingTrimRecipe(AshenSteelItems.ASHEN_SMITHING_TEMPLATE, ModTrimPatterns.ASHEN, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, "ashen")));

                // For 2+ recipes with the same RESULT use
                // .offerTo(recipeExporter, Identifier.of(AcesBS.MOD_ID, "output_item_from_input_item"));
            }

            private void SwordRecipeJsonBuilder(RecipeExporter recipeExporter, ItemConvertible result, ItemConvertible headMaterial, ItemConvertible handleMaterial, ItemConvertible criterionItem){
                createShaped(RecipeCategory.COMBAT, result)
                        .pattern(" # ")
                        .pattern(" # ")
                        .pattern(" I ")
                        .input('#', headMaterial)
                        .input('I', handleMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter);
            }
            private void PickaxeRecipeJsonBuilder(RecipeExporter recipeExporter, ItemConvertible result, ItemConvertible headMaterial, ItemConvertible handleMaterial, ItemConvertible criterionItem){
                createShaped(RecipeCategory.TOOLS, result)
                        .pattern("###")
                        .pattern(" I ")
                        .pattern(" I ")
                        .input('#', headMaterial)
                        .input('I', handleMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter);
            }
            private void HammerRecipeJsonBuilder(RecipeExporter recipeExporter, ItemConvertible result, ItemConvertible headMaterial, ItemConvertible headMaterialBlock, ItemConvertible handleMaterial, ItemConvertible criterionItem){
                createShaped(RecipeCategory.TOOLS, result)
                        .pattern("B#B")
                        .pattern(" I ")
                        .pattern(" I ")
                        .input('B', headMaterialBlock)
                        .input('#', headMaterial)
                        .input('I', handleMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter);
            }
            private void AxeRecipeJsonBuilder(RecipeExporter recipeExporter, ItemConvertible result, ItemConvertible headMaterial, ItemConvertible handleMaterial, ItemConvertible criterionItem){
                createShaped(RecipeCategory.TOOLS, result)
                        .pattern("## ")
                        .pattern("#I ")
                        .pattern(" I ")
                        .input('#', headMaterial)
                        .input('I', handleMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, result.asItem().getName().getString() + ".left")));
                createShaped(RecipeCategory.TOOLS, result)
                        .pattern(" ##")
                        .pattern(" I#")
                        .pattern(" I ")
                        .input('#', headMaterial)
                        .input('I', handleMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, result.asItem().getName().getString() + ".right")));
            }
            private void ShovelRecipeJsonBuilder(RecipeExporter recipeExporter, ItemConvertible result, ItemConvertible headMaterial, ItemConvertible handleMaterial, ItemConvertible criterionItem){
                createShaped(RecipeCategory.TOOLS, result)
                        .pattern(" # ")
                        .pattern(" I ")
                        .pattern(" I ")
                        .input('#', headMaterial)
                        .input('I', handleMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter);
            }
            private void HoeRecipeJsonBuilder(RecipeExporter recipeExporter, ItemConvertible result, ItemConvertible headMaterial, ItemConvertible handleMaterial, ItemConvertible criterionItem){
                createShaped(RecipeCategory.TOOLS, result)
                        .pattern("## ")
                        .pattern(" I ")
                        .pattern(" I ")
                        .input('#', headMaterial)
                        .input('I', handleMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, result.asItem().getName().getString() + ".left")));
                createShaped(RecipeCategory.TOOLS, result)
                        .pattern(" ##")
                        .pattern(" I ")
                        .pattern(" I ")
                        .input('#', headMaterial)
                        .input('I', handleMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter, RegistryKey.of(RegistryKeys.RECIPE, Identifier.of(AcesBS.MOD_ID, result.asItem().getName().getString() + ".right")));
            }

            private void ModArmorRecipeJsonBuilder(RecipeExporter recipeExporter, ItemConvertible helmetResult, ItemConvertible chestplateResult, ItemConvertible leggingsResult, ItemConvertible bootsResult, ItemConvertible baseMaterial, ItemConvertible criterionItem){
                createShaped(RecipeCategory.COMBAT, helmetResult)
                        .pattern("###")
                        .pattern("# #")
                        .pattern("   ")
                        .input('#', baseMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.COMBAT, chestplateResult)
                        .pattern("# #")
                        .pattern("###")
                        .pattern("###")
                        .input('#', baseMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.COMBAT, leggingsResult)
                        .pattern("###")
                        .pattern("# #")
                        .pattern("# #")
                        .input('#', baseMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter);

                createShaped(RecipeCategory.COMBAT, bootsResult)
                        .pattern("   ")
                        .pattern("# #")
                        .pattern("# #")
                        .input('#', baseMaterial)
                        .criterion(hasItem(criterionItem), conditionsFromItem(criterionItem))
                        .offerTo(recipeExporter);
            }

            public void offerAllFoodCookingRecipes (int baseCookingTime, ItemConvertible raw_item, ItemConvertible cooked_item, float experience ){
                offerFoodCookingRecipe("smoking", RecipeSerializer.SMOKING, SmokingRecipe::new,baseCookingTime/2, raw_item, cooked_item, experience);
                offerFoodCookingRecipe("campfire_cooking", RecipeSerializer.CAMPFIRE_COOKING, CampfireCookingRecipe::new, baseCookingTime*3, raw_item, cooked_item, experience);
                offerFoodCookingRecipe("smelting", RecipeSerializer.SMELTING, SmeltingRecipe::new, baseCookingTime, raw_item, cooked_item, experience);
            }
        };
    }

    @Override
    public String getName() {
        return "AcesBS Recipes";
    }
}
