package com.tiedup.remake.mixin.client;

import com.tiedup.remake.client.animation.render.DogPoseRenderHandler;
import com.tiedup.remake.client.animation.util.DogPoseHelper;
import com.tiedup.remake.items.base.ItemBind;
import com.tiedup.remake.items.base.PoseType;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.v2.BodyRegionV2;
import net.minecraft.client.model.PlayerModel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

/**
 * Mixin for PlayerModel to handle DOG pose head adjustments.
 *
 * When in DOG pose (body horizontal):
 * - Head pitch offset so player looks forward
 * - Head yaw converted to zRot (roll) since yRot axis is sideways when body is horizontal
 */
@Mixin(PlayerModel.class)
public class MixinPlayerModel {

    @Inject(method = "setupAnim", at = @At("TAIL"))
    private void tiedup$adjustDogPose(
        LivingEntity entity,
        float limbSwing,
        float limbSwingAmount,
        float ageInTicks,
        float netHeadYaw,
        float headPitch,
        CallbackInfo ci
    ) {
        if (!(entity instanceof AbstractClientPlayer player)) {
            return;
        }

        PlayerBindState state = PlayerBindState.getInstance(player);
        if (state == null) {
            return;
        }

        ItemStack bind = state.getEquipment(BodyRegionV2.ARMS);
        if (bind.isEmpty() || !(bind.getItem() instanceof ItemBind itemBind)) {
            return;
        }

        if (itemBind.getPoseType() != PoseType.DOG) {
            return;
        }

        PlayerModel<?> model = (PlayerModel<?>) (Object) this;

        // === HEAD ROTATION FOR HORIZONTAL BODY ===
        // Body is at -90° pitch (horizontal, face down)
        // We apply a rotation delta to the poseStack in PlayerArmHideEventHandler
        // The head needs to compensate for this transformation

        float rotationDelta = DogPoseRenderHandler.getAppliedRotationDelta(
            player.getId()
        );
        boolean moving = DogPoseRenderHandler.isDogPoseMoving(player.getId());

        // netHeadYaw is head relative to vanilla body (yHeadRot - yBodyRot)
        // We rotated the model by rotationDelta, so compensate:
        // effectiveHeadYaw = netHeadYaw + rotationDelta
        float headYaw = netHeadYaw + rotationDelta;

        // Clamp based on movement state and apply head compensation
        float maxYaw = moving ? 60f : 90f;
        DogPoseHelper.applyHeadCompensationClamped(
            model.head,
            model.hat,
            headPitch,
            headYaw,
            maxYaw
        );
    }
}
