package dev.crucifixbeta.mod.gui.items.buttons;

import dev.crucifixbeta.api.utils.math.Animation;
import dev.crucifixbeta.api.utils.math.Easing;
import dev.crucifixbeta.api.utils.render.ColorUtil;
import dev.crucifixbeta.api.utils.render.Render2DUtil;
import dev.crucifixbeta.core.impl.FontManager;
import dev.crucifixbeta.mod.gui.items.Item;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.client.ClickGui;
import dev.crucifixbeta.mod.modules.impl.client.ClientSetting;
import dev.crucifixbeta.mod.modules.impl.client.ColorsModule;
import dev.crucifixbeta.mod.modules.settings.Setting;
import dev.crucifixbeta.mod.modules.settings.impl.BindSetting;
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 dev.crucifixbeta.mod.modules.settings.impl.StringSetting;
import java.awt.Color;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.util.InputUtil;
import net.minecraft.util.math.RotationAxis;

@Environment(EnvType.CLIENT)
public class ModuleButton extends Button {
   private final Module module;
   private List<Item> items = new ArrayList<>();
   public boolean subOpen;
   public double itemHeight;
   public final Animation animation = new Animation();
   private final Animation hoverAnimation = new Animation();
   private final Animation toggleAnimation = new Animation();
   private final HashMap<BooleanSetting, Animation> parentOpenAnimations = new HashMap<>();

   public ModuleButton(Module module) {
      super(module.getName());
      this.module = module;
      this.initSettings();
   }

   public void initSettings() {
      ArrayList var1 = new ArrayList();

      for (Setting var3 : this.module.getSettings()) {
         if (var3 instanceof BooleanSetting var4) {
            var1.add(new BooleanButton(var4));
         }

         if (var3 instanceof BindSetting var5) {
            var1.add(new BindButton(var5));
         }

         if (var3 instanceof StringSetting var6) {
            var1.add(new StringButton(var6));
         }

         if (var3 instanceof SliderSetting var7) {
            var1.add(new SliderButton(var7));
         }

         if (var3 instanceof EnumSetting var8) {
            var1.add(new EnumButton(var8));
         }

         if (var3 instanceof ColorSetting var9) {
            var1.add(new PickerButton(var9));
         }
      }

      this.items = var1;
   }

   @Override
   public void update() {
      if (ClientSetting.INSTANCE != null) {
         int var1 = Math.max(10, ClientSetting.INSTANCE.moduleHeight.getValueInt());
         this.setHeight(var1);

         for (Item var3 : this.items) {
            var3.setHeight(var1);
         }
      }

      for (Item var5 : this.items) {
         var5.update();
      }
   }

