package net.minecraft.world.level.block.entity;

import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.player.Player;
import javax.annotation.Nullable;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.network.chat.Component;
import net.minecraft.world.LockCode;
import net.minecraft.world.Nameable;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.Container;

public abstract class BaseContainerBlockEntity extends BlockEntity implements Container, MenuProvider, Nameable {
    private LockCode lockKey;
    private Component name;
    
    protected BaseContainerBlockEntity(final BlockEntityType<?> cdm) {
        super(cdm);
        this.lockKey = LockCode.NO_LOCK;
    }
    
    @Override
    public void load(final BlockState cfj, final CompoundTag le) {
        super.load(cfj, le);
        this.lockKey = LockCode.fromTag(le);
        if (le.contains("CustomName", 8)) {
            this.name = Component.Serializer.fromJson(le.getString("CustomName"));
        }
    }
    
    @Override
    public CompoundTag save(final CompoundTag le) {
        super.save(le);
        this.lockKey.addToTag(le);
        if (this.name != null) {
            le.putString("CustomName", Component.Serializer.toJson(this.name));
        }
        return le;
    }
    
    public void setCustomName(final Component mr) {
        this.name = mr;
    }
    
    @Override
    public Component getName() {
        if (this.name != null) {
            return this.name;
        }
        return this.getDefaultName();
    }
    
    @Override
    public Component getDisplayName() {
        return this.getName();
    }
    
    @Nullable
    @Override
    public Component getCustomName() {
        return this.name;
    }
    
    protected abstract Component getDefaultName();
    
    public boolean canOpen(final Player bec) {
        return canUnlock(bec, this.lockKey, this.getDisplayName());
    }
    
    public static boolean canUnlock(final Player bec, final LockCode ani, final Component mr) {
        if (bec.isSpectator() || ani.unlocksWith(bec.getMainHandItem())) {
            return true;
        }
        bec.displayClientMessage(new TranslatableComponent("container.isLocked", new Object[] { mr }), true);
        bec.playNotifySound(SoundEvents.CHEST_LOCKED, SoundSource.BLOCKS, 1.0f, 1.0f);
        return false;
    }
    
    @Nullable
    @Override
    public AbstractContainerMenu createMenu(final int integer, final Inventory beb, final Player bec) {
        if (this.canOpen(bec)) {
            return this.createMenu(integer, beb);
        }
        return null;
    }
    
    protected abstract AbstractContainerMenu createMenu(final int integer, final Inventory beb);
}
