package com.tiedup.remake.v2.furniture.client;

import com.tiedup.remake.client.animation.BondageAnimationManager;
import com.tiedup.remake.client.gltf.GltfData;
import com.tiedup.remake.v2.furniture.EntityFurniture;
import com.tiedup.remake.v2.furniture.FurnitureDefinition;
import com.tiedup.remake.v2.furniture.SeatDefinition;
import dev.kosmx.playerAnim.core.data.KeyframeAnimation;
import java.util.Map;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Client-only: start the seat-pose animation for a player on a furniture
 * entity. Selects the authored clip for the current animation state, falls
 * back through {@code "Occupied"} → first available, and dispatches the
 * result to {@link BondageAnimationManager#playFurniture}.
 *
 * <p>Safe to call repeatedly — {@code playFurniture} replaces any active
 * animation. No-op if the GLB isn't loaded yet (cold cache) or the seat
 * has no authored clip.</p>
 */
@OnlyIn(Dist.CLIENT)
public final class FurnitureClientAnimator {

    private FurnitureClientAnimator() {}

    /**
     * Kick off (or restart) the seat-pose animation. Callers:
     * <ul>
     *   <li>{@code EntityFurniture.addPassenger} — on mount</li>
     *   <li>{@code EntityFurniture.onSyncedDataUpdated} — on
     *       {@code ANIM_STATE} / {@code SEAT_ASSIGNMENTS_SYNC} change</li>
     *   <li>{@code AnimationTickHandler} cold-cache retry</li>
     * </ul>
     *
     * <p>Clip selection matches {@code FurnitureEntityRenderer.resolveActiveAnimation}
     * to keep mesh and pose in lockstep.</p>
     */
    public static void start(EntityFurniture furniture, Player player) {
        if (!furniture.level().isClientSide) return;

        SeatDefinition seat = furniture.getSeatForPassenger(player);
        if (seat == null) return;

        FurnitureDefinition def = furniture.getDefinition();
        if (def == null) return;

        FurnitureGltfData gltfData = FurnitureGltfCache.get(def.modelLocation());
        if (gltfData == null) return;

        Map<String, GltfData.AnimationClip> seatClips =
            gltfData.seatAnimations().get(seat.id());
        if (seatClips == null || seatClips.isEmpty()) return;

        GltfData seatSkeleton = gltfData.seatSkeletons().get(seat.id());

        String stateClipName = switch (furniture.getAnimState()) {
            case EntityFurniture.STATE_OCCUPIED -> "Occupied";
            case EntityFurniture.STATE_STRUGGLE -> "Struggle";
            case EntityFurniture.STATE_ENTERING -> "Enter";
            case EntityFurniture.STATE_EXITING -> "Exit";
            case EntityFurniture.STATE_LOCKING -> "LockClose";
            case EntityFurniture.STATE_UNLOCKING -> "LockOpen";
            default -> "Idle";
        };

        GltfData.AnimationClip clip = seatClips.get(stateClipName);
        if (clip == null) clip = seatClips.get("Occupied");
        if (clip == null) clip = seatClips.values().iterator().next();
        if (clip == null) return;

        KeyframeAnimation anim = FurnitureAnimationContext.create(
            clip,
            seatSkeleton,
            seat.blockedRegions()
        );
        if (anim != null) {
            BondageAnimationManager.playFurniture(player, anim);
        }
    }
}
