package dev.crucifixbeta.mod.gui;

import com.mojang.blaze3d.systems.RenderSystem;
import dev.crucifixbeta.api.utils.render.Render2DUtil;
import dev.crucifixbeta.core.impl.FontManager;
import java.awt.Color;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.render.VertexFormat.DrawMode;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import org.joml.Matrix4f;

@Environment(EnvType.CLIENT)
public class StartupAnimationScreen extends Screen {
   private static final Identifier BG;
   private static final long TOTAL_MS;
   private static boolean played;
   private long initTime;

   public StartupAnimationScreen() {
      super(Text.literal("CrucifiX"));
   }

   public static boolean hasPlayed() {
      return played;
   }

   @Override
   protected void init() {
      this.initTime = Util.getMeasuringTimeMs();
   }

   @Override
   public void tick() {
      if (Util.getMeasuringTimeMs() - this.initTime >= 6000L && this.client != null) {
         played = true;
         this.client.setScreen(EpsilonMainMenuScreen.INSTANCE);
      }
   }

   @Override
   public void render(DrawContext context, int mouseX, int mouseY, float delta) {
      int var5 = this.width;
      int var6 = this.height;
      float var7 = (float)(Util.getMeasuringTimeMs() - this.initTime) / 1000.0F;
      float var8 = easeOut(saturate(var7 / 0.95F));
      float var9 = easeOut(saturate((var7 - 0.35F) / 1.15F));
      float var10 = easeInOut(saturate((var7 - 1.05F) / 1.6F));
      float var11 = easeOut(saturate((var7 - 1.55F) / 1.05F));
      float var12 = easeInOut(saturate(var7 / 5.35F));
      float var13 = easeInOut(saturate((var7 - 5.35F) / 0.65F));
      float var14 = 1.0F - var13;
      float var15 = 1.0F - var13 * 0.18F;
      float var16 = (float)var5 / 2.0F;
      float var17 = (float)var6 / 2.0F;
      this.renderStartupBackground(context, var5, var6, var15, var8);
      this.renderStage(context, var16, var17, var8, var10, var14);
      this.renderMark(context, var16, var17 - 30.0F, var9, var10, var14, var7);
      this.renderWordmark(context, var16, var17 + 26.0F, var11, var14);
      this.renderProgress(context, var16, var17 + 70.0F, var12, var14);
   }

   @Override
   public boolean shouldPause() {
      return false;
   }

   @Override
   public boolean shouldCloseOnEsc() {
      return false;
   }

