package com.tiedup.remake.util;

import net.minecraft.util.Mth;

/**
 * Utility class for smoothing rotation values.
 *
 * <p>Provides smooth interpolation between rotation angles, properly handling
 * wraparound at +/-180 degrees. This prevents sudden jumps when rotating past the
 * 180/-180 boundary.
 *
 * <p>Used by:
 * <ul>
 *   <li>EntityDamsel - smoothing body Y rotation in DOG pose</li>
 *   <li>PlayerArmHideEventHandler - smoothing player body Y rotation in DOG pose</li>
 * </ul>
 *
 * <p>Example usage:
 * <pre>
 * RotationSmoother smoother = new RotationSmoother();
 * // In tick():
 * float smoothedRot = smoother.smooth(targetRotation, 0.1f);
 * entity.yBodyRot = smoothedRot;
 * </pre>
 */
public class RotationSmoother {

    /** Current smoothed rotation value. */
    private float current;

    /** Whether the smoother has been initialized with an initial value. */
    private boolean initialized = false;

    /**
     * Create a new rotation smoother.
     */
    public RotationSmoother() {}

    /**
     * Create a rotation smoother with an initial value.
     *
     * @param initialValue Initial rotation value in degrees
     */
    public RotationSmoother(float initialValue) {
        this.current = initialValue;
        this.initialized = true;
    }

    /**
     * Smooth rotation towards target.
     *
     * <p>Interpolates from current rotation towards target using the given speed.
     * Properly handles wraparound at +/-180 degrees using {@link Mth#wrapDegrees}.
     *
     * @param target Target rotation in degrees
     * @param speed Smoothing speed (0.0 = no change, 1.0 = instant snap)
     *              Typical values: 0.1 (slow), 0.2 (medium), 0.3 (fast)
     * @return Smoothed rotation value in degrees
     */
    public float smooth(float target, float speed) {
        if (!initialized) {
            // First call: snap to target
            current = target;
            initialized = true;
            return current;
        }

        // Calculate delta with wraparound handling
        float delta = Mth.wrapDegrees(target - current);

        // Apply smoothing
        current += delta * speed;

        return current;
    }

    /**
     * Get current smoothed rotation value.
     *
     * @return Current rotation in degrees
     */
    public float getCurrent() {
        return current;
    }

    /**
     * Set current rotation directly (no smoothing).
     *
     * <p>Use this to reset the smoother or initialize it to a specific value.
     *
     * @param value Rotation value in degrees
     */
    public void setCurrent(float value) {
        this.current = value;
        this.initialized = true;
    }

    /**
     * Reset the smoother to uninitialized state.
     *
     * <p>The next call to {@link #smooth} will snap to the target value.
     */
    public void reset() {
        this.initialized = false;
    }

    /**
     * Check if the smoother has been initialized.
     *
     * @return true if initialized, false otherwise
     */
    public boolean isInitialized() {
        return initialized;
    }
}