   @Override
   public void drawScreen(DrawContext context, int mouseX, int mouseY, float partialTicks) {
      boolean var5 = this.isHovering(mouseX, mouseY);
      this.updateHoverSound(var5);
      boolean var6 = this.getState();
      double var7 = this.hoverAnimation.get(var5 ? 1.0 : 0.0, 100L, Easing.CubicInOut);
      double var9 = this.toggleAnimation.get(var6 ? 1.0 : 0.0, 160L, Easing.CubicInOut);
      double var11 = this.getColorDelay();
      ColorsModule var13 = ColorsModule.INSTANCE;
      boolean var14 = var13 != null && var13.colorMode.getValue() == ColorsModule.ColorMode.Static;
      Color var15 = var13 != null ? var13.moduleBg.getValue() : ClickGui.getInstance().defaultColor.getValue();
      Color var16 = var13 != null ? var13.moduleHover.getValue() : ClickGui.getInstance().hoverColor.getValue();
      Color var17 = new Color(var15.getRed(), var15.getGreen(), var15.getBlue(), var15.getAlpha());
      int var18 = ClickGui.getInstance().alpha.getValueInt();
      int var19 = ClickGui.getInstance().hoverAlpha.getValueInt();
      int var20 = Math.max(0, Math.min(255, (int)Math.round((double)var18 + (double)(var19 - var18) * var7)));
      Color var21 = new Color(var16.getRed(), var16.getGreen(), var16.getBlue(), var16.getAlpha());
      Color var22 = ColorUtil.fadeColor(var17, var21, var7);
      float var23 = (float)this.height - 0.5F;
      float var24 = ClientSetting.INSTANCE != null
         ? ClientSetting.INSTANCE.moduleCorner.getValueFloat()
         : Math.min(10.0F, Math.min((float)this.width, var23) / 2.0F);
      if (ClickGui.getInstance().colorMode.getValue() == ClickGui.ColorMode.Spectrum) {
         if (var9 >= 0.999) {
            Render2DUtil.drawLutRect(
               context.getMatrices(),
               this.x,
               this.y,
               (float)this.width,
               var23,
               ClickGui.getInstance().getSpectrumLutId(),
               ClickGui.getInstance().getSpectrumLutHeight(),
               var20
            );
         } else {
            Render2DUtil.drawRoundedRect(context.getMatrices(), this.x, this.y, (float)this.width, var23, var24, var22);
            int var25 = (int)Math.round((double)var20 * var9);
            if (var25 > 0) {
               Render2DUtil.drawLutRect(
                  context.getMatrices(),
                  this.x,
                  this.y,
                  (float)this.width,
                  var23,
                  ClickGui.getInstance().getSpectrumLutId(),
                  ClickGui.getInstance().getSpectrumLutHeight(),
                  var25
               );
            }
         }
      } else {
         Color var83 = var14 ? var13.moduleBgOn.getValue() : ClickGui.getInstance().getActiveColor(var11);
         Color var26 = new Color(var83.getRed(), var83.getGreen(), var83.getBlue(), var83.getAlpha());
         Color var27 = ColorUtil.fadeColor(var22, var26, var9);
         Render2DUtil.drawRoundedRect(context.getMatrices(), this.x, this.y, (float)this.width, var23, var24, var27);
      }

      float var84 = this.getCenteredTextY(this.y, (float)this.height - 0.5F);
      if (var5 && InputUtil.isKeyPressed(mc.getWindow().getHandle(), 340)) {
         this.drawString("Reset Default", (double)(this.x + 2.3F), (double)var84, enableTextColor);
      } else {
         this.drawString(this.module.getDisplayName(), (double)(this.x + 2.3F), (double)var84, this.getState() ? enableTextColor : defaultTextColor);
      }

      if (ClickGui.getInstance().gear.booleanValue) {
         if (!this.subOpen && !(this.itemHeight > 0.0)) {
            boolean var108 = false;
         } else {
            boolean var10000 = true;
         }

         switch ((ClickGui.ExpandIcon)ClickGui.getInstance().expandIcon.getValue()) {
            case PlusMinus:
               this.drawString(
                  this.subOpen ? "-" : "+",
                  (double)(this.x + (float)this.width - 8.0F),
                  (double)var84,
                  ClickGui.getInstance().gear.getValue().getRGB()
               );
               break;
            case Chevron:
               this.drawString(
                  this.subOpen ? "v" : ">",
                  (double)(this.x + (float)this.width - 8.0F),
                  (double)var84,
                  ClickGui.getInstance().gear.getValue().getRGB()
               );
               break;
            case Gear:
               int var85 = ClickGui.getInstance().gear.getValue().getRGB();
               float var28 = FontManager.icon.getWidth("d");
               float var29 = FontManager.icon.getFontHeight("d");
               float var30 = this.x + (float)this.width - var24;
               float var31 = this.y + var23 / 2.0F;
               float var32 = var30 - var28 / 2.0F;
               float var33 = var31 - var29 / 2.0F;
               int var34 = this.getItemHeight();
               float var35 = var34 <= 0 ? 0.0F : (float)Math.min(1.0, Math.max(0.0, this.itemHeight / (double)var34));
               if (var35 > 0.001F) {
                  float var36 = (float)(System.currentTimeMillis() % 2000L) / 2000.0F * 360.0F * var35;
                  context.getMatrices().push();
                  context.getMatrices().translate(var30, var31, 0.0F);
                  context.getMatrices().multiply(RotationAxis.POSITIVE_Z.rotationDegrees(var36));
                  FontManager.icon.drawString(context.getMatrices(), "d", (double)(-var28 / 2.0F), (double)(-var29 / 2.0F), var85);
                  context.getMatrices().pop();
               } else {
                  FontManager.icon.drawString(context.getMatrices(), "d", (double)var32, (double)var33, var85);
               }
         }
      }

      if (this.subOpen || this.itemHeight > 0.0) {
         double var37 = this.getVisibleItemHeight();
         double var39 = Math.max(0.0, Math.min(this.itemHeight, var37));
         float var86 = var37 <= 0.0 ? 0.0F : (float)(var39 / var37);
         if (this.subOpen && var86 < 0.9F) {
            for (Item var89 : this.items) {
               if (var89 instanceof SliderButton) {
                  ((SliderButton)var89).resetFillAnimation();
               }
            }
         }

         float var88 = (1.0F - var86) * 6.0F;
         if (ClickGui.getInstance().line.getValue() && var39 > 0.01) {
            float var90 = this.y + (float)this.height - 0.5F;
            float var93 = (float)((double)(this.y + (float)this.height) + var39 - 0.5);
            float var95 = (float)((double)(this.y + (float)this.height) + var39 - 0.7F);
            double var41 = 0.25;
            float var43 = this.x + 0.6F;
            float var44 = this.x + (float)this.width - 0.6F;
            int var45 = Math.min(160, ClickGui.getInstance().topAlpha.getValueInt());
            if (ClickGui.getInstance().colorMode.getValue() == ClickGui.ColorMode.Spectrum) {
               float var46 = 1.0F;
               Render2DUtil.drawLutRect(
                  context.getMatrices(),
                  var43,
                  var90,
                  var46,
                  var93 - var90,
                  ClickGui.getInstance().getSpectrumLutId(),
                  ClickGui.getInstance().getSpectrumLutHeight(),
                  var45
               );
               Render2DUtil.drawLutRect(
                  context.getMatrices(),
                  var44 - var46,
                  var90,
                  var46,
                  var93 - var90,
                  ClickGui.getInstance().getSpectrumLutId(),
                  ClickGui.getInstance().getSpectrumLutHeight(),
                  var45
               );
            } else {
               Color var101 = ClickGui.getInstance().getColor((double)var90 * var41);
               Color var47 = ClickGui.getInstance().getColor((double)var93 * var41);
               int var48 = var14 ? var101.getRGB() : ColorUtil.injectAlpha(var101.getRGB(), var45);
               int var49 = var14 ? var47.getRGB() : ColorUtil.injectAlpha(var47.getRGB(), var45);
               Render2DUtil.verticalGradient(context.getMatrices(), var43, var90, var43 + 1.0F, var93, var48, var49);
               Render2DUtil.verticalGradient(context.getMatrices(), var44 - 1.0F, var90, var44, var93, var48, var49);
            }

            Color var102 = ClickGui.getInstance().getColor((double)var93 * var41);
            int var104 = var14 ? var102.getRGB() : ColorUtil.injectAlpha(var102.getRGB(), var45);
            Render2DUtil.drawLine(context.getMatrices(), var43, var93, var44, var95, var104);
         }

         float var91 = (float)(this.height + 2);
         List var94 = this.module.getSettings();
         int var96 = 0;

         while (var96 < this.items.size() && var96 < var94.size()) {
            Setting var97 = (Setting)var94.get(var96);
            Item var98 = this.items.get(var96);
            var98.setHeight(this.height);
            double var50 = var98.getVisibleHeight();
            if (var50 <= 0.01 && var98.isHidden()) {
               var96++;
            } else {
               var98.setLocation(this.x + 1.0F, this.y + var91 + var88);
               var98.setWidth(this.width - 9);
               if (var97 instanceof BooleanSetting && ((BooleanSetting)var97).hasParent()) {
                  var98.drawScreen(context, mouseX, mouseY, partialTicks);
                  var91 += (float)(var50 + 2.0);
                  BooleanSetting var100 = (BooleanSetting)var97;
                  double var52 = this.getParentOpenProgress(var100);
                  int var107 = var96 + 1;

                  while (var107 < var94.size() && this.isChildOf(var100, (Setting)var94.get(var107))) {
                     var107++;
                  }

                  double var54 = 0.0;

                  for (int var56 = var96 + 1; var56 < var107 && var56 < this.items.size(); var56++) {
                     if (this.isVisibleWithParentOpen(var100, (Setting)var94.get(var56))) {
                        Item var57 = this.items.get(var56);
                        var57.setHeight(this.height);
                        double var58 = var57.getVisibleHeight();
                        if (!(var58 <= 0.01) || !var57.isHidden()) {
                           var54 += var58 + 2.0;
                        }
                     }
                  }

                  double var60 = var54 * var52;
                  if (var60 > 0.01) {
                     float var62 = (1.0F - (float)var52) * 6.0F;
                     float var63 = this.y + var91 + var88 + var62;
                     float var64 = this.x + 2.0F;
                     int var65 = this.width - 11;
                     int var66 = (int)var64 - 1;
                     int var67 = (int)var63 - 1;
                     int var68 = (int)(var64 + (float)var65 + 8.0F) + 1;
                     int var69 = (int)Math.round((double)var63 + var60) + 1;
                     context.enableScissor(var66, var67, var68, var69);
                     float var70 = var63;

                     for (int var71 = var96 + 1; var71 < var107 && var71 < this.items.size(); var71++) {
                        if (this.isVisibleWithParentOpen(var100, (Setting)var94.get(var71))) {
                           Item var72 = this.items.get(var71);
                           var72.setHeight(this.height);
                           double var73 = var72.getVisibleHeight();
                           if (!(var73 <= 0.01) || !var72.isHidden()) {
                              var72.setLocation(var64, var70);
                              var72.setWidth(var65);
                              if (var73 < (double)var72.getHeight() - 0.01) {
                                 int var75 = (int)var72.getX() - 1;
                                 int var76 = (int)var72.getY() - 1;
                                 int var77 = (int)(var72.getX() + (float)var72.getWidth() + 7.0F) + 1;
                                 int var78 = (int)((double)var72.getY() + var73) + 1;
                                 int var79 = Math.max(var66, var75);
                                 int var80 = Math.max(var67, var76);
                                 int var81 = Math.min(var68, var77);
                                 int var82 = Math.min(var69, var78);
                                 if (var81 > var79 && var82 > var80) {
                                    context.enableScissor(var79, var80, var81, var82);
                                    var72.drawScreen(context, mouseX, mouseY, partialTicks);
                                    context.disableScissor();
                                 }
                              } else {
                                 var72.drawScreen(context, mouseX, mouseY, partialTicks);
                              }

                              var70 += (float)(var73 + 2.0);
                           }
                        }
                     }

                     context.disableScissor();
                  }

                  var91 += (float)var60;
                  var96 = var107;
               } else {
                  if (var50 < (double)var98.getHeight() - 0.01) {
                     int var99 = (int)var98.getX() - 1;
                     int var103 = (int)var98.getY() - 1;
                     int var105 = (int)(var98.getX() + (float)var98.getWidth() + 7.0F) + 1;
                     int var106 = (int)((double)var98.getY() + var50) + 1;
                     context.enableScissor(var99, var103, var105, var106);
                     var98.drawScreen(context, mouseX, mouseY, partialTicks);
                     context.disableScissor();
                  } else {
                     var98.drawScreen(context, mouseX, mouseY, partialTicks);
                  }

                  var91 += (float)(var50 + 2.0);
                  var96++;
               }
            }
         }
      }
   }

