package com.acethewildfire.acesbs.block;

import com.acethewildfire.acesbs.AcesBS;
import com.acethewildfire.acesbs.block.custom.*;
import com.acethewildfire.acesbs.sounds.ModSounds;
import com.acethewildfire.acesbs.world.tree.ModBlockSaplingGenerator;
import com.mojang.serialization.MapCodec;
import net.minecraft.block.*;
import net.minecraft.block.enums.NoteBlockInstrument;
import net.minecraft.block.piston.PistonBehavior;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.intprovider.UniformIntProvider;

import java.util.function.ToIntFunction;

import static net.minecraft.block.Blocks.createFlowerPotBlock;

public class ModBlocks {

    public static final Block ENTROPY_BLOCK = registerBlock("entropy_block",
            new EntropyBlock(AbstractBlock.Settings.create()
                    .strength(3f)
                    .requiresTool()
                    .sounds(BlockSoundGroup.AMETHYST_BLOCK)));
    public static final Block ENTROPY_ORE = registerBlock("entropy_ore",
            new ExperienceDroppingBlock(UniformIntProvider.create(3, 7),
                    AbstractBlock.Settings.create()
                            .strength(3.0F, 3.0F)
                            .mapColor(MapColor.STONE_GRAY)
                            .requiresTool()
                            .sounds(BlockSoundGroup.STONE)));

