package zenith.zov.client.modules.impl.misc;

import com.darkmagician6.eventapi.EventTarget;
import java.util.Objects;
import net.minecraft.client.option.Perspective;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
import net.minecraft.util.math.Vec3d;
import zenith.zov.base.events.impl.player.EventMove;
import zenith.zov.base.events.impl.player.EventMoveInput;
import zenith.zov.base.events.impl.render.EventCameraPosition;
import zenith.zov.base.events.impl.render.EventRender3D;
import zenith.zov.base.events.impl.server.EventPacket;
import zenith.zov.client.modules.api.Category;
import zenith.zov.client.modules.api.Module;
import zenith.zov.client.modules.api.ModuleAnnotation;
import zenith.zov.client.modules.api.setting.impl.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;
import zenith.zov.utility.game.player.MovingUtil;
import zenith.zov.utility.math.MathUtil;
import zenith.zov.utility.render.level.Render3DUtil;

@ModuleAnnotation(
    name = "FreeCam",
    description = "Free camera view, can fly",
    category = Category.MISC
)
public final class FreeCam extends Module {
    public static final FreeCam INSTANCE = new FreeCam();
    private final NumberSetting speedSetting = new NumberSetting("Speed", 2.0F, 0.5F, 5.0F, 0.5F);
    private final BooleanSetting freezeSetting = new BooleanSetting("Freeze", false);
    public Vec3d pos;
    public Vec3d prevPos;

    private FreeCam() {
    }

    @Override
    public void onEnable() {
        this.prevPos = this.pos = new Vec3d(mc.getEntityRenderDispatcher().camera.getPos().toVector3f());
        super.onEnable();
    }

    @EventTarget
    public void onPacket(EventPacket e) {
        Packet var10000 = e.getPacket();
        Objects.requireNonNull(var10000);
        Object var2 = var10000;
        switch (var2) {
            case PlayerMoveC2SPacket move when this.freezeSetting.isEnabled():
                e.cancel();
                break;
            case PlayerRespawnS2CPacket respawn:
                this.toggle();
                break;
            case GameJoinS2CPacket join:
                this.toggle();
                break;
        }
    }

    @EventTarget
    public void onWorldRender(EventRender3D e) {
        Render3DUtil.drawBox(
            mc.player.getBoundingBox().offset(MathUtil.interpolate(mc.player).subtract(mc.player.getPos())),
            zenith.getThemeManager().getClientColor(90).getRGB(),
            1.0F
        );
    }

    @EventTarget
    public void onMove(EventMove e) {
        if (this.freezeSetting.isEnabled()) {
            e.setMovePos(Vec3d.ZERO);
        }
    }

    @EventTarget
    public void onInput(EventMoveInput e) {
        float speed = this.speedSetting.getCurrent();
        double[] motion = MovingUtil.calculateDirection((double)speed);
        this.prevPos = this.pos;
        this.pos = this.pos.add(motion[0], e.getInput().jump() ? (double)speed : (e.getInput().sneak() ? (double)(-speed) : 0.0), motion[1]);
    }

    @EventTarget
    public void onCameraPosition(EventCameraPosition e) {
        e.setPos(MathUtil.interpolate(this.prevPos, this.pos));
        mc.options.setPerspective(Perspective.FIRST_PERSON);
    }
}
