package zenith.zov.utility.mixin.minecraft.entity;

import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.projectile.FireworkRocketEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import zenith.zov.client.modules.impl.movement.ElytraBooster;

@Mixin({FireworkRocketEntity.class})
public abstract class FireworkRocketEntityMixin extends ProjectileEntity {
    @Unique
    private Vec3d rotation;
    @Shadow
    private LivingEntity shooter;

    public FireworkRocketEntityMixin(EntityType<? extends ProjectileEntity> entityType, World world) {
        super(entityType, world);
    }

    @ModifyExpressionValue(
        method = {"tick"},
        at = {@At(
            value = "INVOKE",
            target = "Lnet/minecraft/entity/LivingEntity;getRotationVector()Lnet/minecraft/util/math/Vec3d;"
        )}
    )
    public Vec3d tick(Vec3d original) {
        this.rotation = original;
        return this.rotation;
    }

    @Redirect(
        method = {"tick"},
        at = @At(
            value = "INVOKE",
            target = "Lnet/minecraft/util/math/Vec3d;add(DDD)Lnet/minecraft/util/math/Vec3d;",
            ordinal = 0
        )
    )
    public Vec3d tick(Vec3d instance, double x, double y, double z) {
        ElytraBooster elytraBooster = ElytraBooster.INSTANCE;
        if (elytraBooster != null && elytraBooster.isEnabled() && MinecraftClient.getInstance().player.isGliding()) {
            if (elytraBooster.getMode().getValue().getName().equals("Auto")) {
                return instance.add(
                    this.rotation.x * 0.1 + (this.rotation.x * 2.0 - instance.x) * 0.5,
                    this.rotation.y * 0.1 + (this.rotation.y * 2.0 - instance.y) * 0.5,
                    this.rotation.z * 0.1 + (this.rotation.z * 2.0 - instance.z) * 0.5
                );
            } else {
                double boostValue = (double)elytraBooster.getBoost().getCurrent();
                return instance.add(
                    this.rotation.x * 0.1 + (this.rotation.x * boostValue - instance.x) * 0.5,
                    this.rotation.y * 0.1 + (this.rotation.y * boostValue - instance.y) * 0.5,
                    this.rotation.z * 0.1 + (this.rotation.z * boostValue - instance.z) * 0.5
                );
            }
        } else {
            return instance.add(
                this.rotation.x * 0.1 + (this.rotation.x * 1.5 - instance.x) * 0.5,
                this.rotation.y * 0.1 + (this.rotation.y * 1.5 - instance.y) * 0.5,
                this.rotation.z * 0.1 + (this.rotation.z * 1.5 - instance.z) * 0.5
            );
        }
    }

    @Unique
    private Vec3d calculateRotationVector(float pitch, float yaw) {
        float f = pitch * (float) (Math.PI / 180.0);
        float g = -yaw * (float) (Math.PI / 180.0);
        float h = MathHelper.cos(g);
        float i = MathHelper.sin(g);
        float j = MathHelper.cos(f);
        float k = MathHelper.sin(f);
        return new Vec3d((double)(i * j), (double)(-k), (double)(h * j));
    }
}
