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

import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.process.ICustomGoalProcess;
import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.UpdateEvent;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;

@Environment(EnvType.CLIENT)
public class BaritoneModule extends Module {
   public static BaritoneModule INSTANCE;
   private final SliderSetting rangeConfig = this.add(new SliderSetting("Range", 4.0, 1.0, 5.0));
   private final BooleanSetting placeConfig = this.add(new BooleanSetting("Place", true));
   private final BooleanSetting breakConfig = this.add(new BooleanSetting("Break", true));
   private final BooleanSetting sprintConfig = this.add(new BooleanSetting("Sprint", true));
   private final BooleanSetting inventoryConfig = this.add(new BooleanSetting("UseInventory", false));
   private final BooleanSetting vinesConfig = this.add(new BooleanSetting("Vines", true));
   private final BooleanSetting jump256Config = this.add(new BooleanSetting("JumpAt256", false));
   private final BooleanSetting waterBucketFallConfig = this.add(new BooleanSetting("WaterBucketFall", false));
   private final BooleanSetting parkourConfig = this.add(new BooleanSetting("Parkour", true));
   private final BooleanSetting parkourPlaceConfig = this.add(new BooleanSetting("ParkourPlace", false));
   private final BooleanSetting parkourAscendConfig = this.add(new BooleanSetting("ParkourAscend", true));
   private final BooleanSetting diagonalAscendConfig = this.add(new BooleanSetting("DiagonalAscend", false));
   private final BooleanSetting diagonalDescendConfig = this.add(new BooleanSetting("DiagonalDescend", false));
   private final BooleanSetting mineDownConfig = this.add(new BooleanSetting("MineDownward", true));
   private final BooleanSetting legitMineConfig = this.add(new BooleanSetting("LegitMine", false));
   private final BooleanSetting logOnArrivalConfig = this.add(new BooleanSetting("LogOnArrival", false));
   private final BooleanSetting freeLookConfig = this.add(new BooleanSetting("FreeLook", true));
   private final BooleanSetting antiCheatConfig = this.add(new BooleanSetting("AntiCheat", true));
   private final BooleanSetting strictLiquidConfig = this.add(new BooleanSetting("Strict-Liquid", false));
   private final BooleanSetting censorCoordsConfig = this.add(new BooleanSetting("CensorCoords", false));
   private final BooleanSetting censorCommandsConfig = this.add(new BooleanSetting("CensorCommands", false));
   private final BooleanSetting chatControl = this.add(new BooleanSetting("ChatControl", false));
   private final BooleanSetting debugConfig = this.add(new BooleanSetting("Debug", false));

   public BaritoneModule() {
      super("Baritone", Module.Category.Client);
      CrucifixBeta.EVENT_BUS.subscribe(this);
      INSTANCE = this;
      this.setChinese("\u5bfb\u8def\u8bbe\u7f6e");
   }

   public static void forward() {
      Direction var0 = mc.player.getHorizontalFacing();
      int var1 = mc.player.getBlockX() + var0.getVector().getX() * 30000000;
      int var2 = mc.player.getBlockZ() + var0.getVector().getZ() * 30000000;
      cancelEverything();
      IBaritone var3 = BaritoneAPI.getProvider().getPrimaryBaritone();
      ICustomGoalProcess var4;
      if (var3 != null && (var4 = var3.getCustomGoalProcess()) != null) {
         var4.setGoalAndPath(new GoalXZ(var1, var2));
      }
   }

   public static boolean isPathing() {
      IBaritone var0 = BaritoneAPI.getProvider().getPrimaryBaritone();
      return var0 != null && var0.getPathingBehavior() != null && var0.getPathingBehavior().isPathing();
   }

   public static void gotoPos(BlockPos pos) {
      IBaritone var1 = BaritoneAPI.getProvider().getPrimaryBaritone();
      if (var1 != null) {
         ICustomGoalProcess var2 = var1.getCustomGoalProcess();
         if (var2 == null) {
            return;
         }

         var2.setGoalAndPath(new GoalBlock(pos.getX(), pos.getY(), pos.getZ()));
      }
   }

   public static void mine(Block block) {
      IBaritone var1 = BaritoneAPI.getProvider().getPrimaryBaritone();
      if (var1 != null) {
         var1.getMineProcess().mine(new Block[]{block});
      }
   }

   public static void cancelEverything() {
      IBaritone var0 = BaritoneAPI.getProvider().getPrimaryBaritone();
      if (var0 != null && var0.getPathingBehavior() != null) {
         var0.getPathingBehavior().cancelEverything();
      }
   }

   public static boolean isActive() {
      IBaritone var0 = BaritoneAPI.getProvider().getPrimaryBaritone();
      if (var0 != null) {
         ICustomGoalProcess var1 = var0.getCustomGoalProcess();
         if (var1 != null && var1.isActive()) {
            return true;
         }

         IPathingControlManager var2 = var0.getPathingControlManager();
         if (var2 != null && var2.mostRecentInControl().isPresent()) {
            return var2.mostRecentInControl().get().isActive();
         }
      }

      return false;
   }

   @EventListener
   public void onUpdate(UpdateEvent event) {
      BaritoneAPI.getSettings().blockReachDistance.value = this.rangeConfig.getValueFloat();
      BaritoneAPI.getSettings().allowPlace.value = this.placeConfig.getValue();
      BaritoneAPI.getSettings().allowBreak.value = this.breakConfig.getValue();
      BaritoneAPI.getSettings().allowSprint.value = this.sprintConfig.getValue();
      BaritoneAPI.getSettings().allowInventory.value = this.inventoryConfig.getValue();
      BaritoneAPI.getSettings().allowVines.value = this.vinesConfig.getValue();
      BaritoneAPI.getSettings().allowJumpAt256.value = this.jump256Config.getValue();
      BaritoneAPI.getSettings().allowWaterBucketFall.value = this.waterBucketFallConfig.getValue();
      BaritoneAPI.getSettings().allowParkour.value = this.parkourConfig.getValue();
      BaritoneAPI.getSettings().allowParkourAscend.value = this.parkourAscendConfig.getValue();
      BaritoneAPI.getSettings().allowParkourPlace.value = this.parkourPlaceConfig.getValue();
      BaritoneAPI.getSettings().allowDiagonalAscend.value = this.diagonalAscendConfig.getValue();
      BaritoneAPI.getSettings().allowDiagonalDescend.value = this.diagonalDescendConfig.getValue();
      BaritoneAPI.getSettings().allowDownward.value = this.mineDownConfig.getValue();
      BaritoneAPI.getSettings().legitMine.value = this.legitMineConfig.getValue();
      BaritoneAPI.getSettings().disconnectOnArrival.value = this.logOnArrivalConfig.getValue();
      BaritoneAPI.getSettings().freeLook.value = this.freeLookConfig.getValue();
      BaritoneAPI.getSettings().antiCheatCompatibility.value = this.antiCheatConfig.getValue();
      BaritoneAPI.getSettings().strictLiquidCheck.value = this.strictLiquidConfig.getValue();
      BaritoneAPI.getSettings().censorCoordinates.value = this.censorCoordsConfig.getValue();
      BaritoneAPI.getSettings().censorRanCommands.value = this.censorCommandsConfig.getValue();
      BaritoneAPI.getSettings().chatControl.value = this.chatControl.getValue();
      BaritoneAPI.getSettings().chatDebug.value = this.debugConfig.getValue();
   }

   @Override
   public void enable() {
      this.state = true;
   }

   @Override
   public void disable() {
      this.state = true;
   }

   @Override
   public boolean isOn() {
      return true;
   }
}
