package com.tiedup.remake.client.animation.util;

import net.minecraft.client.model.geom.ModelPart;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 * Utility class for DOG pose head compensation.
 *
 * <h2>Problem</h2>
 * <p>When in DOG pose, the body is rotated -90° pitch (horizontal, face down).
 * This makes the head point at the ground. We need to compensate:
 * <ul>
 *   <li>Head pitch: add -90° offset so head looks forward</li>
 *   <li>Head yaw: convert to zRot (roll) since yRot axis is sideways</li>
 * </ul>
 *
 * <h2>Architecture — NPCs only (Phase 2.8 RIG cleanup)</h2>
 * <p>Le path PLAYER (ex-{@code MixinPlayerModel.setupAnim @TAIL}) a été retiré
 * Phase 2.8 : le renderer RIG patched ne passe plus par {@code PlayerModel.setupAnim},
 * donc le mixin devenait dead code. La compensation head dog pose sera ré-exprimée
 * nativement en StaticAnimation {@code pose_dog.json} (cf. V3-REW-07 dans
 * {@code docs/plans/rig/V3_REWORK_BACKLOG.md}).</p>
 *
 * <pre>
 * ┌─────────────────────────────────────────────────────────────────┐
 * │                         NPCs                                    │
 * ├─────────────────────────────────────────────────────────────────┤
 * │ 1. EntityDamsel.tick()                                          │
 * │    - Uses RotationSmoother for Y rotation (10% per tick)        │
 * │                                                                 │
 * │ 2. DamselRenderer.setupRotations()                              │
 * │    - super.setupRotations() (applique rotation Y)               │
 * │    - Rotation X -90° au PoseStack (APRÈS Y = espace local)      │
 * │    - Offset vertical (-7 model units)                           │
 * │                                                                 │
 * │ 3. DamselModel.setupAnim()                                      │
 * │    - body.xRot = 0 (évite double rotation)                      │
 * │    - Uses DogPoseHelper.applyHeadCompensation()                 │
 * └─────────────────────────────────────────────────────────────────┘
 * </pre>
 *
 * <h2>Usage</h2>
 * <p>Used by:
 * <ul>
 *   <li>DamselModel - for NPC head compensation</li>
 * </ul>
 *
 * @see RotationSmoother for Y rotation smoothing
 * @see com.tiedup.remake.client.model.DamselModel
 */
@OnlyIn(Dist.CLIENT)
public final class DogPoseHelper {

    private static final float DEG_TO_RAD = (float) Math.PI / 180F;
    private static final float HEAD_PITCH_OFFSET = (float) Math.toRadians(-90);

    private DogPoseHelper() {
        // Utility class - no instantiation
    }

    /**
     * Apply head compensation for DOG pose (horizontal body).
     *
     * <p>When body is horizontal (-90° pitch), the head needs compensation:
     * <ul>
     *   <li>xRot: -90° offset + player's up/down look (headPitch)</li>
     *   <li>yRot: 0 (this axis points sideways when body is horizontal)</li>
     *   <li>zRot: -headYaw (left/right look, replaces yaw)</li>
     * </ul>
     *
     * @param head The head ModelPart to modify
     * @param hat The hat ModelPart to sync (can be null)
     * @param headPitch Player's up/down look angle in degrees
     * @param headYaw Head yaw relative to body in degrees (netHeadYaw for NPCs,
     *                netHeadYaw + rotationDelta for players)
     */
    public static void applyHeadCompensation(
        ModelPart head,
        ModelPart hat,
        float headPitch,
        float headYaw
    ) {
        float pitchRad = headPitch * DEG_TO_RAD;
        float yawRad = headYaw * DEG_TO_RAD;

        // xRot: base offset (-90° to look forward) + player's up/down look
        head.xRot = HEAD_PITCH_OFFSET + pitchRad;

        // yRot: stays at 0 (this axis points sideways when body is horizontal)
        head.yRot = 0;

        // zRot: used for left/right look (replaces yaw since body is horizontal)
        head.zRot = -yawRad;

        // Sync hat layer if provided
        if (hat != null) {
            hat.copyFrom(head);
        }
    }

    /**
     * Apply head compensation with yaw clamping.
     *
     * <p>Same as {@link #applyHeadCompensation} but clamps yaw to a maximum angle.
     * Used for players where yaw range depends on movement state.
     *
     * @param head The head ModelPart to modify
     * @param hat The hat ModelPart to sync (can be null)
     * @param headPitch Player's up/down look angle in degrees
     * @param headYaw Head yaw relative to body in degrees
     * @param maxYaw Maximum allowed yaw angle in degrees
     * @deprecated since Phase 2.8 — player dog pose head compensation was
     *     previously applied via {@code MixinPlayerModel.setupAnim @TAIL}
     *     (removed Phase 2.8 RIG cleanup). No remaining call site; retained
     *     only to preserve the API until V3-REW-07 re-expresses the behavior
     *     as a RIG {@code StaticAnimation pose_dog.json}. See
     *     {@code docs/plans/rig/V3_REWORK_BACKLOG.md#V3-REW-07}.
     */
    @Deprecated(since = "2.8")
    public static void applyHeadCompensationClamped(
        ModelPart head,
        ModelPart hat,
        float headPitch,
        float headYaw,
        float maxYaw
    ) {
        // Wrap first so 350° becomes -10° before clamping (fixes full-rotation accumulation)
        float clampedYaw = net.minecraft.util.Mth.clamp(
            net.minecraft.util.Mth.wrapDegrees(headYaw),
            -maxYaw,
            maxYaw
        );
        applyHeadCompensation(head, hat, headPitch, clampedYaw);
    }
}
