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

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.Render2DEvent;
import dev.crucifixbeta.api.events.impl.UpdateEvent;
import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.api.utils.math.Animation;
import dev.crucifixbeta.api.utils.math.Easing;
import dev.crucifixbeta.mod.gui.Snow;
import dev.crucifixbeta.mod.gui.clickgui.ClickGuiScreen;
import dev.crucifixbeta.mod.gui.epsilon.EpsilonClickGUI;
import dev.crucifixbeta.mod.gui.items.buttons.Button;
import dev.crucifixbeta.mod.modules.Module;
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.util.ArrayList;
import java.util.Random;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.util.Identifier;
import wtf.opal.client.screen.click.dropdown.DropdownClickGUI;

@Environment(EnvType.CLIENT)
public class ClickGui extends Module {
   private static ClickGui INSTANCE;
   public static String key;
   public final EnumSetting<ClickGui.BackgroundStyle> backgroundStyle = this.add(
      new EnumSetting<>("BackgroundStyle", ClickGui.BackgroundStyle.Transparent)
   );
   public final BooleanSetting autoSave = this.add(new BooleanSetting("AutoSave", true));
   public final BooleanSetting font = this.add(new BooleanSetting("Font", true));
   public final BooleanSetting disableNotification = this.add(new BooleanSetting("DisableNotification", false));
   public final SliderSetting height = this.add(new SliderSetting("Height", 2, 0, 7));
   public final SliderSetting textOffset = this.add(new SliderSetting("TextOffset", 0.0, -5.0, 5.0, 1.0));
   public final SliderSetting titleOffset = this.add(new SliderSetting("TitleOffset", 0.0, -5.0, 5.0, 1.0));
   public final SliderSetting alpha = this.add(new SliderSetting("Alpha", 203, 0, 255));
   public final SliderSetting hoverAlpha = this.add(new SliderSetting("HoverAlpha", 220, 0, 255));
   public final SliderSetting topAlpha = this.add(new SliderSetting("TopAlpha", 254, 0, 255));
   public final BooleanSetting fade = this.add(new BooleanSetting("Fade", false).setParent());
   public final SliderSetting length = this.add(new SliderSetting("Length", 0, 0, 1000, this.fade::isOpen));
   public final EnumSetting<Easing> easing = this.add(new EnumSetting<>("Easing", Easing.CubicInOut, this.fade::isOpen));
   public final BooleanSetting blur = this.add(new BooleanSetting("Blur", false).setParent());
   public final SliderSetting radius = this.add(new SliderSetting("Radius", 0.0, 0.0, 100.0, this.blur::isOpen));
   public final BooleanSetting elements = this.add(new BooleanSetting("Elements", false).setParent().injectTask(this::a));
   public final BooleanSetting line = this.add(new BooleanSetting("Line", true, this.elements::isOpen));
   public final ColorSetting lineColor = ColorsModule.INSTANCE.clickLineColor;
   public final ColorSetting gear = ColorsModule.INSTANCE.clickGear;
   public final ColorSetting color = ColorsModule.INSTANCE.clickColor;
   public final ColorSetting activeColor = ColorsModule.INSTANCE.clickActiveColor;
   public final ColorSetting hoverColor = ColorsModule.INSTANCE.clickHoverColor;
   public final ColorSetting defaultColor = ColorsModule.INSTANCE.clickDefaultColor;
   public final ColorSetting defaultTextColor = ColorsModule.INSTANCE.clickDefaultTextColor;
   public final ColorSetting enableTextColor = ColorsModule.INSTANCE.clickEnableTextColor;
   public final ColorSetting backGround = ColorsModule.INSTANCE.clickBackGround;
   public final ColorSetting tint = ColorsModule.INSTANCE.clickTint;
   public final ColorSetting endColor = ColorsModule.INSTANCE.clickTintEnd;
   public final SliderSetting categoryWidth = this.add(new SliderSetting("CategoryWidth", 90, 50, 200));
   public final SliderSetting moduleButtonWidth = this.add(new SliderSetting("ModuleButtonWidth", 90, 50, 200));
   public final SliderSetting categoryBarHeight = this.add(new SliderSetting("CategoryBarHeight", 27, 10, 30));
   public final EnumSetting<ClickGui.ColorMode> colorMode = this.add(new EnumSetting<>("ColorMode", ClickGui.ColorMode.Static, () -> false));
   public final BooleanSetting snow = this.add(new BooleanSetting("Snow", false).setParent());
   public final SliderSetting snowAmount = this.add(new SliderSetting("SnowAmount", 120, 0, 200, this.snow::isOpen));
   public final SliderSetting snowSpeed = this.add(new SliderSetting("SnowSpeed", 38.0, 0.0, 50.0, this.snow::isOpen));
   public final SliderSetting snowSize = this.add(new SliderSetting("SnowSize", 1.8, 0.5, 5.0, this.snow::isOpen));
   public final SliderSetting snowWind = this.add(new SliderSetting("SnowWind", 10.0, -50.0, 50.0, this.snow::isOpen));
   public final SliderSetting snowAlpha = this.add(new SliderSetting("SnowAlpha", 160, 0, 255, this.snow::isOpen));
   public final EnumSetting<ClickGui.SnowShape> snowShape = this.add(
      new EnumSetting<>("SnowShape", ClickGui.SnowShape.Circle, this.snow::isOpen)
   );
   public final SliderSetting backgroundAlpha = ColorsModule.INSTANCE.clickBackgroundAlpha;
   public final BooleanSetting scrollAnim = this.add(new BooleanSetting("ScrollAnim", false));
   public final SliderSetting scrollAnimLength = this.add(new SliderSetting("ScrollAnimLength", 220, 50, 500));
   public final EnumSetting<Easing> scrollAnimEasing = this.add(new EnumSetting<>("ScrollAnimEasing", Easing.SineOut));
   public final BooleanSetting mouseMove = this.add(new BooleanSetting("MouseMove", false).setParent());
   public final SliderSetting mouseMoveStrength = this.add(new SliderSetting("MouseMoveStrength", 16.0, 0.0, 30.0, 0.5, this.mouseMove::isOpen));
   public final SliderSetting mouseMoveSmooth = this.add(new SliderSetting("MouseMoveSmooth", 10.0, 0.0, 30.0, 0.5, this.mouseMove::isOpen));
   public final BooleanSetting walkShake = this.add(new BooleanSetting("WalkShake", false).setParent());
   public final SliderSetting walkShakeStrength = this.add(new SliderSetting("WalkShakeStrength", 8.0, 0.0, 20.0, 0.5, this.walkShake::isOpen));
   public final SliderSetting walkShakeSpeed = this.add(new SliderSetting("WalkShakeSpeed", 12.0, 0.0, 30.0, 0.5, this.walkShake::isOpen));
   public final SliderSetting walkShakeSmooth = this.add(new SliderSetting("WalkShakeSmooth", 14.0, 0.0, 30.0, 0.5, this.walkShake::isOpen));
   public final SliderSetting walkShakeMax = this.add(new SliderSetting("WalkShakeMax", 8.0, 0.0, 30.0, 0.5, this.walkShake::isOpen));
   public final EnumSetting<ClickGui.BlurType> blurType = this.add(new EnumSetting<>("BlurType", ClickGui.BlurType.Radial, this.blur::isOpen));
   public final BooleanSetting tips = this.add(new BooleanSetting("Tips", false));
   public final BooleanSetting hoverSound = this.add(new BooleanSetting("HoverSound", true));
   public final SliderSetting hoverSoundPitch = this.add(new SliderSetting("HoverSoundPitch", 1.0, 0.5, 2.0));
   public final EnumSetting<ClickGui.ExpandIcon> expandIcon = this.add(new EnumSetting<>("ExpandIcon", ClickGui.ExpandIcon.PlusMinus));
   public double alphaValue;
   private final Animation animation = new Animation();
   private int[] spectrumLut;
   private final ArrayList<Snow> snowflakes = new ArrayList<>();
   private final Random snowRandom = new Random();
   private final DropdownClickGUI crucifixDropdown = new DropdownClickGUI();