   private void renderStartupBackground(DrawContext ctx, int w, int h, float alpha, float entrance) {
      RenderSystem.enableBlend();
      RenderSystem.setShader(GameRenderer::getPositionTexProgram);
      RenderSystem.setShaderTexture(0, BG);
      Matrix4f var6 = ctx.getMatrices().peek().getPositionMatrix();
      BufferBuilder var7 = Tessellator.getInstance().begin(DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
      var7.vertex(var6, 0.0F, (float)h, 0.0F).texture(0.0F, 1.0F);
      var7.vertex(var6, (float)w, (float)h, 0.0F).texture(1.0F, 1.0F);
      var7.vertex(var6, (float)w, 0.0F, 0.0F).texture(1.0F, 0.0F);
      var7.vertex(var6, 0.0F, 0.0F, 0.0F).texture(0.0F, 0.0F);
      BufferRenderer.drawWithGlobalProgram(var7.end());
      RenderSystem.disableBlend();
      Render2DUtil.drawRect(ctx.getMatrices(), 0.0F, 0.0F, (float)w, (float)h, rgba(8, 8, 11, (int)(218.0F * alpha)));
      Render2DUtil.verticalGradient(
         ctx.getMatrices(), 0.0F, 0.0F, (float)w, (float)h, rgba(31, 28, 38, (int)(54.0F * alpha * entrance)), rgba(5, 5, 7, (int)(126.0F * alpha))
      );
      Render2DUtil.verticalGradient(ctx.getMatrices(), 0.0F, 0.0F, (float)w, (float)h * 0.28F, rgba(0, 0, 0, (int)(88.0F * alpha)), rgba(0, 0, 0, 0));
      Render2DUtil.verticalGradient(
         ctx.getMatrices(), 0.0F, (float)h * 0.68F, (float)w, (float)h * 0.32F, rgba(0, 0, 0, 0), rgba(0, 0, 0, (int)(118.0F * alpha))
      );
      Render2DUtil.horizontalGradient(ctx.getMatrices(), 0.0F, 0.0F, (float)w * 0.24F, (float)h, rgba(0, 0, 0, (int)(72.0F * alpha)), rgba(0, 0, 0, 0));
      Render2DUtil.horizontalGradient(ctx.getMatrices(), (float)w * 0.76F, 0.0F, (float)w, (float)h, rgba(0, 0, 0, 0), rgba(0, 0, 0, (int)(72.0F * alpha)));
   }

   private void renderStage(DrawContext ctx, float cx, float cy, float entrance, float rails, float alpha) {
      float var7 = 218.0F * entrance;
      float var8 = 124.0F;
      float var9 = cx - var7 / 2.0F;
      float var10 = cy - 86.0F;
      int var11 = (int)(9.0F * entrance * alpha);
      int var12 = (int)(72.0F * rails * alpha);
      Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), var9, var10, var7, var8, 18.0F, new Color(255, 255, 255, var11));
      float var13 = 72.0F * rails;
      Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), cx - 106.0F, cy - 78.0F, var13, 1.25F, 0.65F, new Color(210, 204, 226, var12));
      Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), cx + 106.0F - var13, cy - 78.0F, var13, 1.25F, 0.65F, new Color(210, 204, 226, var12));
      Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), cx - 106.0F, cy + 43.0F, var13, 1.25F, 0.65F, new Color(116, 106, 146, var12));
      Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), cx + 106.0F - var13, cy + 43.0F, var13, 1.25F, 0.65F, new Color(116, 106, 146, var12));
   }

   private void renderMark(DrawContext ctx, float cx, float cy, float progress, float rails, float alpha, float elapsed) {
      float var8 = Math.max(0.04F, progress);
      float var9 = 1.0F + (1.0F - progress) * 0.045F;
      float var10 = 52.0F * var9;
      float var11 = 6.6F;
      float var12 = 0.5F + (float)Math.sin((double)(elapsed * 2.2F)) * 0.5F;
      int var13 = (int)((62.0F + var12 * 18.0F) * alpha * progress);
      int var14 = (int)(228.0F * alpha * progress);
      int var15 = (int)(95.0F * alpha * rails);
      Render2DUtil.drawRoundedRectForcedAA(
         ctx.getMatrices(),
         cx - var10 / 2.0F - 8.0F,
         cy - var10 / 2.0F - 8.0F,
         var10 + 16.0F,
         var10 + 16.0F,
         17.0F,
         new Color(255, 255, 255, (int)(8.0F * alpha * progress))
      );
      Render2DUtil.drawRoundedRectForcedAA(
         ctx.getMatrices(),
         cx - var10 / 2.0F - 2.0F,
         cy - var10 / 2.0F - 2.0F,
         var10 + 4.0F,
         var10 + 4.0F,
         13.0F,
         new Color(168, 151, 214, (int)(10.0F * alpha * rails))
      );
      Render2DUtil.drawRoundedRectForcedAA(
         ctx.getMatrices(), cx - var11 / 2.0F, cy - var10 * var8 / 2.0F, var11, var10 * var8, 3.5F, new Color(225, 222, 232, var14)
      );
      Render2DUtil.drawRoundedRectForcedAA(
         ctx.getMatrices(), cx - var10 * var8 / 2.0F, cy - var11 / 2.0F, var10 * var8, var11, 3.5F, new Color(225, 222, 232, var14)
      );
      if (rails > 0.01F) {
         float var16 = easeOut(rails);
         Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), cx + 8.0F, cy - 17.0F, 30.0F * var16, 2.6F, 1.3F, new Color(168, 151, 214, var13));
         Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), cx - 34.0F * var16, cy + 14.0F, 30.0F * var16, 2.6F, 1.3F, new Color(168, 151, 214, var13));
         Render2DUtil.drawRoundedRectForcedAA(
            ctx.getMatrices(), cx - var11 / 2.0F, cy - var10 / 2.0F - 4.0F, var11, 8.0F * var16, 3.2F, new Color(168, 151, 214, var15)
         );
         Render2DUtil.drawRoundedRectForcedAA(
            ctx.getMatrices(), cx + var10 / 2.0F - 4.0F, cy - var11 / 2.0F, 8.0F * var16, var11, 3.2F, new Color(168, 151, 214, var15)
         );
      }
   }

   private void renderWordmark(DrawContext ctx, float cx, float y, float progress, float alpha) {
      String var6 = "CrucifiX";
      String var7 = "V3.2";
      boolean var8 = FontManager.ui != null && FontManager.isCustomFontEnabled();
      float var9 = var8 ? 1.85F : 2.0F;
      float var10 = var8 ? 1.2F : 1.8F;
      float var11 = this.measureTrackedWidth(var6, var8, var10) * var9;
      float var12 = cx - var11 / 2.0F;
      float var13 = (1.0F - progress) * 8.0F;
      int var14 = rgba(232, 229, 238, (int)(235.0F * progress * alpha));
      ctx.getMatrices().push();
      ctx.getMatrices().scale(var9, var9, 1.0F);
      this.drawTrackedTextAA(ctx, var6, var12 / var9, (y - var13) / var9, var14, var8, var10, progress);
      ctx.getMatrices().pop();
      int var15 = (int)(105.0F * progress * alpha);
      float var16 = 1.0F;
      float var17 = this.measureTrackedWidth(var7, var8, var16);
      this.drawTrackedTextAA(ctx, var7, cx - var17 / 2.0F, y + 25.0F, rgba(174, 169, 188, var15), var8, var16, progress);
   }

   private void renderProgress(DrawContext ctx, float cx, float y, float progress, float alpha) {
      float var6 = 168.0F;
      float var7 = 2.6F;
      float var8 = cx - var6 / 2.0F;
      int var9 = (int)(52.0F * alpha);
      int var10 = (int)(180.0F * alpha);
      float var11 = Math.max(var7, var6 * progress);
      Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), var8, y, var6, var7, var7 / 2.0F, new Color(255, 255, 255, var9));
      Render2DUtil.drawRoundedRectForcedAA(ctx.getMatrices(), var8, y, var11, var7, var7 / 2.0F, new Color(215, 208, 232, var10));
      if (progress > 0.06F) {
         float var12 = Math.min(22.0F, var11);
         Render2DUtil.drawRoundedRectForcedAA(
            ctx.getMatrices(), var8 + var11 - var12, y - 0.55F, var12, var7 + 1.1F, (var7 + 1.1F) / 2.0F, new Color(244, 239, 255, (int)(96.0F * alpha))
         );
      }

      for (int var14 = 1; var14 < 4; var14++) {
         float var13 = Math.max(0.18F, 1.0F - Math.abs(progress - (float)var14 * 0.25F) * 3.0F);
         Render2DUtil.drawRoundedRectForcedAA(
            ctx.getMatrices(), var8 + var6 * (float)var14 / 4.0F - 0.7F, y + 8.0F, 1.4F, 1.4F, 0.7F, new Color(196, 188, 218, (int)(50.0F * alpha * var13))
         );
      }
   }

   private void drawTrackedTextAA(DrawContext ctx, String text, float x, float y, int color, boolean customFont, float tracking, float reveal) {
      float var9 = x;

      for (int var10 = 0; var10 < text.length(); var10++) {
         String var11 = text.substring(var10, var10 + 1);
         float var12 = easeOut(saturate((reveal - (float)var10 * 0.055F) / 0.42F));
         if (!var11.equals(" ")) {
            this.drawTextAA(ctx, var11, var9, y + (1.0F - var12) * 4.0F, multiplyAlpha(color, var12), customFont);
         }

         var9 += this.measureText(var11, customFont) + tracking;
      }
   }

   private float measureTrackedWidth(String text, boolean customFont, float tracking) {
      float var4 = 0.0F;

      for (int var5 = 0; var5 < text.length(); var5++) {
         var4 += this.measureText(text.substring(var5, var5 + 1), customFont);
      }

      return var4 + (float)Math.max(0, text.length() - 1) * tracking;
   }

   private float measureText(String text, boolean customFont) {
      return customFont ? FontManager.ui.getWidth(text) : (float)this.textRenderer.getWidth(text);
   }

   private void drawTextAA(DrawContext ctx, String text, float x, float y, int color, boolean customFont) {
      if (color >>> 24 != 0) {
         int var7 = multiplyAlpha(color, 0.24F);
         RenderSystem.enableBlend();
         ctx.getMatrices().push();
         ctx.getMatrices().translate(0.24F, 0.0F, 0.0F);
         this.drawTextRaw(ctx, text, x, y, var7, customFont);
         ctx.getMatrices().translate(-0.48F, 0.0F, 0.0F);
         this.drawTextRaw(ctx, text, x, y, var7, customFont);
         ctx.getMatrices().pop();
         this.drawTextRaw(ctx, text, x, y, color, customFont);
         RenderSystem.disableBlend();
      }
   }

   private void drawTextRaw(DrawContext ctx, String text, float x, float y, int color, boolean customFont) {
      if (customFont) {
         FontManager.ui.drawString(ctx.getMatrices(), text, (double)x, (double)y, color, false);
      } else {
         ctx.drawText(this.textRenderer, text, (int)x, (int)y, color, false);
      }
   }

   private static int multiplyAlpha(int color, float multiplier) {
      int var2 = color >>> 24 & 0xFF;
      return Math.max(0, Math.min(255, (int)((float)var2 * multiplier))) << 24 | color & 16777215;
   }

   private static int rgba(int r, int g, int b, int a) {
      return Math.max(0, Math.min(255, a)) << 24 | Math.max(0, Math.min(255, r)) << 16 | Math.max(0, Math.min(255, g)) << 8 | Math.max(0, Math.min(255, b));
   }

   private static float easeOut(float t) {
      t = saturate(t);
      return 1.0F - (1.0F - t) * (1.0F - t) * (1.0F - t);
   }

   private static float easeInOut(float t) {
      t = saturate(t);
      return t * t * (3.0F - 2.0F * t);
   }

   private static float saturate(float v) {
      return Math.max(0.0F, Math.min(1.0F, v));
   }

   static {

      TOTAL_MS = 6000L;
      BG = Identifier.of("crucifixbeta", "textures/gui/background.png");
   }
}
