import { system, world, EquipmentSlot, EntityEquippableComponent, ItemStack, Player } from "@minecraft/server";

// #region Utils
import { getObjective, getEquipment, getArmor, getPlayers } from "./utils.js";
// #endregion

const voidBoostScore = getObjective("void_boost");
const voidTouched = getObjective("voidtouched");
const overheatTimer = getObjective("overheat_timer");

// #region soft boots
function getBlockUnderPlayer(player) {
  const yVel = player.getVelocity().y * 2.0;
  const raycast = player.dimension.getBlockFromRay(
    player.location,
    { x: 0, y: -1, z: 0 },
    { includeLiquidBlocks: false, includePassableBlocks: false, maxDistance: yVel < -1.1 ? Math.abs(yVel) + 0.95 : 0.8 }
  );
  return raycast?.block;
}
const softLandingTest = ["slime_boots", "dragonscale_boots"];
system.runInterval(() => {
  for (const player of getPlayers()) {
    const isNotFalling = player.isOnGround && !player.isFalling;
    const equipment = getEquipment(player);
    if (!equipment) continue;

    const feetItem = equipment.getEquipment(EquipmentSlot.Feet);
    if (!feetItem) continue;
    const hasSoftBoots = softLandingTest.some((typeId) => feetItem.typeId.includes(typeId));
    if (!hasSoftBoots) continue;
    if (!isNotFalling) {
      const blockUnderPlayer = getBlockUnderPlayer(player);
      if (blockUnderPlayer) {
        player.addEffect("slow_falling", 8, { amplifier: 0, showParticles: false });
      }
    }
  }
});
// #endregion

// #region paladin
system.runInterval(() => {
  for (const player of getPlayers()) {
    const equipment = getEquipment(player);
    const chestItem = equipment?.getEquipment(EquipmentSlot.Chest);
    if (!chestItem?.typeId.includes("paladin")) continue;
    player.addEffect("resistance", 8, { amplifier: 0, showParticles: false });
    if (!(chestItem.typeId.includes("cobalt") || chestItem.typeId.includes("enderium") || chestItem.typeId.includes("slime"))) {
      player.addEffect("slowness", 8, { amplifier: 0, showParticles: false });
    }
}}, 4);
// #endregion

// #region set bonuses
system.runInterval(() => {
  for (const player of getPlayers()) {
    const { head, chest, legs, feet } = getArmor(player);
    if (!head || !chest || !legs || !feet) continue;

    const viewDirection = player.getViewDirection();
    const directionX = viewDirection.x;
    const directionZ = viewDirection.z;
    if (head.typeId.includes("dragonscale") && (chest.typeId.includes("dragonscale") || chest.typeId.includes("elytra")) && legs.typeId.includes("dragonscale") && feet.typeId.includes("dragonscale") ) {
      if (player.getEffect("poison")) { player.removeEffect("poison"); }
      if (player.getEffect("fatal_poison")) { player.removeEffect("fatal_poison"); }
      if (player.isOnGround) { voidBoostScore.setScore(player, 0); }
      const voidBoostValue = voidBoostScore.getScore(player);
      const voidTouchedValue = voidTouched.getScore(player);
      const isVoidtouched = voidTouchedValue === 1;
      if (player.dimension.id === "minecraft:overworld") {
        if (player.location.y < -64) {
          player.addEffect("blindness", 30, { amplifier: 0, showParticles: false });
          player.teleport({ x: player.location.x, y: 340, z: player.location.z });
        }
      }
      if (player.dimension.id === "minecraft:the_end") {
        if (player.location.y < 9) {
          if (!player.isOnGround && player.isGliding) { voidBoostScore.setScore(player, 1); }
          if (!isVoidtouched) {
            player.runCommand("fog @s push minecraft:fog_warped_forest voidtouched");
            voidTouched.setScore(player, 1);
          }
          player.addEffect("conduit_power", 4, { amplifier: 0, showParticles: false });
          if (player.location.y < 5) {
            if (player.location.y < 0) {
              player.addEffect("blindness", 30, { amplifier: 0, showParticles: false });
              player.teleport({ x: player.location.x, y: 340, z: player.location.z });
            }
          }
        } else if (isVoidtouched) {
          player.runCommand("fog @s remove voidtouched");
          voidTouched.setScore(player, 0);
        }
      }
      if (voidBoostValue > 0 && player.isGliding) {
        player.applyKnockback(directionX, directionZ, 6.4, 0.0);
        player.runCommand("execute as @s anchored feet run particle hax:dynamic_sonic_explosion");
        voidBoostScore.addScore(player, -1);
      }
    } else { voidBoostScore.setScore(player, 0); return; }
}});

system.runInterval(() => {
  for (const player of getPlayers()) {
    if (player.dimension.id !== "minecraft:the_end" || !player.isGliding) continue;
    if (player.location.y >= 5) continue;
    player.playSound("hax:bubble.down", { location: player.location, volume: 0.3 });
  }
}, 12);
system.runInterval(() => {
  for (const player of getPlayers()) {
    if (player.dimension.id !== "minecraft:the_end" || player.isGliding) continue;
    if (player.location.y >= 9) continue;
    player.playSound("hax:bubble.down", { location: player.location, volume: 0.2 });
  }
}, 60);

system.runInterval(() => {
  for (const player of getPlayers()) {
    const { head, chest, legs, feet } = getArmor(player);
    if (!head || !chest || !legs || !feet) continue;
    if (head.typeId.includes("enderium") && chest.typeId.includes("enderium") && legs.typeId.includes("enderium") && feet.typeId.includes("enderium")) {
      if (player.getEffect("poison")) { player.removeEffect("poison"); }
      if (player.getEffect("fatal_poison")) { player.removeEffect("fatal_poison"); }
      if (player.getEffect("slowness")) { player.removeEffect("slowness"); }
      //if (player.getEffect("nausea")) { player.removeEffect("nausea"); }
      //if (player.getEffect("blindness")) { player.removeEffect("blindness"); }
    }
}});

system.runInterval(() => {
  for (const player of getPlayers()) {
    const { head, chest, legs, feet } = getArmor(player);
    if (!head || !chest || !legs || !feet) continue;

    const overheatValue = overheatTimer.getScore(player);
    if (head.typeId.includes("netherite") && chest.typeId.includes("netherite") && legs.typeId.includes("netherite") && feet.typeId.includes("netherite")) {
      player.runCommand("function fiery");
      if (239 >= overheatValue) {
        overheatTimer.addScore(player, 1);
        player.runCommand("function overheat");
      } else if (overheatValue === undefined) {
        overheatTimer.addScore(player, 0);
      }
    }
}},2);
// #endregion