   public ClickGui() {
      super("ClickGui", Module.Category.Client);
      this.setChinese("\u70b9\u51fb\u754c\u9762");
      INSTANCE = this;
      this.getBindSetting().setValue(344);
      this.getBindSetting().setHoldEnable(false);
      this.drawn.setValue(false);
      CrucifixBeta.EVENT_BUS.subscribe(new ClickGui.FadeOut());
   }

   public static ClickGui getInstance() {
      return INSTANCE;
   }

   public void a() {
      this.elements.setValueWithoutTask(false);
      this.elements.setOpen(!this.elements.isOpen());
   }

   @Override
   public void onEnable() {
      if (nullCheck()) {
         this.disable();
      } else {
         this.animation.from = 0.0;
         this.animation.to = 0.0;
         this.alphaValue = 0.0;
         this.updateColor();
         if (Sounds.INSTANCE != null) {
            Sounds.INSTANCE.playGuiSound();
         }

         mc.setScreen(this.crucifixDropdown);
      }
   }

   @Override
   public void onDisable() {
      if (mc.currentScreen instanceof DropdownClickGUI || mc.currentScreen instanceof ClickGuiScreen || mc.currentScreen instanceof EpsilonClickGUI) {
         mc.currentScreen.close();
      }

      if (Sounds.INSTANCE != null) {
         Sounds.INSTANCE.playGuiSound();
      }

      if (this.autoSave.getValue()) {
         CrucifixBeta.save();
      }
   }

