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

import com.tiedup.remake.client.gltf.GltfData;
import java.util.Map;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.joml.Quaternionf;
import org.joml.Vector3f;

/**
 * Parsed multi-armature GLB data for a furniture piece.
 *
 * <p>A furniture GLB may contain:
 * <ul>
 *   <li>A <b>furniture armature</b> with mesh/skeleton for the furniture itself</li>
 *   <li>Zero or more <b>Player_*</b> armatures defining seat positions and player animations</li>
 * </ul>
 *
 * <p>The furniture mesh is parsed into a standard {@link GltfData} for rendering via the
 * existing {@code GltfMeshRenderer}. Seat transforms and animations are extracted from
 * Player_* armatures and keyed by seat ID (derived from armature name, e.g.
 * {@code "Player_main"} becomes seat ID {@code "main"}).
 */
@OnlyIn(Dist.CLIENT)
public record FurnitureGltfData(
    /** Furniture mesh data (renderable via GltfMeshRenderer). */
    GltfData furnitureMesh,

    /** Per-seat root transforms from Player_* armatures: seatId to transform. */
    Map<String, SeatTransform> seatTransforms,

    /** Per-seat player animations: seatId to (animName to clip). */
    Map<String, Map<String, GltfData.AnimationClip>> seatAnimations,

    /**
     * Per-seat player skeleton data (for GltfPoseConverter).
     * Joints are filtered through {@code GltfBoneMapper.isKnownBone()},
     * rest poses are converted to Minecraft space, and animations are
     * remapped to match the filtered joint indices.
     */
    Map<String, GltfData> seatSkeletons
) {
    /**
     * Root transform of a Player_* armature, defining where a seated player is
     * positioned and oriented relative to the furniture origin.
     *
     * <p>Values are in Minecraft model-def space: X/Y negated from raw glTF
     * space to match the 180°-around-Z rotation applied to the furniture mesh
     * by {@link com.tiedup.remake.client.gltf.GlbParserUtils#convertMeshToMinecraftSpace}.
     * The conversion happens in {@code PlayerArmatureScanner.extractTransforms}.</p>
     *
     * @param seatId   seat identifier (e.g., "main", "left")
     * @param position translation offset in MC model-def space (meters, Y-up, X/Y negated from glTF)
     * @param rotation orientation quaternion in MC model-def space (qx/qy negated from glTF)
     */
    public record SeatTransform(
        String seatId,
        Vector3f position,
        Quaternionf rotation
    ) {}
}
