package dev.crucifixbeta.mod.modules.impl.client.hud;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.PacketEvent;
import dev.crucifixbeta.api.events.impl.TotemEvent;
import dev.crucifixbeta.core.impl.FontManager;
import dev.crucifixbeta.mod.modules.HudModule;
import dev.crucifixbeta.mod.modules.impl.render.NameTags;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.ColorSetting;
import dev.crucifixbeta.mod.modules.settings.impl.EnumSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import java.awt.Color;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Comparator;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;

@Environment(EnvType.CLIENT)
public class TextRadar extends HudModule {
   public static TextRadar INSTANCE;
   private final DecimalFormat df = new DecimalFormat("0.0");
   private final EnumSetting<TextRadar.SortMode> sortMode = this.add(new EnumSetting<>("SortMode", TextRadar.SortMode.Distance));
   private final ColorSetting color = this.add(new ColorSetting("Color", new Color(255, 255, 255)));
   private final ColorSetting friend = this.add(new ColorSetting("Friend").injectBoolean(true));
   private final BooleanSetting doubleBlank = this.add(new BooleanSetting("Double", false));
   private final BooleanSetting health = this.add(new BooleanSetting("Health", true));
   private final BooleanSetting pops = this.add(new BooleanSetting("Pops", true));
   public final BooleanSetting red = this.add(new BooleanSetting("Red", false));
   private final BooleanSetting distance = this.add(new BooleanSetting("Distance", true));
   private final BooleanSetting effects = this.add(new BooleanSetting("Effects", true).setParent());
   private final BooleanSetting strength = this.add(new BooleanSetting("Potion_Strength", true, this.effects::isOpen));
   private final BooleanSetting turtle = this.add(new BooleanSetting("Potion_Turtle", true, this.effects::isOpen));
   private final BooleanSetting regen = this.add(new BooleanSetting("Potion_Regen", true, this.effects::isOpen));
   private final BooleanSetting fireRes = this.add(new BooleanSetting("Potion_FireRes", true, this.effects::isOpen));
   private final BooleanSetting absorption = this.add(new BooleanSetting("Potion_Absorption", true, this.effects::isOpen));
   private final BooleanSetting potionIcons = this.add(new BooleanSetting("PotionIcons", true, this.effects::isOpen));
   private final BooleanSetting potionLevels = this.add(new BooleanSetting("PotionLevels", true, this.effects::isOpen));
   private final SliderSetting potionBlankGap = this.add(
      new SliderSetting("PotionBlankGap", 25.0, 8.0, 50.0, 0.5, () -> this.effects.isOpen() && this.potionIcons.getValue())
   );
   private final SliderSetting potionIconGap;
   private final SliderSetting potionTextGap;
   private final BooleanSetting showAvatar;
   private final SliderSetting avatarSize;

   public TextRadar() {
      super("TextRadar", "\u6587\u5b57\u96f7\u8fbe", 0, 100);
      this.potionBlankGap.setChinese("\u836f\u6c34\u7a7a\u767d\u95f4\u9694");
      this.potionIconGap = this.add(
         new SliderSetting(
            "PotionIconGap", 2.0, 0.0, 16.0, 0.5, () -> this.effects.isOpen() && this.potionIcons.getValue() && this.potionLevels.getValue()
         )
      );
      this.potionIconGap.setChinese("\u836f\u6c34\u56fe\u6807\u95f4\u9694");
      this.potionTextGap = this.add(
         new SliderSetting("PotionTextGap", 4.0, 0.0, 16.0, 0.5, () -> this.effects.isOpen() && this.potionIcons.getValue())
      );
      this.potionTextGap.setChinese("\u836f\u6c34\u6587\u5b57\u95f4\u9694");
      this.showAvatar = this.add(new BooleanSetting("Avatar", true));
      this.avatarSize = this.add(new SliderSetting("AvatarSize", 8, 8, 32));
      this.setChinese("\u6587\u5b57\u96f7\u8fbe");
      INSTANCE = this;
   }

   @EventListener
   public void onPacketReceive(PacketEvent.Receive event) {
      NameTags var2 = NameTags.INSTANCE;
      if (var2 != null && var2.isOff() && this.effects.getValue()) {
         var2.onPacketReceive(event);
      }
   }