   @EventListener
   public void onUpdate(UpdateEvent event) {
      this.updateColor();
      if (!(mc.currentScreen instanceof DropdownClickGUI) && !(mc.currentScreen instanceof ClickGuiScreen) && !(mc.currentScreen instanceof EpsilonClickGUI)) {
         this.disable();
      }
   }

   public void updateColor() {
      ColorsModule var1 = ColorsModule.INSTANCE;
      if (var1 != null) {
         Button.hoverColor = var1.moduleHover.getValue().getRGB();
         Button.defaultColor = var1.moduleBg.getValue().getRGB();
         Button.defaultTextColor = var1.moduleText.getValue().getRGB();
         Button.enableTextColor = var1.moduleTextOn.getValue().getRGB();
      } else {
         Button.hoverColor = this.hoverColor.getValue().getRGB();
         Button.defaultTextColor = this.defaultTextColor.getValue().getRGB();
         Button.defaultColor = this.defaultColor.getValue().getRGB();
         Button.enableTextColor = this.enableTextColor.getValue().getRGB();
      }
   }

   public Color getActiveColor() {
      return this.getActiveColor(0.0);
   }

   public Color getActiveColor(double delay) {
      ColorsModule var3 = ColorsModule.INSTANCE;
      ColorsModule.ColorMode var4 = var3 != null ? var3.colorMode.getValue() : ColorsModule.ColorMode.Static;
      long var5 = System.currentTimeMillis();
      if (var4 == ColorsModule.ColorMode.Rainbow || var4 == ColorsModule.ColorMode.RainbowDelay) {
         float var17 = (float)(((double)var5 / 3500.0 + delay / 220.0) % 1.0);
         return new Color(Color.HSBtoRGB(var17, 0.65F, 1.0F));
      } else if (var4 == ColorsModule.ColorMode.SimpleRainbow) {
         float var16 = (float)((double)var5 / 4500.0 % 1.0);
         return new Color(Color.HSBtoRGB(var16, 0.58F, 1.0F));
      } else if (var4 == ColorsModule.ColorMode.Pulse) {
         float var15 = (float)((Math.sin((double)var5 / 360.0 + delay / 28.0) + 1.0) * 0.5);
         return blend(this.activeColor.getValue(), this.color.getValue(), var15);
      } else if (var4 == ColorsModule.ColorMode.Ocean) {
         float var14 = (float)((Math.sin((double)var5 / 520.0 + delay / 38.0) + 1.0) * 0.5);
         return blend(new Color(224, 80, 255), new Color(255, 107, 214), var14);
      } else if (var4 == ColorsModule.ColorMode.Aurora) {
         float var13 = (float)((Math.sin((double)var5 / 650.0 + delay / 45.0) + 1.0) * 0.5);
         return blend(new Color(255, 107, 214), new Color(182, 108, 255), var13);
      } else if (var4 == ColorsModule.ColorMode.Cotton) {
         float var12 = (float)((Math.sin((double)var5 / 700.0 + delay / 40.0) + 1.0) * 0.5);
         return blend(new Color(255, 182, 238), new Color(210, 170, 255), var12);
      } else if (var4 == ColorsModule.ColorMode.Sunset) {
         float var11 = (float)((Math.sin((double)var5 / 620.0 + delay / 34.0) + 1.0) * 0.5);
         return blend(new Color(255, 150, 128), new Color(154, 134, 255), var11);
      } else if (var4 == ColorsModule.ColorMode.Ice) {
         float var10 = (float)((Math.sin((double)var5 / 680.0 + delay / 42.0) + 1.0) * 0.5);
         return blend(new Color(236, 190, 255), new Color(255, 107, 214), var10);
      } else if (var4 == ColorsModule.ColorMode.Sakura) {
         float var9 = (float)((Math.sin((double)var5 / 760.0 + delay / 44.0) + 1.0) * 0.5);
         return blend(new Color(255, 188, 220), new Color(196, 182, 255), var9);
      } else if (var4 == ColorsModule.ColorMode.Mint) {
         float var8 = (float)((Math.sin((double)var5 / 700.0 + delay / 36.0) + 1.0) * 0.5);
         return blend(new Color(255, 190, 238), new Color(224, 80, 255), var8);
      } else if (var4 == ColorsModule.ColorMode.Cyber) {
         float var7 = (float)((Math.sin((double)var5 / 480.0 + delay / 26.0) + 1.0) * 0.5);
         return blend(new Color(224, 80, 255), new Color(255, 107, 214), var7);
      } else {
         return var3 != null && var4 == ColorsModule.ColorMode.Static ? var3.accent.getValue() : this.activeColor.getValue();
      }
   }

