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.modules.ChomeNSBotCommandSuggestions;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.command.CommandSource;
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(net.minecraft.client.gui.screen.ChatInputSuggestor.class)
public class ChatInputSuggestorMixin {
  @Shadow
  private CompletableFuture<Suggestions> pendingSuggestions;

  @Shadow
  public void show (boolean narrateFirstSuggestion) {}

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

  @Mutable
  @Final
  @Shadow
  final TextFieldWidget textField;

  public ChatInputSuggestorMixin () {
    textField = null;
  }

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

    final String text = this.textField.getText();
    final int cursor = this.textField.getCursor();

    final ClientPlayerEntity player = MinecraftClient.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((command) -> command.name)
              .toList();

      pendingSuggestions = CommandSource.suggestMatching(
              commands,
              new SuggestionsBuilder(
                      textUpToCursor,
                      getStartOfCurrentWord(textUpToCursor)
              )
      );

      pendingSuggestions.thenRun(() -> {
        if (!pendingSuggestions.isDone()) return;

        show(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 MinecraftClient client = MinecraftClient.getInstance();

      final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();

      if (networkHandler == null) return;

      final CommandDispatcher<FabricClientCommandSource> dispatcher = commandManager.dispatcher;
      final FabricClientCommandSource commandSource = (FabricClientCommandSource) networkHandler.getCommandSource();

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