/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.content.entity.npc.ai.control;

import net.minecraft.util.Mth;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.control.Control;
import top.r3944realms.eroticdungeongame.content.entity.npc.NPCServerPlayer;

public class NPCBodyRotationControl implements Control {
    private final NPCServerPlayer npc;
    private static final int HEAD_STABLE_ANGLE = 15;
    private static final int DELAY_UNTIL_STARTING_TO_FACE_FORWARD = 10;
    private static final int HOW_LONG_IT_TAKES_TO_FACE_FORWARD = 10;
    private int headStableTime;
    private float lastStableYHeadRot;

    public NPCBodyRotationControl(NPCServerPlayer npc) {
        this.npc = npc;
    }
    public void clientTick() {
        if (this.isMoving()) {
            this.npc.yBodyRot = this.npc.getYRot();
            this.rotateHeadIfNecessary();
            this.lastStableYHeadRot = this.npc.yHeadRot;
            this.headStableTime = 0;
        } else {
            if (notCarryingMobPassengers()) {
                if (Math.abs(this.npc.yHeadRot - this.lastStableYHeadRot) > 15.0F) {
                    this.headStableTime = 0;
                    this.lastStableYHeadRot = this.npc.yHeadRot;
                    this.rotateBodyIfNecessary();
                } else {
                    ++this.headStableTime;
                    if (this.headStableTime > 10) {
                        this.rotateHeadTowardsFront();
                    }
                }
            }

        }
    }

    private void rotateBodyIfNecessary() {
        this.npc.yBodyRot = Mth.rotateIfNecessary(this.npc.yBodyRot, this.npc.yHeadRot, (float)this.npc.getMaxHeadYRot());
    }

    private void rotateHeadIfNecessary() {
        this.npc.yHeadRot = Mth.rotateIfNecessary(this.npc.yHeadRot, this.npc.yBodyRot, (float)this.npc.getMaxHeadYRot());
    }

    private void rotateHeadTowardsFront() {
        int i = this.headStableTime - 10;
        float f = Mth.clamp((float)i / 10.0F, 0.0F, 1.0F);
        float f1 = (float)this.npc.getMaxHeadYRot() * (1.0F - f);
        this.npc.yBodyRot = Mth.rotateIfNecessary(this.npc.yBodyRot, this.npc.yHeadRot, f1);
    }

    private boolean notCarryingMobPassengers() {
        return !(this.npc.getFirstPassenger() instanceof Mob);
    }

    private boolean isMoving() {
        double d0 = this.npc.getX() - this.npc.xo;
        double d1 = this.npc.getZ() - this.npc.zo;
        return d0 * d0 + d1 * d1 > (double)2.5000003E-7F;
    }

}
