package dev.crucifixbeta.core.impl;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.interfaces.IChatHudHook;
import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.mod.commands.Command;
import dev.crucifixbeta.mod.commands.impl.*;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.client.ClientSetting;
import java.util.HashMap;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.text.Text;

@Environment(EnvType.CLIENT)
public class CommandManager implements Wrapper {
    private final HashMap<String, Command> commands = new HashMap<>();

    public CommandManager() {
        init();
    }

    public void init() {
        registerCommand(new AimCommand());
        registerCommand(new ReloadCommand());
        registerCommand(new ClipCommand());
        registerCommand(new PrefixCommand());
        registerCommand(new WatermarkCommand());
        registerCommand(new PeekCommand());
        registerCommand(new FriendCommand());
        registerCommand(new PingCommand());
        registerCommand(new RejoinCommand());
        registerCommand(new TCommand());
        registerCommand(new TeleportCommand());
        registerCommand(new FakePlayerCommand());
        registerCommand(new CleanerCommand());
        registerCommand(new BindCommand());
        registerCommand(new LoadCommand());
        registerCommand(new KitCommand());
        registerCommand(new SaveCommand());
        registerCommand(new GcCommand());
        registerCommand(new BindsCommand());
        registerCommand(new DebugCommand());
        registerCommand(new TokenLoginCommand());
        registerCommand(new ToggleCommand());
        registerCommand(new TradeCommand());
        registerCommand(new XrayCommand());
        registerCommand(new GamemodeCommand());
    }

    public static void sendMessage(String message) {
        mc.execute(() -> {
            if (Module.nullCheck()) {
                return;
            }
            if (ClientSetting.INSTANCE.messageStyle.getValue() == ClientSetting.Style.Earth) {
                mc.inGameHud.getChatHud().addMessage(Text.of(message));
            } else if (ClientSetting.INSTANCE.messageStyle.getValue() == ClientSetting.Style.Moon) {
                ((IChatHudHook) mc.inGameHud.getChatHud()).frogClient$addMessage(
                        Text.of("\u00a7f[\u00a7b" + ClientSetting.INSTANCE.hackName.getValue() + "\u00a7f] " + message));
            } else {
                ((IChatHudHook) mc.inGameHud.getChatHud()).frogClient$addMessage(
                        Text.of(ClientSetting.INSTANCE.hackName.getValue() + "\u00a7f " + message));
            }
        });
    }

    public static void sendMessageId(String message, int id) {
        mc.execute(() -> {
            if (Module.nullCheck()) {
                return;
            }
            IChatHudHook chat = (IChatHudHook) mc.inGameHud.getChatHud();
            if (ClientSetting.INSTANCE.messageStyle.getValue() == ClientSetting.Style.Earth) {
                chat.frogClient$addMessage(Text.of(message), id);
            } else if (ClientSetting.INSTANCE.messageStyle.getValue() == ClientSetting.Style.Moon) {
                chat.frogClient$addMessage(
                        Text.of("\u00a7f[\u00a7b" + ClientSetting.INSTANCE.hackName.getValue() + "\u00a7f] " + message), id);
            } else {
                chat.frogClient$addMessage(Text.of(ClientSetting.INSTANCE.hackName.getValue() + "\u00a7f " + message), id);
            }
        });
    }

    public static void sendChatMessageWidthIdNoSync(String message, int id) {
        mc.execute(() -> {
            if (!Module.nullCheck()) {
                ((IChatHudHook) mc.inGameHud.getChatHud()).frogClient$addMessageOutSync(Text.of("\u00a7f" + message), id);
            }
        });
    }

    private void registerCommand(Command command) {
        commands.put(command.getName(), command);
    }

    public Command getCommandBySyntax(String syntax) {
        return commands.get(syntax);
    }

    public HashMap<String, Command> getCommands() {
        return commands;
    }

    public void command(String[] input) {
        Command command = commands.get(input[0].substring(CrucifixBeta.getPrefix().length()).toLowerCase());
        if (command == null) {
            sendMessage("\u00a74Invalid Command!");
            return;
        }
        String[] parameters = new String[input.length - 1];
        System.arraycopy(input, 1, parameters, 0, parameters.length);
        if (parameters.length == 1 && parameters[0].equals("help")) {
            command.sendUsage();
            return;
        }
        command.runCommand(parameters);
    }
}
