package zenith.zov.utility.game.player;

import java.util.List;
import lombok.Generated;
import net.minecraft.client.gui.screen.ingame.AbstractCommandBlockScreen;
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
import net.minecraft.client.gui.screen.ingame.SignEditScreen;
import net.minecraft.client.gui.screen.ingame.StructureBlockScreen;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import zenith.zov.Zenith;
import zenith.zov.base.events.impl.player.EventUpdate;
import zenith.zov.base.request.ScriptManager;
import zenith.zov.utility.interfaces.IMinecraft;

public final class PlayerInventoryComponent implements IMinecraft {
    public static final List<KeyBinding> moveKeys = List.of(
        mc.options.forwardKey, mc.options.backKey, mc.options.leftKey, mc.options.rightKey, mc.options.jumpKey
    );
    public static ScriptManager.ScriptTask script = new ScriptManager.ScriptTask();
    public static boolean canMove = true;

    public static void addTask(Runnable task) {
        if (MovingUtil.hasPlayerMovement()) {
            Zenith.getInstance().getScriptManager().addTask(script);
            String var1 = Zenith.getInstance().getServerHandler().getServer();
            switch (var1) {
                case "FunTime":
                case "HolyWorld":
                    script.schedule(EventUpdate.class, eventUpdate -> {
                        disableMoveKeys();
                        return true;
                    });
                    script.schedule(EventUpdate.class, eventUpdate -> {
                        task.run();
                        enableMoveKeys();
                        return true;
                    });
                    return;
                case "ReallyWorld":
                    if (mc.player.isOnGround()) {
                        script.schedule(EventUpdate.class, eventUpdate -> {
                            disableMoveKeys();
                            return true;
                        });
                        script.schedule(EventUpdate.class, eventUpdate -> {
                            disableMoveKeys();
                            return true;
                        });
                        script.schedule(EventUpdate.class, eventUpdate -> {
                            task.run();
                            return true;
                        });
                        script.schedule(EventUpdate.class, eventUpdate -> {
                            enableMoveKeys();
                            return true;
                        });
                        return;
                    }
                    break;
                case "CopyTime":
                    script.schedule(EventUpdate.class, eventUpdate -> {
                        disableMoveKeys();
                        return true;
                    });
                    script.schedule(EventUpdate.class, eventUpdate -> {
                        task.run();
                        return true;
                    });
                    script.schedule(EventUpdate.class, eventUpdate -> {
                        enableMoveKeys();
                        return true;
                    });
                    return;
            }
        }

        task.run();
    }

    public static void disableMoveKeys() {
        canMove = false;
        unPressMoveKeys();
    }

    public static void enableMoveKeys() {
        PlayerInventoryUtil.closeScreen(true);
        canMove = true;
        updateMoveKeys();
    }

    public static void unPressMoveKeys() {
        moveKeys.forEach(keyBinding -> keyBinding.setPressed(false));
    }

    public static void updateMoveKeys() {
        moveKeys.forEach(keyBinding -> keyBinding.setPressed(InputUtil.isKeyPressed(mc.getWindow().getHandle(), keyBinding.getDefaultKey().getCode())));
    }

    public static boolean shouldSkipExecution() {
        if (mc.currentScreen == null) {
            return false;
        } else if (PlayerIntersectionUtil.isChat(mc.currentScreen)) {
            return false;
        } else if (mc.currentScreen instanceof SignEditScreen) {
            return false;
        } else if (mc.currentScreen instanceof AnvilScreen) {
            return false;
        } else if (mc.currentScreen instanceof AbstractCommandBlockScreen) {
            return false;
        } else if (mc.currentScreen instanceof StructureBlockScreen) {
            return false;
        } else if (mc.player != null && mc.player.currentScreenHandler != null) {
            int slotCount = mc.player.currentScreenHandler.slots.size();
            return slotCount >= 27;
        } else {
            return false;
        }
    }

    @Generated
    private PlayerInventoryComponent() {
        throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
    }
}
