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

import com.darkmagician6.eventapi.EventTarget;
import java.util.Arrays;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.EntityHitResult;
import zenith.zov.Zenith;
import zenith.zov.base.events.impl.player.EventUpdate;
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.MultiBooleanSetting;
import zenith.zov.utility.game.player.RaytracingUtil;
import zenith.zov.utility.interfaces.IClient;

@ModuleAnnotation(
    name = "TriggerBot",
    category = Category.COMBAT,
    description = "Automatically attacks entities you're looking at"
)
public class TriggerBot extends Module implements IClient {
    public static final TriggerBot INSTANCE = new TriggerBot();
    private LivingEntity target = null;
    private final MultiBooleanSetting attackSetting = MultiBooleanSetting.create(
        "Attack setting", Arrays.asList("Only Critical", "Dynamic Cooldown", "Break Shield", "UnPress Shield", "No Attack When Eat")
    );

    private TriggerBot() {
    }

    @Override
    public void onDisable() {
        this.target = null;
        super.onDisable();
    }

    @EventTarget
    public void onTick(EventUpdate event) {
        EntityHitResult result = RaytracingUtil.raytraceEntity(
            3.0,
            Zenith.getInstance().getRotationManager().getCurrentRotation(),
            s -> !Zenith.getInstance().getFriendManager().isFriend(s.getName().getString())
        );
        if (result instanceof EntityHitResult && result.getEntity() instanceof LivingEntity entity) {
            this.target = entity;
            if (this.shouldAttack(entity)) {
                this.performAttack(entity);
            }
        } else {
            this.target = null;
        }
    }

    private boolean shouldAttack(LivingEntity entity) {
        if (entity == null || entity == mc.player) {
            return false;
        } else if (!entity.isAlive()) {
            return false;
        } else {
            double distance = (double)mc.player.distanceTo(entity);
            if (distance > 3.0) {
                return false;
            } else if (this.attackSetting.isEnable("No Attack When Eat") && mc.player.isUsingItem()) {
                return false;
            } else {
                return this.attackSetting.isEnable("Only Critical") ? this.isInCriticalState() : true;
            }
        }
    }

    private boolean isInCriticalState() {
        return mc.player.fallDistance > 0.0F && !mc.player.isOnGround();
    }

    private void performAttack(LivingEntity entity) {
        if (!this.attackSetting.isEnable("Dynamic Cooldown") || !(mc.player.getAttackCooldownProgress(0.5F) < 1.0F)) {
            if (this.attackSetting.isEnable("Break Shield") && entity.isBlocking() && mc.player.getMainHandStack().getItem().toString().contains("axe")) {
                this.attackEntity(entity);
            } else if (!this.attackSetting.isEnable("UnPress Shield") || !entity.isBlocking()) {
                this.attackEntity(entity);
            }
        }
    }

    private void attackEntity(LivingEntity entity) {
        if (mc.interactionManager != null && entity != null) {
            mc.interactionManager.attackEntity(mc.player, entity);
            mc.player.swingHand(Hand.MAIN_HAND);
        }
    }
}
