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

import asm.accessors.ICloseHandledScreenC2SPacket;
import asm.accessors.ICommonPongC2SPacket;
import asm.accessors.IHandSwingC2SPacket;
import asm.accessors.IPlayerActionC2SPacket;
import asm.accessors.IPlayerInteractBlockC2SPacket;
import asm.accessors.IPlayerInteractItemC2SPacket;
import asm.accessors.IUpdateSelectedSlotC2SPacket;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.EntityVelocityUpdateEvent;
import dev.crucifixbeta.api.events.impl.PacketEvent;
import dev.crucifixbeta.core.impl.CommandManager;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.combat.Criticals;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.common.CommonPongC2SPacket;
import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket;
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
import net.minecraft.network.packet.c2s.play.ClientStatusC2SPacket;
import net.minecraft.network.packet.c2s.play.CloseHandledScreenC2SPacket;
import net.minecraft.network.packet.c2s.play.HandSwingC2SPacket;
import net.minecraft.network.packet.c2s.play.PickFromInventoryC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket;
import net.minecraft.network.packet.c2s.play.TeleportConfirmC2SPacket;
import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket;
import net.minecraft.network.packet.c2s.play.VehicleMoveC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.Full;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.LookAndOnGround;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.OnGroundOnly;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.PositionAndOnGround;
import net.minecraft.util.hit.BlockHitResult;

@Environment(EnvType.CLIENT)
public class PacketLogger extends Module {
   public static PacketLogger INSTANCE;
   private final BooleanSetting moveFull = this.add(new BooleanSetting("MoveFull", true));
   private final BooleanSetting movePos = this.add(new BooleanSetting("MovePosition", true));
   private final BooleanSetting moveLook = this.add(new BooleanSetting("MoveLook", true));
   private final BooleanSetting moveGround = this.add(new BooleanSetting("MoveGround", true));
   private final BooleanSetting vehicleMove = this.add(new BooleanSetting("VehicleMove", true));
   private final BooleanSetting playerAction = this.add(new BooleanSetting("PlayerAction", true));
   private final BooleanSetting updateSlot = this.add(new BooleanSetting("UpdateSlot", true));
   private final BooleanSetting handSwing = this.add(new BooleanSetting("HandSwing", true));
   private final BooleanSetting pong = this.add(new BooleanSetting("Pong", true));
   private final BooleanSetting interactEntity = this.add(new BooleanSetting("InteractEntity", true));
   private final BooleanSetting interactBlock = this.add(new BooleanSetting("InteractBlock", true));
   private final BooleanSetting interactItem = this.add(new BooleanSetting("InteractItem", true));
   private final BooleanSetting closeScreen = this.add(new BooleanSetting("CloseScreen", true));
   private final BooleanSetting command = this.add(new BooleanSetting("ClientCommand", true));
   private final BooleanSetting status = this.add(new BooleanSetting("ClientStatus", true));
   private final BooleanSetting clickSlot = this.add(new BooleanSetting("ClickSlot", true));
   private final BooleanSetting pickInventory = this.add(new BooleanSetting("PickInventory", true));
   private final BooleanSetting teleportConfirm = this.add(new BooleanSetting("TeleportConfirm", true));
   private final BooleanSetting s2cVelocity = this.add(new BooleanSetting("S2cVelocity", true));

   public PacketLogger() {
      super("PacketLogger", Module.Category.Misc);
      this.setChinese("\u6570\u636e\u5305\u8bb0\u5f55");
      INSTANCE = this;
   }

   private void logPacket(String msg, Object... args) {
      String var3 = String.format(msg, args);
      CommandManager.sendMessage(var3);
   }

   @EventListener(
      priority = 999999
   )
   public void velocity(EntityVelocityUpdateEvent event) {
      if (this.s2cVelocity.getValue() && event.getEntity() == mc.player) {
         this.logPacket("S2C Velocity, x: %s, y: %s, z: %s, isExplosion: %s", event.getX(), event.getY(), event.getZ(), event.isExplosion());
      }
   }

