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

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.TotemEvent;
import dev.crucifixbeta.api.events.impl.UpdateEvent;
import dev.crucifixbeta.api.utils.math.Timer;
import dev.crucifixbeta.api.utils.player.EntityUtil;
import dev.crucifixbeta.api.utils.player.InventoryUtil;
import dev.crucifixbeta.core.impl.CommandManager;
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 java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket;
import net.minecraft.network.packet.s2c.common.DisconnectS2CPacket;
import net.minecraft.text.Text;
import net.minecraft.util.math.Vec3d;

@Environment(EnvType.CLIENT)
public class AutoLog extends Module {
   public static boolean loggedOut;
   private final BooleanSetting logOnEnable = this.add(new BooleanSetting("LogOnEnable", false));
   private final BooleanSetting onPop = this.add(new BooleanSetting("OnPop", true));
   private final BooleanSetting lowArmor = this.add(new BooleanSetting("LowArmor", true));
   private final BooleanSetting totemLess = this.add(new BooleanSetting("TotemLess", true).setParent());
   private final SliderSetting totems = this.add(new SliderSetting("Totems", 2.0, 0.0, 20.0, 1.0, this.totemLess::isOpen));
   private final BooleanSetting autoDisable = this.add(new BooleanSetting("AutoDisable", true));
   private final BooleanSetting showReason = this.add(new BooleanSetting("ShowReason", false));
   private final BooleanSetting autoHelp = this.add(new BooleanSetting("AutoHelp", false).setParent());
   private final StringSetting helpPrefixText = this.add(new StringSetting("HelpPrefix", "Helpme!QWQ", this.autoHelp::isOpen));
   private final SliderSetting helpDelay = this.add(
      new SliderSetting("HelpDelay", 3.0, 1.0, 10.0, 1.0, this.autoHelp::isOpen).setSuffix("s")
   );
   private final BooleanSetting helpAutoDisable = this.add(new BooleanSetting("HelpAutoDisable", true, this.autoHelp::isOpen));
   private final Timer helpTimer = new Timer();
   private final List<String> onlineFriends = new ArrayList<>();
   private final Set<String> sentFriends = new HashSet<>();

   public AutoLog() {
      super("AutoLog", Module.Category.Misc);
      this.setChinese("\u81ea\u52a8\u4e0b\u7ebf");
   }

   @Override
   public void onEnable() {
      if (this.logOnEnable.getValue()) {
         this.disconnect("Enabled");
      }

      this.resetAutoHelp();
   }

   @EventListener
   public void onUpdate(UpdateEvent event) {
      this.runAutoHelp();
      int var2;
      if (this.totemLess.getValue() && (double)(var2 = InventoryUtil.getItemCount(Items.TOTEM_OF_UNDYING)) <= this.totems.getValue()) {
         this.disconnect("You have too few totems (" + var2 + ").");
      } else {
         if (this.lowArmor.getValue()) {
            for (ItemStack var4 : mc.player.getInventory().armor) {
               if (!var4.isEmpty() && EntityUtil.getDamagePercent(var4) < 5) {
                  this.disconnect("Your armor has keyCodec durability of less than 5%.");
                  return;
               }
            }
         }
      }
   }

   @EventListener
   public void onPop(TotemEvent event) {
      if (this.onPop.getValue() && event.getPlayer() == mc.player) {
         this.disconnect("You poped 1 totem!");
      }
   }

   @Override
   public void onLogout() {
      if (this.autoDisable.getValue()) {
         this.disable();
      }
   }

   private void resetAutoHelp() {
      this.sentFriends.clear();
      this.onlineFriends.clear();
      this.helpTimer.reset();
      if (this.autoHelp.getValue() && !nullCheck()) {
         this.refreshOnlineFriends();
      }
   }

   private void runAutoHelp() {
      if (this.autoHelp.getValue() && !nullCheck()) {
         double var1 = mc.player.getPos().distanceTo(new Vec3d(0.0, 0.0, 0.0));
         if (var1 > 4000.0) {
            this.sendMessage("AutoHelp disabled: too far from spawn.");
            if (this.helpAutoDisable.getValue()) {
               this.autoHelp.setValue(false);
            }
         } else if (this.helpTimer.passedS(this.helpDelay.getValue())) {
            this.helpTimer.reset();
            this.refreshOnlineFriends();
            if (this.onlineFriends.isEmpty()) {
               if (this.helpAutoDisable.getValue()) {
                  this.autoHelp.setValue(false);
               }
            } else {
               String var3 = String.format("%.0f, %.0f, %.0f", mc.player.getX(), mc.player.getY(), mc.player.getZ());
               String var4 = this.onlineFriends.get(0);
               mc.getNetworkHandler().sendChatCommand("tell " + var4 + " " + this.helpPrefixText.getValue() + " " + var3);
               this.sentFriends.add(var4);
            }
         }
      }
   }

   private void refreshOnlineFriends() {
      this.onlineFriends.clear();
      if (mc.getNetworkHandler() != null && mc.player != null) {
         String var1 = mc.player.getGameProfile().getName();

         for (PlayerListEntry var3 : mc.getNetworkHandler().getPlayerList()) {
            String var4 = var3.getProfile().getName();
            if (var4 != null && !var4.equals(var1) && CrucifixBeta.FRIEND.isFriend(var4) && !this.sentFriends.contains(var4)) {
               this.onlineFriends.add(var4);
            }
         }
      }
   }

   private void disconnect(String reason) {
      loggedOut = true;
      CommandManager.sendMessage("§4[AutoLog] " + reason);
      mc.getNetworkHandler().sendPacket(new UpdateSelectedSlotC2SPacket(114514));
      if (this.showReason.getValue()) {
         mc.player.networkHandler.onDisconnect(new DisconnectS2CPacket(Text.literal("[AutoLog]" + reason)));
      }
   }

   static {

      loggedOut = false;
   }
}
