package land.chipmunk.chipmunkmod.mixin;

import com.google.gson.JsonObject;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
import land.chipmunk.chipmunkmod.util.BotValidationUtilities;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.widget.TextFieldWidget;
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(value = ChatScreen.class)
public abstract class ChatScreenMixin {
    @Shadow
    protected TextFieldWidget chatField;

    // 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) {
        chatField.setMaxLength(Integer.MAX_VALUE);
    }

    @Inject(method = "sendMessage", at = @At("HEAD"), cancellable = true)
    private void sendMessage (final String chatText, final boolean addToHistory, final CallbackInfo ci) {
        final MinecraftClient client = MinecraftClient.getInstance();

        if (addToHistory) {
            client.inGameHud.getChatHud().addToMessageHistory(chatText);
        }

        if (ChipmunkMod.CONFIG.bots.testbot.webhookUrl != null && chatText.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", MinecraftClient.getInstance().getSession().getUsername());

                    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 (chatText.startsWith(ChipmunkMod.CONFIG.bots.chomens.prefix)) {
            final List<ChomeNSBotCommand> commands = ChomeNSBotCommandSuggestions.INSTANCE.commands;

            final List<String> moreOrTrustedCommands = commands.stream()
                    .filter(command -> command.trustLevel() != ChomeNSBotCommand.TrustLevel.PUBLIC)
                    .map(command -> command.name().toLowerCase())
                    .toList();

            final List<String> aliases = new ArrayList<>();
            for (final ChomeNSBotCommand command : commands) {
                if (command.trustLevel() == ChomeNSBotCommand.TrustLevel.PUBLIC) continue;

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

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

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

            if (
                    moreOrTrustedCommands.contains(chatCommand) ||
                            aliases.contains(chatCommand.substring(prefixLength))
            ) {
                try {
                    BotValidationUtilities.chomens(chatText.substring(prefixLength));
                    ci.cancel();
                    return;
                } catch (final Exception ignored) {
                }
            }
        }

        if (client.player == null) return;

        if (chatText.startsWith("/")) {
            client.player.networkHandler.sendChatCommand(chatText.substring(1));
        } else {
            client.player.networkHandler.sendChatMessage(chatText);
        }

        ci.cancel();
    }
}
