package com.tiedup.remake.client.events;

import com.mojang.logging.LogUtils;
import com.tiedup.remake.client.animation.AnimationStateRegistry;
import com.tiedup.remake.client.animation.BondageAnimationManager;
import com.tiedup.remake.client.animation.PendingAnimationManager;
import com.tiedup.remake.client.animation.render.DogPoseRenderHandler;
import com.tiedup.remake.client.animation.render.HeldItemHideHandler;
import com.tiedup.remake.client.animation.render.PetBedRenderHandler;
import com.tiedup.remake.client.animation.render.PlayerArmHideEventHandler;
import com.tiedup.remake.client.animation.tick.AnimationTickHandler;
import com.tiedup.remake.client.animation.tick.MCAAnimationTickCache;
import com.tiedup.remake.client.animation.tick.NpcAnimationTickHandler;
import com.tiedup.remake.client.gltf.GltfAnimationApplier;
import com.tiedup.remake.client.state.MovementStyleClientState;
import com.tiedup.remake.client.state.PetBedClientState;
import com.tiedup.remake.core.TiedUpMod;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.entity.EntityLeaveLevelEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.slf4j.Logger;

/**
 * Fans out {@link EntityLeaveLevelEvent} to every per-entity state map on
 * the client — the single source of truth for "entity is gone, drop its
 * tracked state". Each target owns its own static map; this handler
 * ensures none of them leak entries for dead/unloaded entities.
 */
@Mod.EventBusSubscriber(
    modid = TiedUpMod.MOD_ID,
    bus = Mod.EventBusSubscriber.Bus.FORGE,
    value = Dist.CLIENT
)
public class EntityCleanupHandler {

    private static final Logger LOGGER = LogUtils.getLogger();

    /**
     * Automatically clean up animation resources when an entity leaves the world.
     *
     * <p>This event fires when:
     * <ul>
     *   <li>An entity is removed from the world (killed, despawned, unloaded)</li>
     *   <li>A player logs out</li>
     *   <li>A chunk is unloaded and its entities are removed</li>
     * </ul>
     *
     * <p>Cleanup includes:
     * <ul>
     *   <li>Removing animation layers from {@link BondageAnimationManager}</li>
     *   <li>Removing pending animations from {@link PendingAnimationManager}</li>
     * </ul>
     *
     * @param event The entity leave level event
     */
    @SubscribeEvent
    public static void onEntityLeaveLevel(EntityLeaveLevelEvent event) {
        // Only process on client side
        if (!event.getLevel().isClientSide()) {
            return;
        }

        java.util.UUID uuid = event.getEntity().getUUID();

        BondageAnimationManager.cleanup(uuid);
        PendingAnimationManager.remove(uuid);
        GltfAnimationApplier.removeTracking(uuid);
        NpcAnimationTickHandler.remove(uuid);
        MovementStyleClientState.clear(uuid);
        PetBedClientState.clear(uuid);
        PetBedRenderHandler.onEntityLeave(uuid);
        AnimationTickHandler.removeFurnitureRetry(uuid);
        AnimationStateRegistry.getLastTiedState().remove(uuid);
        DogPoseRenderHandler.onEntityLeave(uuid);
        PlayerArmHideEventHandler.onEntityLeave(event.getEntity().getId());
        HeldItemHideHandler.onEntityLeave(event.getEntity().getId());
        MCAAnimationTickCache.remove(uuid);

        LOGGER.debug(
            "Auto-cleaned animation resources for entity: {} (type: {})",
            uuid,
            event.getEntity().getClass().getSimpleName()
        );
    }
}