   @Override
   public void mouseClicked(int mouseX, int mouseY, int mouseButton) {
      if (!this.isHidden() && !(this.getVisibleHeight() <= 0.01)) {
         if (mouseButton == 0 && this.isHovering(mouseX, mouseY) && InputUtil.isKeyPressed(mc.getWindow().getHandle(), 340)) {
            this.resetSettingsToDefault();
            sound();
         } else {
            super.mouseClicked(mouseX, mouseY, mouseButton);
            if (!this.items.isEmpty()) {
               if (mouseButton == 1 && this.isHovering(mouseX, mouseY)) {
                  this.subOpen = !this.subOpen;
                  if (this.subOpen) {
                     for (Item var5 : this.items) {
                        if (var5 instanceof SliderButton) {
                           ((SliderButton)var5).resetFillAnimation();
                        }
                     }
                  }

                  sound();
               }

               if (this.subOpen) {
                  for (Item var7 : this.items) {
                     if (!var7.isHidden()) {
                        var7.mouseClicked(mouseX, mouseY, mouseButton);
                     }
                  }
               }
            }
         }
      }
   }

   @Override
   public void onKeyTyped(char typedChar, int keyCode) {
      super.onKeyTyped(typedChar, keyCode);
      if (!this.items.isEmpty() && this.subOpen) {
         for (Item var4 : this.items) {
            if (!var4.isHidden()) {
               var4.onKeyTyped(typedChar, keyCode);
            }
         }
      }
   }

