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

import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.api.utils.math.Easing;
import dev.crucifixbeta.api.utils.math.FadeUtils;
import dev.crucifixbeta.api.utils.math.Timer;
import dev.crucifixbeta.api.utils.render.ColorUtil;
import dev.crucifixbeta.api.utils.render.Render3DUtil;
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.HashMap;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;

@Environment(EnvType.CLIENT)
public class PlaceRender extends Module {
   public static final HashMap<BlockPos, PlaceRender.PlacePos> renderMap;
   public static PlaceRender INSTANCE;
   public final SliderSetting fadeTime = this.add(new SliderSetting("FadeTime", 500, 0, 3000));
   public final SliderSetting timeout = this.add(new SliderSetting("TimeOut", 500, 0, 3000));
   private final ColorSetting box = this.add(new ColorSetting("Box", new Color(255, 255, 255, 255)).injectBoolean(true));
   private final ColorSetting fill = this.add(new ColorSetting("Fill", new Color(255, 255, 255, 100)).injectBoolean(true));
   private final ColorSetting tryPlaceBox = this.add(new ColorSetting("TryPlaceBox", new Color(178, 178, 178, 255)).injectBoolean(true));
   private final ColorSetting tryPlaceFill = this.add(new ColorSetting("TryPlaceFill", new Color(255, 119, 119, 157)).injectBoolean(true));
   private final BooleanSetting noFail = this.add(new BooleanSetting("NoFail", false));
   private final EnumSetting<Easing> ease = this.add(new EnumSetting<>("Ease", Easing.CubicInOut));
   private final EnumSetting<PlaceRender.Mode> mode = this.add(new EnumSetting<>("Mode", PlaceRender.Mode.All));

   public PlaceRender() {
      super("PlaceRender", Module.Category.Render);
      this.setChinese("\u653e\u7f6e\u663e\u793a");
      this.enable();
      INSTANCE = this;
   }

   @Override
   public void onRender3D(MatrixStack matrixStack) {
      renderMap.values().removeIf(v -> v.draw(matrixStack));
   }

   public void create(BlockPos pos) {
      renderMap.put(pos, new PlaceRender.PlacePos(pos));
   }

   static {

      renderMap = new HashMap<>();
   }
@Environment(EnvType.CLIENT)
   private static enum Mode {
      Fade,
      Shrink,
      All;

}

   @Environment(EnvType.CLIENT)
   public class PlacePos {
      public final FadeUtils fade = new FadeUtils((long)PlaceRender.this.fadeTime.getValue());
      public final BlockPos pos;
      public final Timer timer;
      public boolean isAir;

      public PlacePos(BlockPos placePos) {
         this.pos = placePos;
         this.timer = new Timer();
         this.isAir = true;
      }

      public boolean draw(MatrixStack matrixStack) {
         if (this.isAir) {
            if (!PlaceRender.this.noFail.getValue() && Wrapper.mc.world.isAir(this.pos)) {
               if (!this.timer.passedMs(PlaceRender.this.timeout.getValue())) {
                  this.fade.reset();
                  Box var2 = new Box(this.pos);
                  if (PlaceRender.this.tryPlaceFill.booleanValue) {
                     Render3DUtil.drawFill(matrixStack, var2, PlaceRender.this.tryPlaceFill.getValue());
                  }

                  if (PlaceRender.this.tryPlaceBox.booleanValue) {
                     Render3DUtil.drawBox(matrixStack, var2, PlaceRender.this.tryPlaceBox.getValue());
                  }
               }

               return false;
            }

            this.isAir = false;
         }

         double var3;
         if ((var3 = this.fade.ease(PlaceRender.this.ease.getValue())) == 1.0) {
            return true;
         } else {
            double var5 = PlaceRender.this.mode.getValue() != PlaceRender.Mode.Fade && PlaceRender.this.mode.getValue() != PlaceRender.Mode.All
               ? 1.0
               : 1.0 - var3;
            double var7 = PlaceRender.this.mode.getValue() != PlaceRender.Mode.Shrink && PlaceRender.this.mode.getValue() != PlaceRender.Mode.All ? 0.0 : var3;
            Box var9 = new Box(this.pos).expand(-var7 * 0.5, -var7 * 0.5, -var7 * 0.5);
            if (PlaceRender.this.fill.booleanValue) {
               Render3DUtil.drawFill(
                  matrixStack, var9, ColorUtil.injectAlpha(PlaceRender.this.fill.getValue(), (int)((double)PlaceRender.this.fill.getValue().getAlpha() * var5))
               );
            }

            if (PlaceRender.this.box.booleanValue) {
               Render3DUtil.drawBox(
                  matrixStack, var9, ColorUtil.injectAlpha(PlaceRender.this.box.getValue(), (int)((double)PlaceRender.this.box.getValue().getAlpha() * var5))
               );
            }

            return false;
         }
      }
   }
}
