package net.minecraft.core.dispenser;

import com.mojang.logging.LogUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.DirectionalPlaceContext;
import net.minecraft.world.level.block.DispenserBlock;
import org.slf4j.Logger;

public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior {
    private static final Logger LOGGER = LogUtils.getLogger();

    @Override
    protected ItemStack execute(BlockSource blockSource, ItemStack item) {
        this.setSuccess(false);
        Item item1 = item.getItem();
        if (item1 instanceof BlockItem) {
            Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
            BlockPos blockPos = blockSource.pos().relative(direction);
            Direction direction1 = blockSource.level().isEmptyBlock(blockPos.below()) ? direction : Direction.UP;

            // CraftBukkit start
            org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(blockSource.level(), blockSource.pos());
            org.bukkit.craftbukkit.inventory.CraftItemStack craftItem = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1));

            org.bukkit.event.block.BlockDispenseEvent event = new org.bukkit.event.block.BlockDispenseEvent(bukkitBlock, craftItem.clone(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(blockPos));
            blockSource.level().getCraftServer().getPluginManager().callEvent(event);

            if (event.isCancelled()) {
                return item;
            }

            if (!event.getItem().equals(craftItem)) {
                // Chain to handler for new item
                ItemStack eventStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem());
                DispenseItemBehavior dispenseBehavior = DispenserBlock.getDispenseBehavior(blockSource, eventStack);
                if (dispenseBehavior != DispenseItemBehavior.NOOP && dispenseBehavior != this) {
                    dispenseBehavior.dispense(blockSource, eventStack);
                    return item;
                }
            }
            // CraftBukkit end
            try {
                // Paper start - track changed items in the dispense event
                this.setSuccess(
                    ((BlockItem) item1).place(new DirectionalPlaceContext(blockSource.level(), blockPos, direction, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), direction1)).consumesAction()
                );
                if (this.isSuccess()) {
                    item.shrink(1); // vanilla shrink is in the place function above, manually handle it here
                }
                // Paper end - track changed items in the dispense event
            } catch (Exception var8) {
                LOGGER.error("Error trying to place shulker box at {}", blockPos, var8);
            }
        }

        return item;
    }
}