   @Override
   public void onKeyPressed(int key) {
      super.onKeyPressed(key);
      if (!this.items.isEmpty() && this.subOpen) {
         for (Item var3 : this.items) {
            if (!var3.isHidden()) {
               var3.onKeyPressed(key);
            }
         }
      }
   }

   public int getButtonHeight() {
      return super.getHeight();
   }

   public double getVisibleItemHeight() {
      double var1 = 3.0;
      List var3 = this.module.getSettings();
      int var4 = 0;

      while (var4 < this.items.size() && var4 < var3.size()) {
         Setting var5 = (Setting)var3.get(var4);
         Item var6 = this.items.get(var4);
         var6.setHeight(this.height);
         double var7 = var6.getVisibleHeight();
         if (var7 <= 0.01 && var6.isHidden()) {
            var4++;
         } else {
            var1 += var7 + 2.0;
            if (var5 instanceof BooleanSetting && ((BooleanSetting)var5).hasParent()) {
               BooleanSetting var9 = (BooleanSetting)var5;
               double var10 = this.getParentOpenProgress(var9);
               int var12 = var4 + 1;

               while (var12 < var3.size() && this.isChildOf(var9, (Setting)var3.get(var12))) {
                  var12++;
               }

               double var13 = 0.0;

               for (int var15 = var4 + 1; var15 < var12 && var15 < this.items.size(); var15++) {
                  if (this.isVisibleWithParentOpen(var9, (Setting)var3.get(var15))) {
                     Item var16 = this.items.get(var15);
                     var16.setHeight(this.height);
                     double var17 = var16.getVisibleHeight();
                     if (!(var17 <= 0.01) || !var16.isHidden()) {
                        var13 += var17 + 2.0;
                     }
                  }
               }

               var1 += var13 * var10;
               var4 = var12;
            } else {
               var4++;
            }
         }
      }

      return var1;
   }

