package dev.crucifixbeta.mod.gui.windows;

import com.mojang.blaze3d.systems.RenderSystem;
import dev.crucifixbeta.api.utils.math.AnimateUtil;
import dev.crucifixbeta.api.utils.math.MathUtil;
import dev.crucifixbeta.api.utils.render.ColorUtil;
import dev.crucifixbeta.api.utils.render.Render2DUtil;
import dev.crucifixbeta.core.impl.FontManager;
import dev.crucifixbeta.mod.modules.impl.client.ClickGui;
import java.awt.Color;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.util.Identifier;

@Environment(EnvType.CLIENT)
public class WindowBase {
   private final String name;
   private final Identifier icon;
   private float x;
   private float y;
   private float width;
   private float height;
   private float dragX;
   private float dragY;
   private float scrollOffset;
   private float prevScrollOffset;
   private float maxElementsHeight;
   private boolean dragging;
   private boolean hoveringWindow;
   private boolean scaling;
   private boolean scrolling;
   private boolean visible = true;

   protected WindowBase(float x, float y, float width, float height, String name, Identifier icon) {
      this.setX(x);
      this.setY(y);
      this.setWidth(width);
      this.setHeight(height);
      this.name = name;
      this.icon = icon;
   }

   public void render(DrawContext context, int mouseX, int mouseY) {
      if (this.dragging && WindowsScreen.draggingWindow == this) {
         this.x = (float)mouseX - this.dragX;
         this.y = (float)mouseY - this.dragY;
      } else if (this.scaling && WindowsScreen.lastClickedWindow == this) {
         float var4 = (float)mouseX - this.dragX;
         float var5 = (float)mouseY - this.dragY;
         this.width = Math.max(120.0F, var4);
         this.height = Math.max(80.0F, var5);
      }

      this.prevScrollOffset = AnimateUtil.fast(this.prevScrollOffset, this.scrollOffset, 12.0F);
      ClickGui var35 = ClickGui.getInstance();
      Color var36 = new Color(-983868581, true);
      RenderSystem.enableBlend();
      float var6 = var35 != null ? (float)var35.categoryBarHeight.getValueInt() : 14.0F;
      float var7 = this.x;
      float var8 = this.y;
      float var9 = this.width;
      int var10 = var35 != null ? var35.topAlpha.getValueInt() : 210;
      if (var35 != null && var35.colorMode.getValue() == ClickGui.ColorMode.Spectrum) {
         Render2DUtil.drawLutRect(context.getMatrices(), var7, var8, var9, var6, var35.getSpectrumLutId(), var35.getSpectrumLutHeight(), var10);
      } else {
         Color var11 = var35 != null ? ColorUtil.injectAlpha(var35.getColor((double)var8 / 10.0), var10) : new Color(0, 120, 212, var10);
         Render2DUtil.drawRect(context.getMatrices(), var7, var8, var9, var6, var11);
      }

      if (var35 == null || var35.backgroundStyle.getValue() != ClickGui.BackgroundStyle.Transparent) {
         int var37 = var35 != null ? var35.hoverColor.getValue().getRGB() : new Color(50, 50, 50, 200).getRGB();
         Render2DUtil.drawRectWithOutline(context.getMatrices(), var7, var8, var9, var6, new Color(0, 0, 0, 0), new Color(var37));
      }

      if (var35 == null || var35.backGround.booleanValue) {
         int var38 = var35 != null ? var35.backgroundAlpha.getValueInt() : 236;
         Color var12 = var35 != null ? ColorUtil.injectAlpha(var35.backGround.getValue(), var38) : new Color(30, 30, 30, var38);
         Render2DUtil.drawRect(context.getMatrices(), this.x, this.y + var6, this.width, this.height - var6, var12);
         int var13 = var35 != null ? var35.hoverColor.getValue().getRGB() : new Color(50, 50, 50, 200).getRGB();
         Render2DUtil.drawRectWithOutline(context.getMatrices(), this.x, this.y + var6, this.width, this.height - var6, new Color(0, 0, 0, 0), new Color(var13));
      }

      float var39 = FontManager.isCustomFontEnabled() ? FontManager.ui.getFontHeight() : 9.0F;
      float var40 = var8 + (var6 - var39) / 2.0F + (var35 != null ? (float)var35.titleOffset.getValueInt() : 0.0F);
      FontManager.ui.drawString(context.getMatrices(), this.name, (double)(this.x + 6.0F), (double)var40, -1);
      float var41 = this.y + (var6 - 10.0F) / 2.0F;
      boolean var14 = Render2DUtil.isHovered((double)mouseX, (double)mouseY, (double)(this.x + this.width - 14.0F), (double)var41, 10.0, 10.0);
      int var15 = var35 != null
         ? (var14 ? var35.hoverColor.getValue().getRGB() : var35.defaultColor.getValue().getRGB())
         : (var14 ? new Color(-982026377, true).getRGB() : new Color(-984131753, true).getRGB());
      Render2DUtil.rect(context.getMatrices(), this.x + this.width - 14.0F, var41, this.x + this.width - 4.0F, var41 + 10.0F, var15);
      float var16 = this.getScrollTop(var6);
      float var17 = this.getScrollHeight(var6);
      float var18 = this.getScrollBarWidth();
      float var19 = this.x + this.width - var18;
      float var20 = Math.max(1.0F, this.maxElementsHeight);
      float var21 = var17 / var20;
      float var22 = Math.min(var17, var17 * var21);
      float var23 = var16 - this.scrollOffset * var21;
      float var24 = var16 + var17 - var22;
      if (var23 < var16) {
         var23 = var16;
      }

      if (var23 > var24) {
         var23 = var24;
      }

      boolean var25 = Render2DUtil.isHovered((double)mouseX, (double)mouseY, (double)var19, (double)var16, (double)var18, (double)var17);
      Render2DUtil.drawRectWithOutline(
         context.getMatrices(), var19, var16, var18, var17, var25 ? new Color(1595085587, true) : new Color(1593835520, true), var36
      );
      Render2DUtil.drawRect(context.getMatrices(), var19, var23, var18, var22, new Color(-1590611663, true));
      float var26 = this.x + this.width - 14.0F;
      float var28 = var26 + 10.0F;
      float var29 = var41 + 10.0F;
      String var30 = "x";
      float var31 = var26 + (10.0F - FontManager.ui.getWidth(var30)) / 2.0F;
      float var32 = var41 + (10.0F - FontManager.ui.getFontHeight()) / 2.0F;
      FontManager.ui.drawString(context.getMatrices(), var30, (double)var31, (double)var32, -1);
      RenderSystem.disableBlend();
      if (this.scrolling) {
         float var33 = ((float)mouseY - var16) / var17;
         float var34 = this.getScrollRange(var17);
         this.scrollOffset = -(var33 * var34);
         this.scrollOffset = MathUtil.clamp(this.scrollOffset, -var34, 0.0F);
      }

      this.hoveringWindow = Render2DUtil.isHovered(
         (double)mouseX, (double)mouseY, (double)this.getX(), (double)this.getY(), (double)this.getWidth(), (double)this.getHeight()
      );
      Render2DUtil.drawLine(
         context.getMatrices(),
         this.getX() + this.getWidth(),
         this.getY() + this.getHeight() - 3.0F,
         this.getX() + this.getWidth() + 7.0F,
         this.getY() + this.getHeight() - 10.0F,
         var36.getRGB()
      );
      Render2DUtil.drawLine(
         context.getMatrices(),
         this.getX() + this.getWidth() + 5.0F,
         this.getY() + this.getHeight() - 3.0F,
         this.getX() + this.getWidth() + 7.0F,
         this.getY() + this.getHeight() - 5.0F,
         var36.getRGB()
      );
   }

