package land.chipmunk.chipmunkmod.mixin;

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.command.CommandManager;
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.CommandSuggestions;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.SharedSuggestionProvider;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
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 java.util.List;
import java.util.concurrent.CompletableFuture;

@Mixin(CommandSuggestions.class)
public class CommandSuggestionsMixin {
    @Mutable
    @Final
    @Shadow
    final EditBox input;
    @Shadow
    private CompletableFuture<Suggestions> pendingSuggestions;

    public CommandSuggestionsMixin () {
        input = null;
    }

    @Shadow
    private static int getLastWordIndex (final String input) {
        return 0;
    }

    @Shadow
    public void showSuggestions (final boolean narrateFirstSuggestion) {
    }

    @Inject(at = @At("TAIL"), method = "updateCommandInfo()V")
    public void updateCommandInfo (final CallbackInfo ci) {
        final CommandManager commandManager = CommandManager.INSTANCE;

        if (this.input == null) return;

        final String text = this.input.getValue();
        final int cursor = this.input.getCursorPosition();

        final LocalPlayer player = Minecraft.getInstance().player;

        final String chomeNSPrefix = ChipmunkMod.CONFIG.bots.chomens.prefix;

        if (!text.contains(" ") && text.startsWith(chomeNSPrefix) && player != null) {
            final String textUpToCursor = text.substring(0, cursor);

            final List<String> commands = ChomeNSBotCommandSuggestions.INSTANCE.commands
                    .stream()
                    .map(ChomeNSBotCommand::name)
                    .toList();

            pendingSuggestions = SharedSuggestionProvider.suggest(
                    commands,
                    new SuggestionsBuilder(
                            textUpToCursor,
                            getLastWordIndex(textUpToCursor)
                    )
            );

            pendingSuggestions.thenRun(() -> {
                if (!pendingSuggestions.isDone()) return;
                showSuggestions(true);
            });
        } else if (cursor >= commandManager.prefix.length() && text.startsWith(commandManager.prefix)) {
            final StringReader reader = new StringReader(text);
            reader.setCursor(commandManager.prefix.length()); // Skip the prefix

            final Minecraft client = Minecraft.getInstance();

            final ClientPacketListener connection = client.getConnection();

            if (connection == null) return;

            final CommandDispatcher<FabricClientCommandSource> dispatcher = commandManager.dispatcher;
            final FabricClientCommandSource commandSource = (FabricClientCommandSource) connection.getSuggestionsProvider();

            pendingSuggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(reader, commandSource), cursor);
            showSuggestions(true);
        }
    }
}
