package com.thebrokenrail.twine.block;

import com.thebrokenrail.twine.util.ItemUtil;
import com.thebrokenrail.twine.util.block.DirectionalBlock;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.dispenser.DispenserBehavior;
import net.minecraft.block.dispenser.ItemDispenserBehavior;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPointer;
import net.minecraft.util.math.BlockPointerImpl;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;

import java.util.List;
import java.util.Random;

@SuppressWarnings("deprecation")
public class CreativeItemSpawnerBlock extends DirectionalBlock {
    public static final BooleanProperty TRIGGERED = Properties.TRIGGERED;

    public CreativeItemSpawnerBlock() {
        super(Settings.of(Material.STONE).strength(-1.0F, 3600000.0F).dropsNothing());
        setDefaultState(stateManager.getDefaultState().with(TRIGGERED, false));
    }

    @Override
    protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
        super.appendProperties(builder);
        builder.add(TRIGGERED);
    }

    @Override
    public void neighborUpdate(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
        boolean bl = world.isReceivingRedstonePower(pos) || world.isReceivingRedstonePower(pos.up());
        boolean bl2 = state.get(TRIGGERED);
        if (bl && !bl2) {
            world.getBlockTickScheduler().schedule(pos, this, 4);
            world.setBlockState(pos, state.with(TRIGGERED, true), 4);
        } else if (!bl && bl2) {
            world.setBlockState(pos, state.with(TRIGGERED, false), 4);
        }
    }

    @Override
    public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
        dispense(world, pos, state);
    }

    private void dispense(World world, BlockPos pos, BlockState state) {
        DispenserBehavior behavior = new ItemDispenserBehavior() {
            @Override
            protected void playSound(BlockPointer pointer) {
                pointer.getWorld().playSound(null, pointer.getBlockPos(), SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.BLOCKS, 1f, 1f);
            }
        };
        BlockPos invPos = pos.offset(state.get(FACING).getOpposite());
        BlockEntity entity = world.getBlockEntity(invPos);
        if (entity instanceof Inventory) {
            BlockPointerImpl blockPointerImpl = new BlockPointerImpl(world, pos);
            int size = ((Inventory) entity).size();
            for (int i = 0; i < size; i++) {
                ItemStack stack = ((Inventory) entity).getStack(i).copy();
                while (!stack.isEmpty()) {
                    stack = behavior.dispense(blockPointerImpl, stack);
                }
            }
        }
    }

    @Override
    @Environment(EnvType.CLIENT)
    public void buildTooltip(ItemStack stack, BlockView world, List<Text> tooltip, TooltipContext options) {
        super.buildTooltip(stack, world, tooltip, options);
        ItemUtil.addTooltip("block", "creative_item_spawner", 3, tooltip);
    }
}
