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

import com.tiedup.remake.v2.furniture.FurnitureDefinition;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f;

/**
 * Client-only helper to resolve seat world positions from parsed GLB data.
 *
 * <p>This class exists to isolate the {@link FurnitureGltfCache} dependency
 * from {@link com.tiedup.remake.v2.furniture.EntityFurniture EntityFurniture},
 * which is loaded on both client and dedicated server. The dedicated server
 * never touches this class, preventing classloader errors from the
 * {@code @OnlyIn(Dist.CLIENT)} cache/parser classes.</p>
 */
@OnlyIn(Dist.CLIENT)
public final class FurnitureSeatPositionHelper {

    private FurnitureSeatPositionHelper() {}

    /**
     * Look up the seat transform from the parsed GLB data and compute
     * the world position for a passenger in that seat.
     *
     * @param def         the furniture definition (provides modelLocation)
     * @param seatId      the seat identifier to look up
     * @param furnitureX  furniture entity X position
     * @param furnitureY  furniture entity Y position
     * @param furnitureZ  furniture entity Z position
     * @param furnitureYRot furniture entity Y rotation in degrees
     * @return the world position [x, y, z] for the passenger, or null if
     *         the GLB data or seat transform is unavailable
     */
    @Nullable
    public static double[] getSeatWorldPosition(
        FurnitureDefinition def,
        String seatId,
        double furnitureX,
        double furnitureY,
        double furnitureZ,
        float furnitureYRot
    ) {
        ResourceLocation modelLoc = def.modelLocation();
        if (modelLoc == null) return null;

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

        FurnitureGltfData.SeatTransform transform = gltfData
            .seatTransforms()
            .get(seatId);
        if (transform == null) return null;

        // The seat transform position is in Minecraft model space (post-conversion):
        // X and Y are negated from glTF. We need to rotate by the entity's yaw.
        Vector3f pos = transform.position();
        float yawRad = (float) Math.toRadians(-furnitureYRot);
        float cos = (float) Math.cos(yawRad);
        float sin = (float) Math.sin(yawRad);

        // Rotate the local seat offset by the furniture's yaw around the Y axis
        float sx = pos.x();
        float sy = pos.y();
        float sz = pos.z();
        float rx = sx * cos - sz * sin;
        float rz = sx * sin + sz * cos;

        return new double[] {
            furnitureX + rx,
            furnitureY + sy,
            furnitureZ + rz,
        };
    }
}