   @EventListener
   public void onTotemPop(TotemEvent event) {
      NameTags var2 = NameTags.INSTANCE;
      if (var2 != null && var2.isOff() && this.effects.getValue()) {
         var2.onTotemPop(event);
      }
   }

   @Override
   public void onRender2D(DrawContext drawContext, float tickDelta) {
      if (mc.player != null && mc.world != null) {
         ArrayList<AbstractClientPlayerEntity> var3 = new ArrayList<>(mc.world.getPlayers());
         switch ((TextRadar.SortMode)this.sortMode.getValue()) {
            case Distance:
               var3.sort(Comparator.comparingDouble(player -> (double)mc.player.distanceTo(player)));
               break;
            case Health:
               var3.sort(Comparator.comparingDouble(player -> (double)(player.getHealth() + player.getAbsorptionAmount())));
         }

         int var4 = this.avatarSize.getValueInt();
         int var5 = this.showAvatar.getValue() ? var4 + 4 : 0;
         NameTags var6 = NameTags.INSTANCE;
         ArrayList<TextRadar.RadarRow> var7 = new ArrayList<>();
         int var8 = 0;
         int var9 = 0;

         for (PlayerEntity var11 : var3) {
            if (var11 != mc.player) {
               long var12 = System.currentTimeMillis();
               if (var6 != null && this.effects.getValue()) {
                  var6.syncPotionState(var11, var12);
               }

               boolean var14 = var6 != null && this.turtle.getValue() && var6.hasTurtleEffect(var11);
               String var15 = this.doubleBlank.getValue() ? "  " : " ";
               StringBuilder var16 = new StringBuilder();
               if (this.health.getValue()) {
                  var16.append(getHealthColor(var11));
                  var16.append(this.df.format((double)(var11.getHealth() + var11.getAbsorptionAmount())));
                  var16.append(var15);
               }

               var16.append(var14 ? NameTags.TURTLE_COLOR : Formatting.RESET.toString());
               var16.append(var11.getName().getString());
               if (this.distance.getValue()) {
                  var16.append(var15);
                  var16.append(Formatting.WHITE);
                  var16.append(this.df.format((double)mc.player.distanceTo(var11)));
                  var16.append("m");
               }

               if (this.effects.getValue() && var6 != null) {
                  var16.append(
                     var6.getPotionDisplayString(
                        var11,
                        var15,
                        this.strength.getValue(),
                        this.turtle.getValue(),
                        this.regen.getValue(),
                        this.fireRes.getValue(),
                        this.absorption.getValue(),
                        this.potionIcons.getValue(),
                        this.potionLevels.getValue(),
                        this.potionBlankGap.getValueFloat(),
                        this.potionTextGap.getValueFloat()
                     )
                  );
               }

               if (this.pops.getValue()) {
                  int var17 = CrucifixBeta.POP.getPop(var11);
                  if (var17 > 0) {
                     var16.append(var15);
                     var16.append(getPopColor(var17));
                     var16.append("-");
                     var16.append(var17);
                  }
               }

               boolean var29 = CrucifixBeta.FRIEND.isFriend(var11);
               if (!var29 || this.friend.booleanValue) {
                  int var18;
                  if (var29 && this.friend.booleanValue) {
                     var18 = this.friend.getValue().getRGB();
                  } else if (var14) {
                     var18 = NameTags.TURTLE_COLOR_RGB;
                  } else {
                     var18 = this.color.getValue().getRGB();
                  }

                  String var19 = var16.toString();
                  int var20 = this.getTextWidth(var19);
                  int var21 = useHudFont() ? (int)FontManager.ui.getFontHeight() : 9;
                  if (this.showAvatar.getValue()) {
                     var21 = Math.max(var21, var4);
                  }

                  var7.add(new TextRadar.RadarRow(var11, var19, var18, var20, var21));
                  var8 = Math.max(var8, var20);
                  var9 += var21;
               }
            }
         }

         if (var7.isEmpty()) {
            this.clearHudBounds();
         } else {
            int var24 = Math.max(1, var5 + var8);
            int var25 = Math.max(1, var9);
            int var22 = this.getHudRenderX(var24);
            int var23 = this.getHudRenderY(var25);
            int var26 = var22 + var5;

            for (TextRadar.RadarRow var28 : var7) {
               if (this.showAvatar.getValue() && var28.player instanceof AbstractClientPlayerEntity var30) {
                  this.drawPlayerHead(drawContext, var30, var22, var23, var4);
               }

               if (useHudFont()) {
                  FontManager.ui.drawString(drawContext.getMatrices(), var28.text, (double)var26, (double)var23, var28.color, false);
               } else {
                  drawContext.drawText(mc.textRenderer, var28.text, var26, var23, var28.color, false);
               }

               if (this.effects.getValue() && var6 != null) {
                  var6.drawTextRadarPotionIcons(
                     drawContext,
                     var28.player,
                     var28.text,
                     (float)var26,
                     (float)var23,
                     useHudFont(),
                     false,
                     this.strength.getValue(),
                     this.turtle.getValue(),
                     this.regen.getValue(),
                     this.fireRes.getValue(),
                     this.absorption.getValue(),
                     this.potionIcons.getValue(),
                     this.potionLevels.getValue(),
                     this.potionIconGap.getValueFloat(),
                     this.potionTextGap.getValueFloat()
                  );
               }

               var23 += var28.lineHeight;
            }

            this.setHudBounds(var22, this.getHudRenderY(var25), var24, var25);
         }
      } else {
         this.clearHudBounds();
      }
   }