   public void mouseClicked(double mouseX, double mouseY, int button) {
      ClickGui var6 = ClickGui.getInstance();
      float var7 = var6 != null ? (float)var6.categoryBarHeight.getValueInt() : 14.0F;
      float var8 = this.y + (var7 - 10.0F) / 2.0F;
      if (Render2DUtil.isHovered(mouseX, mouseY, (double)(this.x + this.width - 14.0F), (double)var8, 10.0, 10.0)) {
         this.setVisible(false);
      } else if (Render2DUtil.isHovered(mouseX, mouseY, (double)this.x, (double)this.y, (double)this.width, (double)var7)) {
         if (WindowsScreen.draggingWindow == null) {
            this.dragging = true;
         }

         if (WindowsScreen.draggingWindow == null) {
            WindowsScreen.draggingWindow = this;
         }

         WindowsScreen.lastClickedWindow = this;
         this.dragX = (float)((int)(mouseX - (double)this.getX()));
         this.dragY = (float)((int)(mouseY - (double)this.getY()));
      } else if (Render2DUtil.isHovered(mouseX, mouseY, (double)(this.x + this.width), (double)(this.y + this.height - 10.0F), 10.0, 10.0)) {
         WindowsScreen.lastClickedWindow = this;
         this.dragX = (float)((int)(mouseX - (double)this.getWidth()));
         this.dragY = (float)((int)(mouseY - (double)this.getHeight()));
         this.scaling = true;
      } else {
         float var9 = this.getScrollTop(var7);
         float var10 = this.getScrollHeight(var7);
         float var11 = this.getScrollBarWidth();
         float var12 = this.x + this.width - var11;
         if (Render2DUtil.isHovered(mouseX, mouseY, (double)var12, (double)var9, (double)var11, (double)var10)) {
            WindowsScreen.lastClickedWindow = this;
            this.dragX = (float)((int)(mouseX - (double)this.getWidth()));
            this.dragY = (float)((int)(mouseY - (double)this.getHeight()));
            this.scrolling = true;
         }
      }
   }

