package top.r3944realms.lib39.util.block;

import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.mixin.minecraft.CreativeModeTabsAccessor;
import top.r3944realms.lib39.platform.Services;

import java.util.function.BiFunction;
import java.util.function.Supplier;

/**
 * The type Block registry builder.
 */
@SuppressWarnings({"UnusedReturnValue", "unused"})
public abstract class BlockRegistryBuilder {
    private String registryName;
    private Supplier<Block> blockObject;
    private BiFunction<String, Supplier<Item>, Supplier<Item>> blockItemRegister;
    private boolean needBuildItem;
    private Item.Properties properties;

    /**
     * Create block registry builder.
     *
     * @return the block registry builder
     */
    public static BlockRegistryBuilder create() {
        return Services.PLATFORM.getUtilHelper().getBlockRegistryBuilder();
    }

    /**
     * 设置注册名称
     *
     * @param name the name
     * @return the block registry builder
     */
    public BlockRegistryBuilder withName(String name) {
        this.registryName = name;
        return this;
    }

    /**
     * 注册方块（不自动注册物品）
     *
     * @param blockRegister the block register
     * @param blockSupplier the block supplier
     * @return the block registry builder
     */
    public BlockRegistryBuilder registerBlock(@NotNull BiFunction<String, Supplier<Block>,Supplier<Block>> blockRegister, Supplier<Block> blockSupplier) {
        this.blockObject = blockRegister.apply(this.registryName, blockSupplier);
        return this;
    }

    /**
     * 注册对应的方块物品
     *
     * @param itemRegister the item deferred register
     * @return the block registry builder
     */
    public BlockRegistryBuilder registerItem(BiFunction<String, Supplier<Item>,Supplier<Item>> itemRegister) {
        this.blockItemRegister = itemRegister;
        needBuildItem = true;
        return this;
    }

    /**
     * 注册对应的方块带有对应属性物品
     *
     * @param itemRegister the item deferred register
     * @param properties   the item properties
     * @return the block registry builder
     */
    public BlockRegistryBuilder registerItemWithProperties(BiFunction<String, Supplier<Item>,Supplier<Item>> itemRegister, Item.Properties properties) {
        this.blockItemRegister = itemRegister;
        this.properties = properties;
        needBuildItem = true;
        return this;
    }

    /**
     * 对应的方块物品属性
     *
     * @param properties the item properties
     * @return the block registry builder
     */
    public BlockRegistryBuilder ItemProperties(Item.Properties properties) {
        this.properties = properties;
        return this;
    }

    /**
     * 内部方法：注册对应的方块物品
     *
     * @param blockObject  the block object
     * @param creativeTabs the creative tabs
     */
    protected abstract void registerBlockItem(Supplier<Block> blockObject, ResourceKey<CreativeModeTab>... creativeTabs);

    /**
     * 注册方块和物品到建筑标签页
     *
     * @param blockRegister the block register
     * @param blockSupplier the block supplier
     * @return the block registry builder
     */
    public BlockRegistryBuilder registerWithBuildingTab(BiFunction<String, Supplier<Block>,Supplier<Block>> blockRegister, Supplier<Block> blockSupplier) {
        registerBlock(blockRegister, blockSupplier);
        registerBlockItem(this.blockObject, CreativeModeTabsAccessor.getBuildingBlocks());
        return this;
    }

    /**
     * 注册方块和物品到功能标签页
     *
     * @param blockRegister the block register
     * @param blockSupplier the block supplier
     * @return the block registry builder
     */
    public BlockRegistryBuilder registerWithFunctionalTab(BiFunction<String, Supplier<Block>,Supplier<Block>> blockRegister, Supplier<Block> blockSupplier) {
        registerBlock(blockRegister, blockSupplier);
        registerBlockItem(this.blockObject, CreativeModeTabsAccessor.getFunctionalBlocks());
        return this;
    }

    /**
     * 获取注册的方块对象
     *
     * @return the registry object
     */
    public Supplier<Block> build() {
        if (needBuildItem) {
            blockItemRegister.apply(this.registryName, () -> new BlockItem(this.blockObject.get(), properties == null ? new Item.Properties() : properties));
        }
        return this.blockObject;
    }

}