   private int getTextWidth(String text) {
      return useHudFont() ? (int)Math.ceil((double)FontManager.ui.getWidth(text)) : mc.textRenderer.getWidth(text);
   }

   private static boolean useHudFont() {
      return HudSetting.useFont() && FontManager.ui != null;
   }

   public static Formatting getHealthColor(PlayerEntity player) {
      double var1 = (double)(player.getHealth() + player.getAbsorptionAmount());
      if (var1 > 18.0) {
         return Formatting.GREEN;
      } else if (var1 > 16.0) {
         return Formatting.DARK_GREEN;
      } else if (var1 > 12.0) {
         return Formatting.YELLOW;
      } else if (var1 > 8.0) {
         return Formatting.GOLD;
      } else {
         return var1 > 4.0 ? Formatting.RED : Formatting.DARK_RED;
      }
   }

   public static Formatting getPopColor(int totems) {
      if (INSTANCE.red.getValue()) {
         return Formatting.RED;
      } else if (totems > 10) {
         return Formatting.DARK_RED;
      } else if (totems > 8) {
         return Formatting.RED;
      } else if (totems > 6) {
         return Formatting.GOLD;
      } else if (totems > 4) {
         return Formatting.YELLOW;
      } else {
         return totems > 2 ? Formatting.DARK_GREEN : Formatting.GREEN;
      }
   }

   private void drawPlayerHead(DrawContext drawContext, AbstractClientPlayerEntity player, int x, int y, int size) {
      if (player != null) {
         Identifier var6 = player.getSkinTextures().texture();
         drawContext.fill(x, y, x + size, y + size, -13421773);
         drawContext.drawTexture(var6, x, y, size, size, 8.0F, 8.0F, 8, 8, 64, 64);

         try {
            Class var7 = Class.forName("net.minecraft.client.render.entity.model.PlayerModelPart");
            Field var8 = var7.getField("HAT");
            Object var9 = var8.get(null);
            Method var10 = AbstractClientPlayerEntity.class.getMethod("isPartVisible", var7);
            boolean var11 = (Boolean)var10.invoke(player, var9);
            if (var11) {
               drawContext.drawTexture(var6, x, y, size, size, 40.0F, 8.0F, 8, 8, 64, 64);
            }
         } catch (Exception var12) {
         }
      }
   }
@Environment(EnvType.CLIENT)
   private static final class RadarRow {
      private final PlayerEntity player;
      private final String text;
      private final int color;
      private final int textWidth;
      private final int lineHeight;

      private RadarRow(PlayerEntity player, String text, int color, int textWidth, int lineHeight) {
         this.player = player;
         this.text = text;
         this.color = color;
         this.textWidth = textWidth;
         this.lineHeight = lineHeight;
      }
   }

   @Environment(EnvType.CLIENT)
   public static enum SortMode {
      Distance,
      Health;

}
}
