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

import com.darkmagician6.eventapi.EventTarget;
import net.minecraft.block.Block;
import net.minecraft.util.hit.BlockHitResult;
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;

@ModuleAnnotation(
    name = "AutoTool",
    category = Category.PLAYER,
    description = "Selects best tool for mining blocks"
)
public final class AutoTool extends Module {
    public static final AutoTool INSTANCE = new AutoTool();
    private int previousSlot = -1;

    private AutoTool() {
    }

    @EventTarget
    public void onUpdate(EventUpdate event) {
        if (mc.player != null && mc.world != null && mc.interactionManager != null && !mc.player.isCreative()) {
            if (mc.interactionManager.isBreakingBlock() && this.previousSlot == -1) {
                this.previousSlot = mc.player.getInventory().selectedSlot;
            }

            if (mc.interactionManager.isBreakingBlock()) {
                int toolSlot = this.findOptimalTool();
                if (toolSlot != -1) {
                    mc.player.getInventory().selectedSlot = toolSlot;
                }
            } else if (this.previousSlot != -1) {
                mc.player.getInventory().selectedSlot = this.previousSlot;
                this.previousSlot = -1;
            }
        } else {
            this.previousSlot = -1;
        }
    }

    private int findOptimalTool() {
        if (mc.player != null && mc.world != null) {
            if (mc.crosshairTarget instanceof BlockHitResult blockHitResult) {
                Block block = mc.world.getBlockState(blockHitResult.getBlockPos()).getBlock();
                return this.findTool(block);
            } else {
                return -1;
            }
        } else {
            return 0;
        }
    }

    private int findTool(Block block) {
        int bestSlot = -1;
        float bestSpeed = 1.0F;

        for (int i = 0; i < 9; i++) {
            float speed = this.getMiningSpeed(i, block);
            if (speed > bestSpeed) {
                bestSpeed = speed;
                bestSlot = i;
            }
        }

        return bestSlot;
    }

    private float getMiningSpeed(int slot, Block block) {
        return mc.player == null ? 0.0F : mc.player.getInventory().getStack(slot).getMiningSpeedMultiplier(block.getDefaultState());
    }

    @Override
    public void onDisable() {
        this.previousSlot = -1;
        super.onDisable();
    }
}
