package asm.mixins;

import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.utils.render.Render2DUtil;
import dev.crucifixbeta.mod.commands.Command;
import dev.crucifixbeta.mod.modules.impl.client.ClientSetting;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatInputSuggestor;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.OrderedText;
import net.minecraft.text.Text;
import org.apache.commons.lang3.StringUtils;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Environment(EnvType.CLIENT)
@Mixin({ChatInputSuggestor.class})
public abstract class MixinChatInputSuggestor {
   @Final
   @Shadow
   TextFieldWidget textField;
   @Shadow
   private CompletableFuture<Suggestions> pendingSuggestions;
   @Final
   @Shadow
   private List<OrderedText> messages;
   @Unique
   private boolean showOutline = false;

   @Shadow
   public abstract void show(boolean bl);

   @Inject(
      at = {@At("HEAD")},
      method = {"render"}
   )
   private void onRender(DrawContext context, int mouseX, int mouseY, CallbackInfo ci) {
      if (this.showOutline) {
         int var5 = this.textField.getX() - 3;
         int var6 = this.textField.getY() - 3;
         Render2DUtil.drawRect(
            context.getMatrices(), (float)var5, (float)var6, (float)(this.textField.getWidth() + 1), 1.0F, ClientSetting.INSTANCE.color.getValue().getRGB()
         );
         Render2DUtil.drawRect(
            context.getMatrices(),
            (float)var5,
            (float)(var6 + this.textField.getHeight() + 1),
            (float)(this.textField.getWidth() + 1),
            1.0F,
            ClientSetting.INSTANCE.color.getValue().getRGB()
         );
         Render2DUtil.drawRect(
            context.getMatrices(), (float)var5, (float)var6, 1.0F, (float)(this.textField.getHeight() + 1), ClientSetting.INSTANCE.color.getValue().getRGB()
         );
         Render2DUtil.drawRect(
            context.getMatrices(),
            (float)(var5 + this.textField.getWidth() + 1),
            (float)var6,
            1.0F,
            (float)(this.textField.getHeight() + 2),
            ClientSetting.INSTANCE.color.getValue().getRGB()
         );
      }
   }

   @Inject(
      at = {@At(
         value = "INVOKE",
         target = "Lnet/minecraft/client/gui/widget/TextFieldWidget;getCursor()I",
         ordinal = 0
      )},
      method = {"refresh()V"}
   )
   private void onRefresh(CallbackInfo ci) {
      String var2 = CrucifixBeta.getPrefix();
      String var3 = this.textField.getText();
      this.showOutline = var3.startsWith(var2);
      String var4;
      if (!var3.isEmpty() && (var2.startsWith(var4 = var3.substring(0, this.textField.getCursor())) || var4.startsWith(var2))) {
         int var5 = 0;
         Matcher var6 = Pattern.compile("(\\s+)").matcher(var4);

         while (var6.find()) {
            var5 = var6.end();
         }

         SuggestionsBuilder var7 = new SuggestionsBuilder(var4, var5);
         if (var4.length() < var2.length()) {
            if (!var2.startsWith(var4)) {
               return;
            }

            var7.suggest(var2);
         } else {
            if (!var4.startsWith(var2)) {
               return;
            }

            int var8 = StringUtils.countMatches(var4, " ");
            List var9 = Arrays.asList(var4.split(" "));
            if (var8 == 0) {
               for (Object var13 : CrucifixBeta.COMMAND.getCommands().keySet().toArray()) {
                  String var14 = (String)var13;
                  var7.suggest(CrucifixBeta.getPrefix() + var14 + " ");
               }
            } else {
               if (var9.isEmpty()) {
                  return;
               }

               Command var16 = CrucifixBeta.COMMAND.getCommandBySyntax(((String)var9.getFirst()).substring(var2.length()));
               if (var16 == null) {
                  this.messages.add(Text.of(" §4no commands found: §f" + ((String)var9.getFirst()).substring(var2.length())).asOrderedText());
                  return;
               }

               String[] var17 = var16.getAutocorrect(var8, var9);
               if (var17 == null || var17.length == 0) {
                  return;
               }

               for (String var15 : var17) {
                  var7.suggest(var15 + " ");
               }
            }
         }

         this.pendingSuggestions = var7.buildFuture();
         this.show(false);
      }
   }
}