   public Color getColor(double delay) {
      return this.getActiveColor(delay);
   }

   public int getActiveColorRGB(double delay) {
      return this.getActiveColor(delay).getRGB();
   }

   public double animationProgress(long length, Easing easing) {
      return this.animation.get(this.isOn() ? 1.0 : 0.0, Math.max(1L, length), easing);
   }

   public Identifier getSpectrumLutId() {
      return Identifier.of("minecraft", "shaders/post/rainbow.json");
   }

   public void renderSnow(DrawContext context) {
      if (this.snow.getValue() && mc != null && mc.getWindow() != null) {
         int var2 = Math.max(1, mc.getWindow().getScaledWidth());
         int var3 = Math.max(1, mc.getWindow().getScaledHeight());
         int var4 = Math.max(0, this.snowAmount.getValueInt());

         while (this.snowflakes.size() < var4) {
            this.snowflakes.add(this.newSnow(var2, var3));
         }

         while (this.snowflakes.size() > var4) {
            this.snowflakes.remove(this.snowflakes.size() - 1);
         }

         for (Snow var6 : this.snowflakes) {
            var6.drawSnow(
               context,
               var2,
               var3,
               this.snowSpeed.getValueFloat(),
               this.snowSize.getValueFloat(),
               this.snowWind.getValueFloat(),
               this.snowAlpha.getValueInt(),
               this.snowShape.getValue() == ClickGui.SnowShape.Star
            );
         }
      } else {
         this.snowflakes.clear();
      }
   }