   public void keyPressed(int keyCode, int scanCode, int modifiers) {
   }

   public void charTyped(char key, int keyCode) {
   }

   public void mouseScrolled(int i) {
      if (this.hoveringWindow) {
         this.scrollOffset += (float)(i * 16);
         ClickGui var2 = ClickGui.getInstance();
         float var3 = var2 != null ? (float)var2.categoryBarHeight.getValueInt() : 14.0F;
         float var4 = this.getScrollHeight(var3);
         float var5 = this.getScrollRange(var4);
         this.scrollOffset = MathUtil.clamp(this.scrollOffset, -var5, 0.0F);
      }
   }

   protected float getScrollTop(float headerH) {
      return this.y + headerH + 3.0F;
   }

   protected float getScrollHeight(float headerH) {
      return Math.max(1.0F, this.getHeight() - headerH - 6.0F);
   }

   protected float getScrollRange(float scrollH) {
      return Math.max(0.0F, this.maxElementsHeight - scrollH);
   }

   protected float getScrollBarWidth() {
      return 6.0F;
   }

   public void mouseReleased(double mouseX, double mouseY, int button) {
      this.dragging = false;
      this.scaling = false;
      this.scrolling = false;
      WindowsScreen.draggingWindow = null;
   }

   public float getX() {
      return this.x;
   }

   public void setPosition(float x, float y) {
      this.setX(x);
      this.setY(y);
   }

   protected void setX(float x) {
      this.x = x;
   }

   public float getY() {
      return this.y;
   }

   protected void setY(float y) {
      this.y = y;
   }

   public float getWidth() {
      return this.width;
   }

   protected void setWidth(float width) {
      this.width = width;
   }

   public float getHeight() {
      return this.height;
   }

   protected void setHeight(float height) {
      this.height = height;
   }

   protected float getScrollOffset() {
      return this.prevScrollOffset;
   }

   protected void resetScroll() {
      this.prevScrollOffset = 0.0F;
      this.scrollOffset = 0.0F;
   }

   protected void setMaxElementsHeight(float maxElementsHeight) {
      this.maxElementsHeight = maxElementsHeight;
   }

   public boolean isVisible() {
      return this.visible;
   }

   public void setVisible(boolean visible) {
      this.visible = visible;
   }

   public Identifier getIcon() {
      return this.icon;
   }
}
