package net.moonleay.gimble.mixin;

import com.mojang.authlib.GameProfile;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.World;
import net.moonleay.gimble.editor.ServerEditorManager;
import net.moonleay.gimble.editor.state.mode.Capability;
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.callback.CallbackInfo;

import java.util.UUID;

@Mixin(PlayerEntity.class)
public abstract class NoClipMixin extends LivingEntity {
    @Shadow public abstract GameProfile getGameProfile();

    @Shadow public abstract PlayerAbilities getAbilities();

    @Shadow
    public abstract boolean isCreative();

    protected NoClipMixin(EntityType<? extends LivingEntity> entityType, World world) {
        super(entityType, world);
    } // Server side


    @Inject(method = "tick", at = @At(value = "FIELD",
            target = "Lnet/minecraft/entity/player/PlayerEntity;noClip:Z", shift = At.Shift.AFTER)
    )    private void enoClip(CallbackInfo ci) {
        if (!this.isCreative())
            return;
        UUID uuid = this.getGameProfile().getId();

        if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP)) {
            return; // NoClip is not enabled
        }
        if (!this.getAbilities().flying) {
            return;
        }
        // Enable NoClip
        this.noClip = true;
    }

    @Inject(method = "updatePose", at = @At("HEAD"))
    private void onUpdatePose(CallbackInfo ci) {
        UUID uuid = this.getGameProfile().getId();

        if (!ServerEditorManager.INSTANCE.shouldPlayer(uuid, Capability.NO_CLIP))
            return; // NoClip is not enabled
        if (!this.getAbilities().flying)
            return;

        // Force standing pose in NoClip mode

        this.setPose(EntityPose.STANDING);
    }
}
