package com.tiedup.remake.v2.blocks;

import com.tiedup.remake.core.TiedUpMod;
import java.util.UUID;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import org.jetbrains.annotations.Nullable;

/**
 * Block entity for Pet Cage.
 * Tracks the occupant UUID and provides OBJ model rendering data.
 */
public class PetCageBlockEntity extends ObjBlockEntity {

    public static final ResourceLocation MODEL_LOCATION =
        ResourceLocation.fromNamespaceAndPath(
            TiedUpMod.MOD_ID,
            "models/obj/blocks/cage/model.obj"
        );

    public static final ResourceLocation TEXTURE_LOCATION =
        ResourceLocation.fromNamespaceAndPath(
            TiedUpMod.MOD_ID,
            "textures/block/pet_cage.png"
        );

    @Nullable
    private UUID occupantUUID;

    public PetCageBlockEntity(
        BlockEntityType<?> type,
        BlockPos pos,
        BlockState state
    ) {
        super(type, pos, state);
    }

    @Override
    public ResourceLocation getModelLocation() {
        return MODEL_LOCATION;
    }

    @Override
    public ResourceLocation getTextureLocation() {
        return TEXTURE_LOCATION;
    }

    @Override
    public float getModelScale() {
        return 1.0f;
    }

    /**
     * Large render bounding box so the cage doesn't disappear when the camera
     * is inside the model (e.g. player caged) or looking away from the master block.
     */
    @Override
    public AABB getRenderBoundingBox() {
        BlockPos p = getBlockPos();
        return new AABB(
            p.getX() - 2,
            p.getY(),
            p.getZ() - 2,
            p.getX() + 3,
            p.getY() + 3,
            p.getZ() + 3
        );
    }

    // OCCUPANT MANAGEMENT

    public boolean hasOccupant() {
        return occupantUUID != null;
    }

    @Nullable
    public UUID getOccupantUUID() {
        return occupantUUID;
    }

    public void setOccupant(UUID uuid) {
        this.occupantUUID = uuid;
        setChanged();
    }

    public void clearOccupant() {
        this.occupantUUID = null;
        setChanged();
    }

    /**
     * Get the occupant ServerPlayer if online.
     */
    @Nullable
    public ServerPlayer getOccupant(@Nullable MinecraftServer server) {
        if (server == null || occupantUUID == null) return null;
        return server.getPlayerList().getPlayer(occupantUUID);
    }

    // NBT

    @Override
    protected void saveAdditional(CompoundTag tag) {
        super.saveAdditional(tag);
        if (occupantUUID != null) {
            tag.putUUID("occupantUUID", occupantUUID);
        }
    }

    @Override
    public void load(CompoundTag tag) {
        super.load(tag);
        if (tag.hasUUID("occupantUUID")) {
            this.occupantUUID = tag.getUUID("occupantUUID");
        } else {
            this.occupantUUID = null;
        }
    }
}