   private Snow newSnow(int width, int height) {
      int var3 = this.snowRandom.nextInt(Math.max(1, width));
      int var4 = this.snowRandom.nextInt(Math.max(1, height + 20)) - 20;
      int var5 = Math.max(1, Math.round(this.snowSpeed.getValueFloat() / 12.0F) + this.snowRandom.nextInt(3));
      int var6 = Math.max(1, Math.round(this.snowSize.getValueFloat()));
      return new Snow(var3, var4, var5, var6);
   }

   public int getSpectrumLutHeight() {
      return this.spectrumLut != null ? this.spectrumLut.length : 0;
   }

   public void updateSpectrumLut(int height) {
      if (this.spectrumLut == null || this.spectrumLut.length != height) {
         this.spectrumLut = new int[height];

         for (int var2 = 0; var2 < height; var2++) {
            float var3 = (float)var2 / (float)height;
            this.spectrumLut[var2] = Color.HSBtoRGB(var3, 0.8F, 1.0F);
         }
      }
   }

   private static Color blend(Color a, Color b, float t) {
      t = Math.max(0.0F, Math.min(1.0F, t));
      int var3 = (int)((float)a.getRed() + (float)(b.getRed() - a.getRed()) * t);
      int var4 = (int)((float)a.getGreen() + (float)(b.getGreen() - a.getGreen()) * t);
      int var5 = (int)((float)a.getBlue() + (float)(b.getBlue() - a.getBlue()) * t);
      int var6 = (int)((float)a.getAlpha() + (float)(b.getAlpha() - a.getAlpha()) * t);
      return new Color(var3, var4, var5, var6);
   }

   static {

      key = "";
   }
@Environment(EnvType.CLIENT)
   public static enum BackgroundStyle {
      Dark,
      Transparent;

}

   @Environment(EnvType.CLIENT)
   public static enum BlurType {
      Box,
      Tent,
      Gaussian,
      Kawase,
      Radial;

}

   @Environment(EnvType.CLIENT)
   public static enum ColorMode {
      Static,
      Rainbow,
      Spectrum;

}

   @Environment(EnvType.CLIENT)
   public static enum ExpandIcon {
      Arrow,
      Plus,
      Circle,
      PlusMinus,
      Chevron,
      Gear;

}

   @Environment(EnvType.CLIENT)
   public class FadeOut {
      @EventListener(
         priority = -99999
      )
      public void onRender2D(Render2DEvent event) {
         if (ClickGui.this.fade.getValue()) {
            if (ClickGui.this.alphaValue > 0.0 || ClickGui.this.isOn()) {
               ClickGui.this.alphaValue = ClickGui.this.animation
                  .get(ClickGui.this.isOn() ? 1.0 : 0.0, (long)ClickGui.this.length.getValueInt(), ClickGui.this.easing.getValue());
            }

            if (ClickGui.this.alphaValue > 0.0
               && !(Wrapper.mc.currentScreen instanceof DropdownClickGUI)
               && !(Wrapper.mc.currentScreen instanceof ClickGuiScreen)
               && !(Wrapper.mc.currentScreen instanceof EpsilonClickGUI)) {
               event.drawContext.getMatrices().push();
               event.drawContext.getMatrices().translate(0.0F, 0.0F, 5000.0F);
               ClickGuiScreen.getInstance().render(event.drawContext, 0, 0, event.tickDelta);
               event.drawContext.getMatrices().pop();
            }
         } else {
            ClickGui.this.alphaValue = 1.0;
         }
      }
   }

   @Environment(EnvType.CLIENT)
   public static enum SnowShape {
      Circle,
      Star;

}
}
