package dev.crucifixbeta.mod.modules.impl.misc;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.PacketEvent;
import dev.crucifixbeta.api.events.impl.ServerConnectBeginEvent;
import dev.crucifixbeta.api.events.impl.UpdateEvent;
import dev.crucifixbeta.api.utils.math.Timer;
import dev.crucifixbeta.api.utils.player.InventoryUtil;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import dev.crucifixbeta.mod.modules.settings.impl.StringSetting;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair;
import java.security.MessageDigest;
import java.util.HashMap;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
import net.minecraft.client.network.ServerAddress;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket;
import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket;
import net.minecraft.screen.GenericContainerScreenHandler;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.util.Hand;

@Environment(EnvType.CLIENT)
public class AutoReconnect extends Module {
   public static AutoReconnect INSTANCE;
   public final BooleanSetting rejoin = this.add(new BooleanSetting("Rejoin", true));
   public final SliderSetting delay = this.add(new SliderSetting("Delay", 5.0, 0.0, 20.0, 0.1).setSuffix("s"));
   public final BooleanSetting autoLogin = this.add(new BooleanSetting("AutoAuth", true));
   public final SliderSetting afterLoginTime = this.add(
      new SliderSetting("AfterLoginTime", 3.0, 0.0, 10.0, 0.1).setSuffix("s")
   );
   public final BooleanSetting autoQueue = this.add(new BooleanSetting("AutoQueue", true));
   public final SliderSetting joinQueueDelay = this.add(
      new SliderSetting("JoinQueueDelay", 3.0, 0.0, 10.0, 0.1).setSuffix("s")
   );
   final StringSetting password = this.add(new StringSetting("password", "123456"));
   public final BooleanSetting autoAnswer = this.add(new BooleanSetting("AutoAnswer", true));
   public static boolean inQueueServer;
   private boolean queueingByMessage;
   private final Timer queueTimer = new Timer();
   private final Timer queueMenuTimer = new Timer();
   private final Timer timer = new Timer();
   public Pair<ServerAddress, ServerInfo> lastServerConnection;
   private boolean login = false;
   final String[] abc = new String[]{"A", "B", "C"};
   public static final HashMap<String, String> asks = new HashMap<>() {{
      put("\u7ea2\u77f3\u706b\u628a", "15");
      put("\u732a\u88ab\u95ea\u7535", "\u50f5\u5c38\u732a\u4eba");
      put("\u5c0f\u7bb1\u5b50\u80fd", "27");
      put("\u5f00\u670d\u5e74\u4efd", "2020");
      put("\u5b9a\u4f4d\u672b\u5730\u9057\u8ff9", "0");
      put("\u722c\u884c\u8005\u88ab\u95ea\u7535", "\u9ad8\u538b\u722c\u884c\u8005");
      put("\u5927\u7bb1\u5b50\u80fd", "54");
      put("\u7f8a\u9a7c\u4f1a\u4e3b\u52a8", "\u4e0d\u4f1a");
      put("\u65e0\u9650\u6c34", "3");
      put("\u6316\u6398\u901f\u5ea6\u6700\u5feb", "\u91d1\u9550");
      put("\u51cb\u7075\u6b7b\u540e", "\u4e0b\u754c\u4e4b\u661f");
      put("\u82e6\u529b\u6015\u7684\u5b98\u65b9", "\u722c\u884c\u8005");
      put("\u5357\u74dc\u7684\u751f\u957f", "\u4e0d\u9700\u8981");
      put("\u5b9a\u4f4d\u672b\u5730", "0");
   }};

   public AutoReconnect() {
      super("AutoReconnect", Module.Category.Misc);
      this.setChinese("\u81ea\u52a8\u91cd\u8fde");
      INSTANCE = this;
      CrucifixBeta.EVENT_BUS.subscribe(new AutoReconnect.StaticListener());
   }

   @EventListener
   public void onUpdate(UpdateEvent event) {
      if (this.login && this.timer.passedS(this.afterLoginTime.getValue())) {
         mc.getNetworkHandler().sendChatCommand("login " + this.password.getValue());
         this.login = false;
      }

      if (this.autoQueue.getValue()
         && !this.queueingByMessage
         && InventoryUtil.findItem(Items.COMPASS) != -1
         && this.queueTimer.passedS(this.joinQueueDelay.getValue())) {
         InventoryUtil.switchToSlot(InventoryUtil.findItem(Items.COMPASS));
         sendSequencedPacket(
            id -> new PlayerInteractItemC2SPacket(Hand.MAIN_HAND, id, CrucifixBeta.ROTATION.getLastYaw(), CrucifixBeta.ROTATION.getLastPitch())
         );
         this.queueTimer.reset();
      }

      if (nullCheck()) {
         inQueueServer = false;
         this.queueingByMessage = false;
      } else {
         if (this.autoQueue.getValue()
            && !this.queueingByMessage
            && mc.currentScreen instanceof GenericContainerScreen
            && this.queueMenuTimer.passedS(this.joinQueueDelay.getValue())) {
            GenericContainerScreenHandler var2 = ((GenericContainerScreen)mc.currentScreen).getScreenHandler();
            if (var2 != null && mc.player.currentScreenHandler.getCursorStack().isEmpty()) {
               int var3 = var2.getInventory().size();
               int var4 = var3 == 9 ? 4 : (var3 == 5 ? 2 : -1);
               if (var4 != -1) {
                  ItemStack var5 = var2.getInventory().getStack(var4);
                  if (var5 != null && var5.getItem() == Items.COMPASS) {
                     mc.interactionManager.clickSlot(var2.syncId, var4, 0, SlotActionType.PICKUP, mc.player);
                     this.queueMenuTimer.reset();
                  }
               }
            }
         }

         inQueueServer = InventoryUtil.findItem(Items.COMPASS) != -1;
      }
   }

   @Override
   public void onLogin() {
      if (this.autoLogin.getValue()) {
         this.login = true;
         this.timer.reset();
      }
   }

   public boolean rejoin() {
      return this.isOn() && this.rejoin.getValue() && !AutoLog.loggedOut;
   }

   @Override
   public void onLogout() {
      inQueueServer = false;
      this.queueingByMessage = false;
   }

   @Override
   public void onDisable() {
      inQueueServer = false;
      this.queueingByMessage = false;
   }

   @EventListener
   public void onPacketReceive(PacketEvent.Receive e) {
      if (!nullCheck()) {
         Packet var2 = e.getPacket();
         String var3 = null;
         if (var2 instanceof GameMessageS2CPacket var4) {
            var3 = var4.content().getString();
             if (var3.toLowerCase().contains("position in queue")) {
               this.queueingByMessage = true;
            }
         }

         if (this.autoAnswer.getValue()) {
            if (inQueueServer) {
               if (var3 != null) {
                  for (String var5 : asks.keySet()) {
                     if (var3.contains(var5)) {
                        for (String var9 : this.abc) {
                           if (var3.contains(var9 + "." + asks.get(var5))) {
                              mc.getNetworkHandler().sendChatMessage(var9.toLowerCase());
                              return;
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }

@Environment(EnvType.CLIENT)
   private class StaticListener {
      @EventListener
      private void onGameJoined(ServerConnectBeginEvent event) {
         AutoReconnect.this.lastServerConnection = new ObjectObjectImmutablePair(event.address, event.info);
      }
   }
}