   public int getItemHeight() {
      return (int)Math.round(this.getVisibleItemHeight());
   }

   private void resetSettingsToDefault() {
      for (Setting var2 : this.module.getSettings()) {
         this.resetSettingToDefault(var2);
      }
   }

   public void resetChildSettingsToDefault(BooleanSetting parent) {
      boolean var2 = parent.isOpen();

      for (Setting var4 : this.module.getSettings()) {
         if (var4 != parent) {
            parent.setOpen(true);
            boolean var5 = var4.isVisible();
            parent.setOpen(false);
            boolean var6 = var4.isVisible();
            parent.setOpen(var2);
            if (var5 && !var6) {
               if (var4 instanceof BooleanSetting) {
                  BooleanSetting var7 = (BooleanSetting)var4;
                  if (var7.hasParent()) {
                     this.resetChildSettingsToDefault(var7);
                  }
               }

               this.resetSettingToDefault(var4);
            }
         }
      }
   }

   public void resetPageSettingsToDefault(EnumSetting<?> page) {
      Enum var2 = page.getValue();
      Enum[] var3 = (Enum[])var2.getDeclaringClass().getEnumConstants();
      String var4 = var2.name();
      page.setEnumValue(var4);

      for (Setting var6 : this.module.getSettings()) {
         if (var6 != page) {
            page.setEnumValue(var4);
            boolean var7 = var6.isVisible();
            if (var7) {
               boolean var8 = true;

               for (Enum var12 : var3) {
                  page.setEnumValue(var12.name());
                  if (!var6.isVisible()) {
                     var8 = false;
                     break;
                  }
               }

               page.setEnumValue(var4);
               if (!var8) {
                  if (var6 instanceof BooleanSetting var13 && var13.hasParent()) {
                     this.resetChildSettingsToDefault(var13);
                  }

                  this.resetSettingToDefault(var6);
               }
            }
         }
      }

      page.setEnumValue(var4);
   }

