package net.halbear.aotg.registries;

import net.halbear.aotg.AgeoftheGods;
import net.halbear.aotg.custom.WorldGen.GenerationFeatures.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstrapContext;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.valueproviders.ConstantInt;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.BlockBlobConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration;
import net.minecraft.world.level.levelgen.feature.featuresize.TwoLayersFeatureSize;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
import net.neoforged.fml.common.Mod;

public class ModConfiguredFeatures {
    public static final ResourceKey<ConfiguredFeature<?, ?>> TWISTY_TREE_KEY =
            ResourceKey.create(Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "maquis_tall_twisty_tree"));
    public static final ResourceKey<ConfiguredFeature<?, ?>> MAQUIS_SHORT_TWISTY_TREE_KEY =
            ResourceKey.create(Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "maquis_short_twisty_tree"));
    public static final ResourceKey<ConfiguredFeature<?, ?>> GARRIGUE_TWISTY_TREE =
            ResourceKey.create(Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "garrigue_short_twisty_tree"));
    public static final ResourceKey<ConfiguredFeature<?, ?>> TALL_THIN_TWISTY_TREE =
            ResourceKey.create(Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "tall_thin_twisty_tree"));
    public static final ResourceKey<ConfiguredFeature<?, ?>> SHORT_THIN_TWISTY_TREE =
            ResourceKey.create(Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "short_thin_twisty_tree"));
    public static final ResourceKey<ConfiguredFeature<?, ?>> GRANITE_BOULDER = ResourceKey.create(
            Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "granite_boulder"));
    public static final ResourceKey<ConfiguredFeature<?, ?>> SHALE_BOULDER = ResourceKey.create(
            Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "shale_boulder"));
    public static final ResourceKey<ConfiguredFeature<?, ?>> GRAVEL_BOULDER = ResourceKey.create(
            Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "gravel_boulder"));
    public static final ResourceKey<ConfiguredFeature<?, ?>> LIMESTONE_BOULDER = ResourceKey.create(
            Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "limestone_boulder"));

    public static void bootstrap(BootstrapContext<ConfiguredFeature<?, ?>> context) {
        context.register(SHORT_THIN_TWISTY_TREE, new ConfiguredFeature<>(
                Feature.TREE,
                new TreeConfiguration.TreeConfigurationBuilder(
                        BlockStateProvider.simple(ModBlocks.OLIVE_LOG.get().defaultBlockState()),
                        new ThinShortTwistyBranchingTrunkPlacer(5, 4, 5),
                        BlockStateProvider.simple(ModBlocks.OLIVE_LEAVES.get().defaultBlockState()),
                        new LeafBunchFoliagePlacer(ConstantInt.of(1),ConstantInt.of(0)),
                        new TwoLayersFeatureSize(3, 1, 3)
                ).build()
        ));
        context.register(TALL_THIN_TWISTY_TREE, new ConfiguredFeature<>(
                Feature.TREE,
                new TreeConfiguration.TreeConfigurationBuilder(
                        BlockStateProvider.simple(ModBlocks.OLIVE_LOG.get().defaultBlockState()),
                        new ThinTwistyBranchingTrunkPlacer(12, 10, 10),
                        BlockStateProvider.simple(ModBlocks.OLIVE_LEAVES.get().defaultBlockState()),
                        new LeafBunchFoliagePlacer(ConstantInt.of(1),ConstantInt.of(0)),
                        new TwoLayersFeatureSize(3, 1, 3)
                ).build()
        ));
        context.register(TWISTY_TREE_KEY, new ConfiguredFeature<>(
                Feature.TREE,
                new TreeConfiguration.TreeConfigurationBuilder(
                        BlockStateProvider.simple(Blocks.OAK_LOG.defaultBlockState()),
                        new TwistyBranchingTrunkPlacer(15, 15, 15),
                        BlockStateProvider.simple(Blocks.OAK_LEAVES.defaultBlockState()),
                        new LeafBunchFoliagePlacer(ConstantInt.of(1),ConstantInt.of(0)),
                        new TwoLayersFeatureSize(5, 3, 5)
                ).build()
        ));
        context.register(GARRIGUE_TWISTY_TREE, new ConfiguredFeature<>(
                Feature.TREE,
                new TreeConfiguration.TreeConfigurationBuilder(
                        BlockStateProvider.simple(ModBlocks.OLIVE_LOG.get().defaultBlockState()),
                        new BushTwistyBranchingTrunkPlacer(2, 3, 3),
                        BlockStateProvider.simple(ModBlocks.OLIVE_LEAVES.get().defaultBlockState()),
                        new LeafBunchFoliagePlacer(ConstantInt.of(1),ConstantInt.of(0)),
                        new TwoLayersFeatureSize(3, 1, 3)
                ).build()
        ));
        context.register(MAQUIS_SHORT_TWISTY_TREE_KEY, new ConfiguredFeature<>(
                Feature.TREE,
                new TreeConfiguration.TreeConfigurationBuilder(
                        BlockStateProvider.simple(Blocks.OAK_LOG.defaultBlockState()),
                        new ThinTwistyBranchingTrunkPlacer(3, 3, 3),
                        BlockStateProvider.simple(Blocks.OAK_LEAVES.defaultBlockState()),
                        new LeafBunchFoliagePlacer(ConstantInt.of(1),ConstantInt.of(0)),
                        new TwoLayersFeatureSize(5, 3, 5)
                ).build()
        ));
        BlockBlobConfiguration config = new BlockBlobConfiguration(
                Blocks.GRANITE.defaultBlockState(),
                BlockPredicate.matchesBlocks(
                        new BlockPos(0, -1, 0),
                        ModBlocks.SHALE_GRASS_BLOCK.get(),
                        Blocks.SANDSTONE,
                        ModBlocks.SHALE_BLOCK.get(),
                        ModBlocks.LIMESTONE_GRASS_BLOCK.get()
                )
        );

        context.register(GRANITE_BOULDER, new ConfiguredFeature<>(Feature.BLOCK_BLOB, config));

        config = new BlockBlobConfiguration(
                ModBlocks.SHALE_BLOCK.get().defaultBlockState(),
                BlockPredicate.matchesBlocks(
                        new BlockPos(0, -1, 0),
                        ModBlocks.SHALE_GRASS_BLOCK.get(),
                        Blocks.SANDSTONE,
                        ModBlocks.SHALE_BLOCK.get(),
                        ModBlocks.LIMESTONE_GRASS_BLOCK.get()
                )
        );

        context.register(SHALE_BOULDER, new ConfiguredFeature<>(Feature.BLOCK_BLOB, config));
        config = new BlockBlobConfiguration(
                Blocks.GRAVEL.defaultBlockState(),
                BlockPredicate.matchesBlocks(
                        new BlockPos(0, -1, 0),
                        ModBlocks.SHALE_GRASS_BLOCK.get(),
                        Blocks.SANDSTONE,
                        ModBlocks.SHALE_BLOCK.get(),
                        ModBlocks.LIMESTONE_GRASS_BLOCK.get()
                )
        );

        context.register(GRAVEL_BOULDER, new ConfiguredFeature<>(Feature.BLOCK_BLOB, config));

        config = new BlockBlobConfiguration(
                ModBlocks.LIMESTONE_BLOCK.get().defaultBlockState(),
                BlockPredicate.matchesBlocks(
                        new BlockPos(0, -1, 0),
                        ModBlocks.SHALE_GRASS_BLOCK.get(),
                        Blocks.SANDSTONE,
                        ModBlocks.SHALE_BLOCK.get(),
                        ModBlocks.LIMESTONE_GRASS_BLOCK.get()
                )
        );

        context.register(LIMESTONE_BOULDER, new ConfiguredFeature<>(Feature.BLOCK_BLOB, config));
    }
}
