package net.Chipperfluff.chipi.mixin;

import com.mojang.authlib.GameProfile;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
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;

import net.Chipperfluff.chipi.effect.ModEffects;
import net.Chipperfluff.chipi.effect.PregnantEffect;
import net.Chipperfluff.chipi.util.ChipiTrackedData;

@Mixin(PlayerEntity.class)
public abstract class PlayerEntityMixin {

    /* ============================================================
       INIT: tracked data
       ============================================================ */

    @Inject(method = "<init>", at = @At("TAIL"))
    private void chipi$initTrackedData(
        World world,
        BlockPos pos,
        float yaw,
        GameProfile profile,
        CallbackInfo ci
    ) {
        PlayerEntity self = (PlayerEntity)(Object)this;
        DataTracker tracker = self.getDataTracker();

        tracker.startTracking(ChipiTrackedData.CHIPI_ENERGY, 1.0f);
    }

    /* ============================================================
       JUMP CLAMP: pregnancy logic
       ============================================================ */

    @Inject(
        method = "jump",
        at = @At("HEAD"),
        cancellable = true
    )
    private void chipi$pregnancyJumpClamp(CallbackInfo ci) {
        if (!((Object)this instanceof ServerPlayerEntity player)) return;

        StatusEffectInstance inst =
            player.getStatusEffect(ModEffects.PREGNANT);

        if (inst == null) return; // normal jump

        int total = PregnantEffect.TOTAL_DURATION;
        int remaining = inst.getDuration();

        // progress 0.0 → 1.0
        double progress =
            1.0 - ((double)remaining / total);
        progress = Math.min(Math.max(progress, 0.0), 1.0);

        // vanilla jump velocity ≈ 0.42
        double maxJump = 0.42 * (1.0 - progress);

        // End stage: NO jumping at all
        if (maxJump < 0.05) {
            ci.cancel();
            return;
        }

        Vec3d vel = player.getVelocity();
        player.setVelocity(vel.x, maxJump, vel.z);
        player.velocityDirty = true;

        // stop vanilla jump
        ci.cancel();
    }
}
