package top.r3944realms.lib39.content.block.blockentity;

import com.mojang.authlib.GameProfile;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.SkullBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.lib39.content.register.Lib39BlockEntities;
import top.r3944realms.lib39.util.GameProfileHelper;
import top.r3944realms.lib39.util.nbt.NBTReader;
import top.r3944realms.lib39.util.nbt.NBTWriter;

import javax.annotation.Nullable;

/**
 * The type Doll block entity.
 */
public class DollBlockEntity extends BlockEntity {

    @Nullable
    private GameProfile owner;

    /**
     * Instantiates a new Doll block entity.
     *
     * @param pos        the pos
     * @param blockState the block state
     */
    public DollBlockEntity(BlockPos pos, BlockState blockState) {
        super(Lib39BlockEntities.DOLL_BLOCK_ENTITY.get(), pos, blockState);
    }

    protected void saveAdditional(@NotNull CompoundTag tag) {
        super.saveAdditional(tag);
        NBTWriter.of(tag)
                .compoundIf(GameProfileHelper.TAG_OWN_PROFILE, owner != null, () -> NbtUtils.writeGameProfile(new CompoundTag(), this.owner));
    }

    public void load(@NotNull CompoundTag tag) {
        super.load(tag);
        NBTReader.of(tag)
                .compound(GameProfileHelper.TAG_OWN_PROFILE, compoundTag -> setOwner(NbtUtils.readGameProfile(compoundTag)));
    }

    /**
     * Gets owner profile.
     *
     * @return the owner profile
     */
    @Nullable
    public GameProfile getOwnerProfile() {
        return this.owner;
    }


    public ClientboundBlockEntityDataPacket getUpdatePacket() {
        return ClientboundBlockEntityDataPacket.create(this);
    }

    public @NotNull CompoundTag getUpdateTag() {
        return this.saveWithoutMetadata();
    }

    /**
     * Sets owner.
     *
     * @param owner the owner
     */
    public void setOwner(@Nullable GameProfile owner) {
        synchronized (this) {
            this.owner = owner;
        }

        this.updateOwnerProfile();
    }

    /**
     * Sets owner.
     *
     * @param ownerName the owner name
     */
    public void setOwner(@Nullable String ownerName) {
        setOwner(new GameProfile(Util.NIL_UUID, ownerName));
    }

    private void updateOwnerProfile() {
        SkullBlockEntity.updateGameprofile(this.owner, gameProfile -> {
            this.owner = gameProfile;
            this.setChanged();
        });
    }

}
