//прочность для кастомных инструментов
import * as mc from "@minecraft/server";
import {
  world,
  system,
  Player,
  GameMode,
  BlockPermutation,
} from "@minecraft/server";
const useOn_axe = [
  "minecraft:oak_wood",
  "minecraft:spruce_wood",
  "minecraft:birch_wood",
  "minecraft:acacia_wood",
  "minecraft:mangrove_wood",
  "minecraft:pale_oak_wood",
  "minecraft:cherry_wood",
  "minecraft:warped_hyphae",
  "minecraft:crimson_hyphae",
  "minecraft:warped_stem",
  "minecraft:crimson_stem",
  "minecraft:oak_log",
  "minecraft:spruce_log",
  "minecraft:birch_log",
  "minecraft:acacia_log",
  "minecraft:mangrove_log",
  "minecraft:cherry_log",
  "minecraft:pale_oak_log",
  "minecraft:exposed_copper",
  "minecraft:weathered_copper",
  "minecraft:oxidized_copper",
  "minecraft:waxed_exposed_copper",
  "minecraft:waxed_weathered_copper",
  "minecraft:waxed_oxidized_copper",
  "minecraft:exposed_cut_copper",
  "minecraft:weathered_cut_copper",
  "minecraft:oxidized_cut_copper",
  "minecraft:waxed_cut_copper",
  "minecraft:waxed_exposed_cut_copper",
  "minecraft:waxed_weathered_cut_copper",
  "minecraft:waxed_oxidized_cut_copper",
  "minecraft:exposed_double_cut_copper_slab",
  "minecraft:exposed_cut_copper_slab",
  "minecraft:weathered_double_cut_copper_slab",
  "minecraft:weathered_cut_copper_slab",
  "minecraft:oxidized_double_cut_copper_slab",
  "minecraft:waxed_cut_copper_slab",
  "minecraft:waxed_exposed_double_cut_copper_slab",
  "minecraft:waxed_exposed_cut_copper_slab",
  "minecraft:waxed_weathered_double_cut_copper_slab",
  "minecraft:waxed_weathered_cut_copper_slab",
  "minecraft:waxed_oxidized_double_cut_copper_slab",
  "minecraft:waxed_oxidized_cut_copper_slab",
  "minecraft:exposed_cut_copper_stairs",
  "minecraft:weathered_cut_copper_stairs",
  "minecraft:oxidized_cut_copper_stairs",
  "minecraft:waxed_cut_copper_stairs",
  "minecraft:waxed_exposed_cut_copper_stairs",
  "minecraft:exposed_cut_copper_stairs",
  "minecraft:waxed_oxidized_cut_copper_stairs",
  "minecraft:waxed_weathered_cut_copper_stairs",
];
const useOn_shovel = [
  "minecraft:grass_block",
  "minecraft:dirt",
  "minecraft:coarse_dirt",
  "minecraft:dirt_with_roots",
  "minecraft:podzol",
  "minecraft:mycelium",
];
const useOn_hoe = [
  "minecraft:grass_block",
  "minecraft:dirt",
  "minecraft:coarse_dirt",
  "minecraft:dirt_with_roots",
  "minecraft:grass_path",
];
//ломание блоков инструментом
mc.world.beforeEvents.playerBreakBlock.subscribe((event) => {
  // Check if the player is in Creative mode
  const gameMode = event.player.getGameMode();
  if (gameMode === "Creative") return; // Abort if the player is in Creative mode
  mc.system.run(() => {
    const tool = event.player
      .getComponent("equippable")
      ?.getEquipment("Mainhand");
    if (!tool?.typeId?.startsWith("tvf_randev:")) return; // Check if the tool has a specific type ID prefix
    if (
      !(
        tool.typeId.endsWith("_axe") ||
        tool.typeId.endsWith("_hoe") ||
        tool.typeId.endsWith("_shovel") ||
        tool.typeId.endsWith("_pickaxe") ||
        tool.typeId.endsWith("_sword")
      )
    )
      return;
    const level = event.itemStack
      .getComponent("minecraft:enchantable")
      ?.getEnchantment("unbreaking")?.level;
    let Damage = 1;
    function durability() {
      const durabilityComponent = tool.getComponent("minecraft:durability");
      if (
        durabilityComponent.maxDurability - durabilityComponent.damage >
        Damage
      ) {
        // Increase the tool's damage if it's not fully broken
        durabilityComponent.damage += Damage;
        event.player.getComponent("equippable").setEquipment("Mainhand", tool);
      } else {
        // If the tool is broken, replace it with air and play a break sound
        event.player.runCommand(
          "replaceitem entity @s slot.weapon.mainhand 0 air"
        );
        event.player.runCommand("playsound random.break @a[r=4] ~ ~ ~");
      }
    }
    const t = Math.floor(Math.random() * 10);
    // Unbreaking enchantment logic
    if (level === 1 && t > 8) Damage = 0;
    else if (level === 2 && t > 6) Damage = 0;
    else if (level === 3 && t > 4) Damage = 0;
    else durability();
  });
});
const COOLDOWN_TICKS = 4; // Adjust this value to change the cooldown duration
const playerCooldowns = new Map();
//использование на блоках для инструментов
world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
  const player = event.player;
  const block = event.block;
  if (!(player instanceof Player)) return;
  const item = event.itemStack;
  if (!item || !item.typeId.startsWith("tvf_randev:")) return;
  if (
    !(
      item.typeId.endsWith("_axe") ||
      item.typeId.endsWith("_hoe") ||
      item.typeId.endsWith("_shovel")
    )
  )
    return;
  if (item.typeId.endsWith("_axe")) {
    if (!useOn_axe.includes(block.typeId)) return;
  } else if (item.typeId.endsWith("_shovel")) {
    if (!useOn_shovel.includes(block.typeId)) return;
  } else if (item.typeId.endsWith("_hoe")) {
    if (!useOn_hoe.includes(block.typeId)) return;
  } else return;
  const currentTick = system.currentTick;
  // Check if the player is on cooldown
  if (playerCooldowns.has(player.id)) {
    const lastUseTick = playerCooldowns.get(player.id);
    if (currentTick - lastUseTick < COOLDOWN_TICKS) {
      return; // Exit early if the player is on cooldown
    }
  }
  // Update the player's last use tick
  playerCooldowns.set(player.id, currentTick);
  system.run(() => {
    damageTool(player, item);
  });
});

