package me.deftware.mixin.mixins.entity;

import me.deftware.client.framework.event.events.EventIsPotionActive;
import me.deftware.client.framework.global.GameKeys;
import me.deftware.client.framework.global.GameMap;
import me.deftware.mixin.imp.IMixinEntityLivingBase;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Map;

@Mixin(LivingEntity.class)
public class MixinEntityLivingBase implements IMixinEntityLivingBase {

    @Shadow
    @Final
    private Map<StatusEffect, StatusEffectInstance> activeStatusEffects;

    @Shadow
    protected int itemUseTimeLeft;

    @SuppressWarnings("ConstantConditions")
    @Inject(method = "hasStatusEffect", at = @At(value = "TAIL"), cancellable = true)
    private void onHasStatusEffect(StatusEffect effect, CallbackInfoReturnable<Boolean> cir) {
        if (!((LivingEntity) (Object) this instanceof ClientPlayerEntity)) {
            return;
        }

        EventIsPotionActive event = new EventIsPotionActive(effect.getTranslationKey(), activeStatusEffects.containsKey(effect));
        event.broadcast();
        cir.setReturnValue(event.isActive());
    }

    @Inject(method = "getJumpVelocity", at = @At(value = "TAIL"), cancellable = true)
    private void onGetJumpVelocity(CallbackInfoReturnable<Float> cir) {
        cir.setReturnValue(GameMap.INSTANCE.get(GameKeys.JUMP_HEIGHT, cir.getReturnValue()));
    }

    @Override
    public int getActiveItemStackUseCount() {
        return itemUseTimeLeft;
    }

    @Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;hasStatusEffect(Lnet/minecraft/entity/effect/StatusEffect;)Z"))
    private boolean travelHasStatusEffectProxy(LivingEntity self, StatusEffect statusEffect) {
        if (statusEffect == StatusEffects.LEVITATION && !GameMap.INSTANCE.get(GameKeys.LEVITATION, true))
            return false;
        return self.hasStatusEffect(statusEffect);
    }

    @Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;hasNoGravity()Z"))
    private boolean travelHasNoGravityProxy(LivingEntity self) {
        if (self.hasStatusEffect(StatusEffects.LEVITATION) && !GameMap.INSTANCE.get(GameKeys.LEVITATION, true))
            return false;
        return self.hasNoGravity();
    }

}

@@ -311,32 +311,68 @@
 ntPlayerEntity;%0A
+import net.minecraft.entity.Entity;%0A
 import net.minec
@@ -939,16 +939,56 @@
 l.Map;%0A%0A
+@SuppressWarnings(%22ConstantConditions%22)%0A
 @Mixin(L
@@ -1227,52 +1227,8 @@
 t;%0A%0A
-    @SuppressWarnings(%22ConstantConditions%22)%0A
     
@@ -1416,17 +1416,16 @@
     if (
-!
 ((Living
@@ -1449,74 +1449,28 @@
 this
- instanceof ClientPlayerEntity)) %7B%0A            return;%0A        %7D%0A%0A
+).isPlayer()) %7B%0A    
     
@@ -1597,23 +1597,8 @@
 ct))
-;%0A        event
 .bro
@@ -1603,24 +1603,28 @@
 roadcast();%0A
+    
         cir.
@@ -1653,24 +1653,34 @@
 sActive());%0A
+        %7D%0A
     %7D%0A%0A    @
@@ -1824,32 +1824,91 @@
 e%3CFloat%3E cir) %7B%0A
+        if (((LivingEntity) (Object) this).isPlayer())%0A    
         cir.setR
@@ -2451,32 +2451,77 @@
 EVITATION, true)
+ && ((LivingEntity) (Object) this).isPlayer()
 )%0A            re
@@ -2889,16 +2889,61 @@
 N, true)
+ && ((LivingEntity) (Object) this).isPlayer()
 )%0A      

Fix jump height entity check