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

import com.darkmagician6.eventapi.EventManager;
import com.darkmagician6.eventapi.EventTarget;
import net.minecraft.item.Items;
import net.minecraft.util.Hand;
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.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;

@ModuleAnnotation(
    name = "AutoPearlCatch",
    description = "Throws ender pearl high and uses wind charges to catch it",
    category = Category.MOVEMENT
)
public class AutoPearlCatch extends Module {
    private final NumberSetting throwHeight = new NumberSetting("Throw Height", 50.0F, 10.0F, 100.0F, 1.0F);
    private final NumberSetting windChargeDelay = new NumberSetting("Wind Charge Delay", 20.0F, 5.0F, 60.0F, 1.0F);
    private final BooleanSetting silent = new BooleanSetting("Silent", false);
    private final BooleanSetting autoThrow = new BooleanSetting("Auto Throw", true);
    private boolean hasThrownPearl = false;
    private int windChargeSlot = -1;
    private int pearlSlot = -1;
    private int originalSlot = -1;
    private int delayTicks = 0;

    public AutoPearlCatch() {
        EventManager.register(this);
    }

    @EventTarget
    public void onUpdate(EventUpdate event) {
        if (mc.player != null && mc.world != null) {
            if (this.isEnabled()) {
                if (!this.hasThrownPearl) {
                    this.throwBothSimultaneously();
                } else {
                    this.delayTicks++;
                    if (this.delayTicks >= 10) {
                        this.hasThrownPearl = false;
                        this.delayTicks = 0;
                    }
                }
            } else {
                this.hasThrownPearl = false;
                this.delayTicks = 0;
                if (this.silent.isEnabled() && this.originalSlot != -1) {
                    mc.player.getInventory().setSelectedSlot(this.originalSlot);
                }
            }
        }
    }

    private void throwBothSimultaneously() {
        this.pearlSlot = this.findPearlSlot();
        this.windChargeSlot = this.findWindChargeSlot();
        if (this.pearlSlot == -1) {
            System.out.println("No ender pearl found in inventory");
        } else if (this.windChargeSlot == -1) {
            System.out.println("No wind charge found in inventory");
        } else {
            if (this.silent.isEnabled()) {
                this.originalSlot = mc.player.getInventory().selectedSlot;
            }

            mc.player.getInventory().setSelectedSlot(this.pearlSlot);
            mc.player.setPitch(-45.0F);
            mc.interactionManager.interactItem(mc.player, Hand.MAIN_HAND);
            mc.player.swingHand(Hand.MAIN_HAND);
            mc.player.getInventory().setSelectedSlot(this.windChargeSlot);
            mc.player.setPitch(-90.0F);
            mc.interactionManager.interactItem(mc.player, Hand.MAIN_HAND);
            mc.player.swingHand(Hand.MAIN_HAND);
            if (this.silent.isEnabled() && this.originalSlot != -1) {
                mc.player.getInventory().setSelectedSlot(this.originalSlot);
            }

            this.hasThrownPearl = true;
            this.delayTicks = 0;
            System.out.println("Thrown both ender pearl and wind charge simultaneously");
        }
    }

    private int findPearlSlot() {
        for (int i = 0; i < 9; i++) {
            if (!mc.player.getInventory().getStack(i).isEmpty() && mc.player.getInventory().getStack(i).getItem() == Items.ENDER_PEARL) {
                return i;
            }
        }

        return -1;
    }

    private int findWindChargeSlot() {
        for (int i = 0; i < 9; i++) {
            if (!mc.player.getInventory().getStack(i).isEmpty() && mc.player.getInventory().getStack(i).getItem() == Items.WIND_CHARGE) {
                return i;
            }
        }

        return -1;
    }
}