   private double getParentOpenProgress(BooleanSetting parent) {
      Animation var2 = this.parentOpenAnimations.get(parent);
      if (var2 == null) {
         var2 = new Animation();
         this.parentOpenAnimations.put(parent, var2);
      }

      return var2.get(parent.isOpen() ? 1.0 : 0.0, 200L, Easing.CubicInOut);
   }

   private boolean isChildOf(BooleanSetting parent, Setting setting) {
      boolean var3 = parent.isOpen();
      parent.setOpen(true);
      boolean var4 = setting.isVisible();
      parent.setOpen(false);
      boolean var5 = setting.isVisible();
      parent.setOpen(var3);
      return var4 && !var5;
   }

   private boolean isVisibleWithParentOpen(BooleanSetting parent, Setting setting) {
      boolean var3 = parent.isOpen();
      parent.setOpen(true);
      boolean var4 = setting.isVisible();
      parent.setOpen(var3);
      return var4;
   }

   private void resetSettingToDefault(Setting setting) {
      if (setting instanceof BooleanSetting var8) {
         var8.setValue(var8.getDefaultValue());
         if (var8.hasParent()) {
            var8.setOpen(false);
         }
      } else if (setting instanceof SliderSetting var7) {
         var7.setValue(var7.getDefaultValue());
      } else if (setting instanceof StringSetting var6) {
         var6.setValue(var6.getDefaultValue());
      } else if (setting instanceof BindSetting var5) {
         var5.setValue(var5.getDefaultValue());
         var5.setHoldEnable(false);
         var5.setPressed(false);
         var5.holding = false;
      } else if (setting instanceof EnumSetting var4) {
         Enum var3 = var4.getDefaultValue();
         var4.setEnumValue(var3.name());
      } else {
         if (setting instanceof ColorSetting var2) {
            var2.setValue(var2.getDefaultValue());
            var2.rainbow = var2.getDefaultRainbow();
            if (var2.injectBoolean) {
               var2.booleanValue = var2.getDefaultBooleanValue();
            }
         }
      }
   }

   @Override
   public int getHeight() {
      if (this.subOpen) {
         int var1 = super.getHeight();

         for (Item var3 : this.items) {
            if (!var3.isHidden()) {
               var1 += var3.getHeight() + 1;
            }
         }

         return var1 + 2;
      } else {
         return super.getHeight();
      }
   }

   public Module getModule() {
      return this.module;
   }

   @Override
   public void toggle() {
      this.module.toggle();
   }

   @Override
   public boolean getState() {
      return this.module.isOn();
   }
}
