package land.chipmunk.chipmunkmod.mixin;

import com.google.gson.JsonObject;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.command.CommandManager;
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
import land.chipmunk.chipmunkmod.util.BotValidationUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.ChatScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

@Mixin(ChatScreen.class)
public abstract class ChatScreenMixin {
    @Shadow
    protected EditBox input;

    // infinite chat
    // can't use ModifyConstant due to VFP, see:
    // https://github.com/ViaVersion/ViaFabricPlus/blob/main/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/limitation/max_chat_length/MixinChatScreen.java
    @Inject(method = "init", at = @At("RETURN"))
    private void init (final CallbackInfo ci) {
        input.setMaxLength(Integer.MAX_VALUE);
    }

    @Inject(method = "handleChatInput", at = @At("HEAD"), cancellable = true)
    private void handleChatInput (final String msg, final boolean addToRecent, final CallbackInfo ci) {
        final CommandManager commandManager = CommandManager.INSTANCE;
        final Minecraft client = Minecraft.getInstance();

        if (addToRecent) {
            client.gui.getChat().addRecentChat(msg);
        }

        if (ChipmunkMod.CONFIG.bots.testbot.webhookUrl != null && msg.startsWith(ChipmunkMod.CONFIG.bots.testbot.prefix)) {
            ChipmunkMod.executorService.submit(() -> {
                try {
                    final URL url = new URI(ChipmunkMod.CONFIG.bots.testbot.webhookUrl).toURL();

                    final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
                    connection.addRequestProperty("Content-Type", "application/json");
                    connection.addRequestProperty("User-Agent", "ChipmunkMod");
                    connection.setDoOutput(true);
                    connection.setRequestMethod("POST");

                    final JsonObject jsonObject = new JsonObject();

                    jsonObject.addProperty("username", "ChipmunkMod UwU");
                    jsonObject.addProperty("content", Minecraft.getInstance().getUser().getName());

                    final OutputStream stream = connection.getOutputStream();
                    stream.write(jsonObject.toString().getBytes());
                    stream.flush();
                    stream.close();

                    connection.getInputStream().close();
                    connection.disconnect();
                } catch (final IOException | URISyntaxException e) {
                    ChipmunkMod.LOGGER.error("Error while trying to request TestBot webhook", e);
                }
            });
        } else if (msg.startsWith(ChipmunkMod.CONFIG.bots.chomens.prefix)) {
            final List<ChomeNSBotCommand> commands = ChomeNSBotCommandSuggestions.INSTANCE.commands;

            final List<String> moreOrTrustedCommands = new ArrayList<>();
            final List<String> ownerCommands = new ArrayList<>();
            final List<String> aliases = new ArrayList<>();

            for (final ChomeNSBotCommand command : commands) {
                if (command.trustLevel() == ChomeNSBotCommand.TrustLevel.PUBLIC) continue;

                final String stringCommand = command.name().toLowerCase();

                moreOrTrustedCommands.add(stringCommand);
                if (command.trustLevel() == ChomeNSBotCommand.TrustLevel.OWNER) ownerCommands.add(stringCommand);

                aliases.addAll(command.aliases());
            }

            final String chatCommand = msg.toLowerCase().split("\\s")[0];

            final int prefixLength = ChipmunkMod.CONFIG.bots.chomens.prefix.length();

            if (
                    ownerCommands.contains(chatCommand) ||
                            (ChipmunkMod.CONFIG.bots.chomens.autoValidate &&
                                    (
                                            moreOrTrustedCommands.contains(chatCommand)
                                                    || aliases.contains(chatCommand.substring(prefixLength))
                                    )
                            )
            ) {
                try {
                    BotValidationUtilities.chomens(msg.substring(prefixLength));
                    ci.cancel();
                    return;
                } catch (final Exception ignored) {
                }
            }
        } else if (msg.startsWith(commandManager.prefix)) {
            commandManager.executeCommand(msg.substring(commandManager.prefix.length()));
            ci.cancel();
            return;
        }

        if (client.player == null) return;

        if (msg.startsWith("/")) {
            client.player.connection.sendCommand(msg.substring(1));
        } else {
            client.player.connection.sendChat(msg);
        }

        ci.cancel();
    }
}