   @EventListener(
      priority = -999999
   )
   public void onPacketSend(PacketEvent.Send event) {
      Packet var2 = event.getPacket();
      if (var2 instanceof Full var3 && this.moveFull.getValue()) {
         StringBuilder var4 = new StringBuilder();
         var4.append("PlayerMove Full - ");
         if (var3.changesPosition()) {
            var4.append("x: ")
               .append(var3.getX(0.0))
               .append(", y: ")
               .append(var3.getY(0.0))
               .append(", z: ")
               .append(var3.getZ(0.0))
               .append(" ");
         }

         if (var3.changesLook()) {
            var4.append("yaw: ")
               .append(var3.getYaw(0.0F))
               .append(", pitch: ")
               .append(var3.getPitch(0.0F))
               .append(" ");
         }

         var4.append(" onground: ").append(var3.isOnGround());
         this.logPacket(var4.toString());
      }

      if (var2 instanceof PositionAndOnGround var6 && this.movePos.getValue()) {
         StringBuilder var23 = new StringBuilder();
         var23.append("PlayerMove PosGround - ");
         if (var6.changesPosition()) {
            var23.append("x: ")
               .append(var6.getX(0.0))
               .append(", y: ")
               .append(var6.getY(0.0))
               .append(", z: ")
               .append(var6.getZ(0.0))
               .append(" ");
         }

         var23.append(" onground: ").append(var6.isOnGround());
         this.logPacket(var23.toString());
      }

      if (var2 instanceof LookAndOnGround var7 && this.moveLook.getValue()) {
         StringBuilder var24 = new StringBuilder();
         var24.append("PlayerMove LookGround - ");
         if (var7.changesLook()) {
            var24.append("yaw: ")
               .append(var7.getYaw(0.0F))
               .append(", pitch: ")
               .append(var7.getPitch(0.0F))
               .append(" ");
         }

         var24.append(" onground: ").append(var7.isOnGround());
         this.logPacket(var24.toString());
      }

      if (var2 instanceof OnGroundOnly var8 && this.moveGround.getValue()) {
         this.logPacket("PlayerMove Ground - onground: " + var8.isOnGround());
      }

      if (var2 instanceof VehicleMoveC2SPacket var9 && this.vehicleMove.getValue()) {
         this.logPacket("VehicleMove - x: %s, y: %s, z: %s, yaw: %s, pitch: %s", var9.getX(), var9.getY(), var9.getZ(), var9.getYaw(), var9.getPitch());
      }

      if (var2 instanceof PlayerActionC2SPacket var10) {
         IPlayerActionC2SPacket var25 = (IPlayerActionC2SPacket)var10;
         if (this.playerAction.getValue() && var25.getDirection() != null) {
            this.logPacket("PlayerAction - action: %s, direction: %s, pos: %s", var25.getAction().name(), var25.getDirection().name(), var25.getPos().toShortString());
         }
      }

      if (var2 instanceof UpdateSelectedSlotC2SPacket var11 && this.updateSlot.getValue()) {
         this.logPacket("UpdateSlot - slot: %d", ((IUpdateSelectedSlotC2SPacket)var11).getSelectedSlot());
      }

      if (var2 instanceof HandSwingC2SPacket var12 && this.handSwing.getValue()) {
         this.logPacket("HandSwing - hand: %s", ((IHandSwingC2SPacket)var12).getHand().name());
      }

      if (var2 instanceof CommonPongC2SPacket var13 && this.pong.getValue()) {
         this.logPacket("Pong - %d", ((ICommonPongC2SPacket)var13).getParameter());
      }

      if (var2 instanceof PlayerInteractEntityC2SPacket var14 && this.interactEntity.getValue()) {
         this.logPacket("InteractEntity - Entity: %s, id: %s", Criticals.getEntity(var14).getName().getString(), Criticals.getEntity(var14).getId());
      }

      if (var2 instanceof PlayerInteractBlockC2SPacket var15) {
         IPlayerInteractBlockC2SPacket var26 = (IPlayerInteractBlockC2SPacket)var15;
         if (this.interactBlock.getValue()) {
            BlockHitResult var5 = var26.getBlockHitResult();
            this.logPacket("InteractBlock - pos: %s, dir: %s, hand: %s", var5.getBlockPos().toShortString(), var5.getSide().name(), var26.getHand().name());
         }
      }

      if (var2 instanceof PlayerInteractItemC2SPacket var16 && this.interactItem.getValue()) {
         this.logPacket("InteractItem - hand: %s", ((IPlayerInteractItemC2SPacket)var16).getHand().name());
      }

      if (var2 instanceof CloseHandledScreenC2SPacket var17 && this.closeScreen.getValue()) {
         this.logPacket("CloseScreen - id: %s", ((ICloseHandledScreenC2SPacket)var17).getSyncId());
      }

      if (var2 instanceof ClientCommandC2SPacket var18 && this.command.getValue()) {
         this.logPacket("ClientCommand - mode: %s", var18.getMode().name());
      }

      if (var2 instanceof ClientStatusC2SPacket var19 && this.status.getValue()) {
         this.logPacket("ClientStatus - mode: %s", var19.getMode().name());
      }

      if (var2 instanceof ClickSlotC2SPacket var20 && this.clickSlot.getValue()) {
         this.logPacket("ClickSlot - type: %s, slot: %s, button: %s, id: %s", var20.getActionType().name(), var20.getSlot(), var20.getButton(), var20.getSyncId());
      }

      if (var2 instanceof PickFromInventoryC2SPacket var21 && this.pickInventory.getValue()) {
         this.logPacket("PickInventory - slot: %s", var21.getSlot());
      }

      if (var2 instanceof TeleportConfirmC2SPacket var22 && this.teleportConfirm.getValue()) {
         this.logPacket("TeleportConfirm - id: %s", var22.getTeleportId());
      }
   }
}