//чиню юз лопаты на чём то кроме блока травы, должно работать и без этого, но нет
mc.world.beforeEvents.playerInteractWithBlock.subscribe((event) => {
  if (
    event.itemStack &&
    event.itemStack.typeId.startsWith("tvf_randev:") &&
    event.itemStack.typeId.endsWith("_shovel")
  ) {
    if (useOn_shovel.includes(event.block.typeId)) {
      const permutatuion = BlockPermutation.resolve("minecraft:grass_path");
      system.run(() => {
        event.block.setPermutation(permutatuion);
      });
    }
  }
});

//использование итемов (не инструменты) должно быть обёрнуто в event
export function damageCustomItem(player, item) {
  if (!(player instanceof Player)) return;
  if (item.typeId == undefined) return;
  const currentTick = system.currentTick;
  if (playerCooldowns.has(player.id)) {
    const lastUseTick = playerCooldowns.get(player.id);
    if (currentTick - lastUseTick < COOLDOWN_TICKS) {
      return;
    }
  }
  // Update the player's last use tick
  playerCooldowns.set(player.id, currentTick);
  system.run(() => {
    damageTool(player, item);
  });
}
function damageTool(player, item, damage = 1) {
  if (player.getGameMode() === GameMode.Creative) {
    return; // Skip if the player is in creative mode
  }
  const durability = item.getComponent("durability");
  if (!durability) return;
  const enchantable = item.getComponent("enchantable");
  const unbreakingLevel = enchantable?.getEnchantment("unbreaking")?.level ?? 0;
  let shouldBreak = false;
  if (Math.random() * 100 <= 100 / (unbreakingLevel + 1)) {
    if (durability.damage + damage >= durability.maxDurability) {
      shouldBreak = true;
    } else {
      durability.damage += damage;
    }
    if (item.typeId.endsWith("_axe")) player.playSound("use.wood");
    if (item.typeId.endsWith("_hoe")) player.playSound("use.gravel");
    if (item.typeId.endsWith("_shovel")) player.playSound("use.grass");
  }
  const inventory = player.getComponent("inventory");
  if (!inventory) return;
  // Search for the axe in the player's inventory
  let targetSlot = -1;
  for (let i = 0; i < inventory.container.size; i++) {
    const slotItem = inventory.container.getItem(i);
    if (slotItem && slotItem.typeId === item.typeId) {
      targetSlot = i;
      break;
    }
  }
  if (targetSlot === -1) return;
  if (shouldBreak) {
    try {
      // Remove the item from the inventory
      inventory.container.setItem(targetSlot, undefined);
      // Play breaking sound
      player.runCommand("playsound random.break @a[r=5]");
    } catch (error) {
      // Handle error if needed
    }
  } else {
    try {
      inventory.container.setItem(targetSlot, item);
    } catch (error) {
      // Handle error if needed
    }
  }
}
