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.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<?> bwm) {
        super(bwm);
        this.lockKey = LockCode.NO_LOCK;
    }
    
    @Override
    public void load(final CompoundTag jt) {
        super.load(jt);
        this.lockKey = LockCode.fromTag(jt);
        if (jt.contains("CustomName", 8)) {
            this.name = Component.Serializer.fromJson(jt.getString("CustomName"));
        }
    }
    
    @Override
    public CompoundTag save(final CompoundTag jt) {
        super.save(jt);
        this.lockKey.addToTag(jt);
        if (this.name != null) {
            jt.putString("CustomName", Component.Serializer.toJson(this.name));
        }
        return jt;
    }
    
    public void setCustomName(final Component lf) {
        this.name = lf;
    }
    
    @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 ayj) {
        return canUnlock(ayj, this.lockKey, this.getDisplayName());
    }
    
    public static boolean canUnlock(final Player ayj, final LockCode ajn, final Component lf) {
        if (ayj.isSpectator() || ajn.unlocksWith(ayj.getMainHandItem())) {
            return true;
        }
        ayj.displayClientMessage(new TranslatableComponent("container.isLocked", new Object[] { lf }), true);
        ayj.playNotifySound(SoundEvents.CHEST_LOCKED, SoundSource.BLOCKS, 1.0f, 1.0f);
        return false;
    }
    
    @Nullable
    @Override
    public AbstractContainerMenu createMenu(final int integer, final Inventory ayi, final Player ayj) {
        if (this.canOpen(ayj)) {
            return this.createMenu(integer, ayi);
        }
        return null;
    }
    
    protected abstract AbstractContainerMenu createMenu(final int integer, final Inventory ayi);
}