    public static final Block DEEPSLATE_ENTROPY_ORE = registerBlock("deepslate_entropy_ore",
            new ExperienceDroppingBlock(UniformIntProvider.create(3, 7),
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.DEEPSLATE_GRAY)
                            .strength(4.5F, 3.0F)
                            .requiresTool()
                            .sounds(BlockSoundGroup.DEEPSLATE)));

    public static final Block ENDTROPY_ORE = registerBlock("endtropy_ore",
            new ExperienceDroppingBlock(UniformIntProvider.create(3, 7),
                   AbstractBlock.Settings.create()
                           .mapColor(MapColor.PALE_YELLOW)
                           .requiresTool()
                           .strength(3.0F, 9.0F)));

    public static final Block INFERNAL_ASHES_ORE = registerBlock("infernal_ashes_ore",
            new ExperienceDroppingBlock(
                    UniformIntProvider.create(0, 1),
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.DARK_RED)
                            .requiresTool()
                            .strength(3.0F, 3.0F)
                            .sounds(BlockSoundGroup.NETHER_GOLD_ORE)));

    public static final Block STABLE_ENTROPY_BLOCK = registerBlock("stable_entropy_block",
            new StableEntropyBlock(AbstractBlock.Settings.create()
                    .strength(5f)
                    .luminance(new ToIntFunction<BlockState>() {
                        @Override
                        public int applyAsInt(BlockState value) {
                            return 7;
                        }
                    })
                    .requiresTool()
                    .sounds(BlockSoundGroup.LODESTONE)));

    public static final Block ENTROPIC_STABILIZER = registerBlock("entropic_stabilizer",
            new EntropicStabilizer(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.LIGHT_GRAY)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.METAL)
                            .requiresTool()
            ));

    public static final Block ENTROPIC_EVISCERATOR = registerBlock("entropic_eviscerator",
            new EntropicEviscerator(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.LIGHT_GRAY)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.METAL)
                            .requiresTool()
            ));
    public static final Block ENTROPIC_ENTANGLER = registerBlock("entropic_entangler",
            new EntropicEntangler(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.LIGHT_GRAY)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.METAL)
                            .requiresTool()
            ));


    public static final Block LEMONWOOD_LOG = registerBlock("lemonwood_log",
            new PillarBlock(AbstractBlock.Settings.copy(Blocks.BIRCH_LOG)));
    public static final Block LEMONWOOD_WOOD = registerBlock("lemonwood_wood",
            new PillarBlock(AbstractBlock.Settings.copy(Blocks.BIRCH_WOOD).mapColor(MapColor.PALE_YELLOW)));
    public static final Block STRIPPED_LEMONWOOD_LOG = registerBlock("stripped_lemonwood_log",
            new PillarBlock(AbstractBlock.Settings.copy(Blocks.STRIPPED_BIRCH_LOG)));
    public static final Block STRIPPED_LEMONWOOD_WOOD = registerBlock("stripped_lemonwood_wood",
            new PillarBlock(AbstractBlock.Settings.copy(Blocks.STRIPPED_BIRCH_WOOD).mapColor(MapColor.PALE_YELLOW)));

    public static final Block LEMONWOOD_LEAVES = registerBlock("lemonwood_leaves",
            new LeavesBlock(AbstractBlock.Settings.copy(Blocks.BIRCH_LEAVES)));
    public static final Block LEMONWOOD_SAPLING = registerBlock("lemonwood_sapling",
            new SaplingBlock(ModBlockSaplingGenerator.LEMONWOOD, AbstractBlock.Settings.copy(Blocks.BIRCH_SAPLING)));

    public static final Block POTTED_LEMONWOOD_SAPLING = registerBlock("potted_lemonwood_sapling", createFlowerPotBlock(LEMONWOOD_SAPLING));

    public static final Block LEMONWOOD_PLANKS = registerBlock("lemonwood_planks",
            new Block(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .instrument(NoteBlockInstrument.BASS)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
            ));


    public static final Block LEMONWOOD_STAIRS = registerBlock("lemonwood_stairs",
            new StairsBlock(ModBlocks.LEMONWOOD_PLANKS.getDefaultState(),
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
            ));
    public static final Block LEMONWOOD_SLAB = registerBlock("lemonwood_slab",
            new SlabBlock(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
            ));

    public static final Block LEMONWOOD_BUTTON = registerBlock("lemonwood_button",
            new ButtonBlock(BlockSetType.BIRCH, 10,
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
                            .noCollision()
            ));
    public static final Block LEMONWOOD_PRESSURE_PLATE = registerBlock("lemonwood_pressure_plate",
            new PressurePlateBlock(BlockSetType.BIRCH,
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
            ));

    public static final Block LEMONWOOD_FENCE = registerBlock("lemonwood_fence",
            new FenceBlock(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
            ));
    public static final Block LEMONWOOD_FENCE_GATE = registerBlock("lemonwood_fence_gate",
            new FenceGateBlock(WoodType.BIRCH,
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
            ));
    public static final Block LEMONWOOD_WALL = registerBlock("lemonwood_wall",
            new WallBlock(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
            ));

    public static final Block LEMONWOOD_DOOR = registerBlock("lemonwood_door",
            new DoorBlock(BlockSetType.BIRCH,
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
                            .nonOpaque()
            ));
    public static final Block LEMONWOOD_TRAPDOOR = registerBlock("lemonwood_trapdoor",
            new TrapdoorBlock(BlockSetType.BIRCH,
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.PALE_YELLOW)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
                            .nonOpaque()
            ));

    public static final Block LIZARD_PLANKS = registerBlock("lizard_planks",
            new Block(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.DARK_GREEN)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
            ));

    public static final Block LIZARD_BUTTON = registerBlock("lizard_button",
            new ButtonBlock(BlockSetType.BIRCH, 1,
                   AbstractBlock.Settings.create()
                            .mapColor(MapColor.DARK_GREEN)
                            .strength(2.0F, 3.0F)
                            .sounds(BlockSoundGroup.WOOD)
                            .burnable()
                            .noCollision()
            ){
                private final BlockSetType blockSetType = BlockSetType.BIRCH;

//                @Override
//                protected void playClickSound(@Nullable PlayerEntity player, WorldAccess world, BlockPos pos, boolean powered) {
//                    world.playSound(powered ? player : null, pos, ModSounds.LIZARD, SoundCategory.BLOCKS);
//                }
                @Override
                protected SoundEvent getClickSound(boolean powered) {
                    return powered ? ModSounds.LIZARD : this.blockSetType.buttonClickOff();
                }
            });

    public static final Block EVIL_BLOCK = registerBlock("evil_block",
            new EvilBlock(AbstractBlock.Settings.create()
                    .strength(5f)
                    .luminance(state -> state.get(EvilBlock.CLICKED) ? 15 : 0)
                    .requiresTool()
                    .sounds(BlockSoundGroup.LODESTONE)));

    public static final Block PRISMA_STEEL_BLOCK = registerBlock(
    "prisma_steel_block",
            new Block(
            AbstractBlock.Settings.create()
				.mapColor(MapColor.IRON_GRAY)
				.instrument(NoteBlockInstrument.IRON_XYLOPHONE)
				.requiresTool()
				.strength(5.0F, 6.0F)
				.sounds(BlockSoundGroup.METAL)
		)
    );

    public static final Block INFERNAL_ASHES_BLOCK = registerBlock(
            "infernal_ashes_block",
            new FallingBlock(
                    AbstractBlock.Settings.create()
                            .mapColor(MapColor.LIGHT_GRAY)
                            .instrument(NoteBlockInstrument.SNARE)
                            .strength(0.5F)
                            .sounds(BlockSoundGroup.SAND)
            ) {
                @Override
                protected MapCodec<? extends FallingBlock> getCodec() {
                    return null;
                }
            }
    );

    public static final Block CRYSTAL_ENTROPY = registerBlock(
            "crystal_entropy",
            new TransparentBlock(
                    AbstractBlock.Settings.create()
                            .instrument(NoteBlockInstrument.HAT)
                            .strength(0.3F)
                            .sounds(BlockSoundGroup.GLASS)
                            .nonOpaque()
                            .allowsSpawning(Blocks::never)
                            .solidBlock(Blocks::never)
                            .suffocates(Blocks::never)
                            .blockVision(Blocks::never)
            )
    );

    public static final Block CRYSTAL_ENTROPY_PANE = registerBlock(
            "crystal_entropy_pane",
            new PaneBlock(
                    AbstractBlock.Settings.create()
                            .instrument(NoteBlockInstrument.HAT)
                            .strength(0.3F)
                            .sounds(BlockSoundGroup.GLASS)
                            .nonOpaque()
            )
    );

    public static final Block TOBACCO_CROP = registerBlockWithoutItem("tobacco_crop", new TobaccoCrop(
            AbstractBlock.Settings.create()
                    .mapColor(MapColor.DARK_GREEN)
                    .noCollision()
                    .ticksRandomly()
                    .breakInstantly()
                    .sounds(BlockSoundGroup.CROP)
                    .pistonBehavior(PistonBehavior.DESTROY)
    ));

    private static Block registerBlockWithoutItem(String name, Block block){
        return Registry.register(Registries.BLOCK, Identifier.of(AcesBS.MOD_ID, name), block);
    }

    private static Block registerBlock(String name, Block block){
        registerBlockItem(name, block);
        return Registry.register(Registries.BLOCK, Identifier.of(AcesBS.MOD_ID, name), block);
    }

    private static void registerBlockItem(String name, Block block){
        Registry.register(Registries.ITEM, Identifier.of(AcesBS.MOD_ID, name),
                new BlockItem(block, new Item.Settings()));
    }

    public static void registerModBlocks(){
        AcesBS.LOGGER.info("Registering Mod Blocks for " + AcesBS.MOD_ID);

//        ItemGroupEvents.modifyEntriesEvent(ItemGroups.BUILDING_BLOCKS).register(fabricItemGroupEntries -> {
//            fabricItemGroupEntries.add(ENTROPY_BLOCK);
//        });
    }
}
