import { world, EquipmentSlot, GameMode } from "@minecraft/server";

// Generates a random number between min and max (non-inclusive of max)
function randomNum(min, max) {
  let num = Math.random() * max;
  if (num < min) num = min; // Prevents values below min (but can return min itself)
  return num;
}

// Subscribe to block breaking events to reduce tool durability
export function breakBlockItemDurability() {
  world.afterEvents.playerBreakBlock.subscribe((event) => {
    betaLowerMainHandDurability(event.player, event.itemStackAfterBreak);
  });
}

// Subscribe to hit events to reduce weapon/tool durability when hitting entities
export function hitEntityItemDurability() {
  world.afterEvents.entityHitEntity.subscribe((event) => {
    if (!event.damagingEntity) return;

    const typeId = event.damagingEntity.typeId;
    if (typeId !== "minecraft:player") return; // Ensure it's a player

    if (event.damagingEntity.getGameMode() === GameMode.creative) return;

    const holdingItem = event.damagingEntity.getComponent("equippable").getEquipment("Mainhand");
    if (!holdingItem) return;

    betaLowerMainHandDurability(event.damagingEntity, holdingItem);
  });
}

// Get the player's current game mode
function getGamemode(player) {
  return Object.values(GameMode).find((g) => [...world.getPlayers({ name: player.name, gameMode: g })].length);
}

// Main function to reduce durability of held item if it belongs to your custom namespace
export function betaLowerMainHandDurability(event, usedItem) {
  // Skip if the player is in Creative mode
  if (getGamemode(event) == "creative") {
    return;
  }
  if (event.getGameMode() === GameMode.creative) return;

  // Sanity checks on the used item
  if (!usedItem || !usedItem.typeId) {
    return;
  }

  // Only proceed if the item belongs to your namespace (e.g., "hb_hr:" tools)
  if (!usedItem.typeId.includes("hb_hr:")) {
    return;
  }

  const MainHand = event.getComponent("equippable").getEquipmentSlot(EquipmentSlot.Mainhand);
  const Item = MainHand.getItem();
  const Player = event;
  const durability = Item.getComponent("durability");

  if (!durability) return; // Item doesn't support durability (e.g., it's unbreakable or not a tool)

  const LowerAmount = 1;

  // If the item is enchantable, handle Unbreaking logic
  if (Item.getComponent("enchantable")) {
    const enchants = Item.getComponent("enchantable");
    let chance = 0.0;

    const unbreaking = enchants.getEnchantment("unbreaking");
    if (unbreaking) {
      const level = unbreaking.level;
      chance = 0.11 * level; // Minecraft's Unbreaking formula approximation
    }

    // Apply damage with Unbreaking probability
    if (randomNum(0, 1) > chance) {
      if (durability.damage + LowerAmount > durability.maxDurability) {
        Player.runCommand("/playsound random.break @s"); // Play break sound
        MainHand.setItem(undefined); // Remove broken item
      } else {
        durability.damage += LowerAmount; // Increase damage
        MainHand.setItem(Item); // Update item in hand
      }
    }
  } else {
    // No enchantment component present, always apply damage
    if (durability.damage + LowerAmount > durability.maxDurability) {
      Player.runCommand("/playsound random.break @s");
      MainHand.setItem(undefined);
    } else {
      durability.damage += LowerAmount;
      MainHand.setItem(Item);
    }
  }
}

// can be changed to this if june update is released with enchantable item components
export function MainHandDurabilityAxe(player, usedItem, durabilityDamage) {
  if (getGamemode(player) == "creative") {
    return;
  }

  let testFlag = false;
  let Slot;
  let SlotType;

  const holdingItem = player.getComponent("equippable").getEquipment("Mainhand");
  // // ////world.sendMessage("holdingItem.typeId: " + holdingItem.typeId);
  // // ////world.sendMessage("usedItem.typeId: " + usedItem.typeId);
  if (holdingItem) {
    if (holdingItem.typeId == usedItem.typeId) {
      // ////world.sendMessage("mainhand found item");
      testFlag = true;
      Slot = player.getComponent("equippable").getEquipmentSlot(EquipmentSlot.Mainhand);
      SlotType = "Mainhand";
    }
  }
  if (!testFlag) {
    // ////world.sendMessage("inventory found item");
    const playerContainer = player.getComponent("inventory").container;
    for (let i = 0; i < playerContainer.size; i++) {
      const item = playerContainer.getItem(i);

      if (!item) continue;
      if (item.typeId == usedItem.typeId) {
        testFlag = true;
        Slot = i;
        SlotType = "inventory";
      }
    }
  }
  if (!testFlag) return;

  let enchFlag = false;

  if (usedItem.typeId == "hb_hr:chainsaw") enchFlag = true;
  if (!enchFlag) {
    return;
  } else {
    
    let Item;
    switch (SlotType) {
      case "inventory":
        const playerContainer = player.getComponent("inventory").container;
        Item = playerContainer.getItem(Slot);
        break;
      case "Mainhand":
        const MainHand = player.getComponent("equippable").getEquipmentSlot(EquipmentSlot.Mainhand);
        Item = MainHand.getItem();
        break;

      default:
        break;
    }
    const LowerAmount = 1 + durabilityDamage;
    if (Item.getComponent("enchantable") != undefined) {
      // ////world.sendMessage("wsss");
      const durability = Item.getComponent("durability");
      if (durability != undefined) {
        // ////world.sendMessage("durabluiedy damamge: " + durability.damage);
      }
      const enchants = Item.getComponent("enchantable");
      let chance = 0.0;
      if (enchants.getEnchantment("unbreaking") != undefined) {
        const level = enchants.getEnchantment("unbreaking").level;
        chance = 0.11 * level;
      }
      if (randomNum(0, 1) > chance) {
        const durability = Item.getComponent("durability");
        if (durability != undefined) {
          if (durability.damage + LowerAmount > durability.maxDurability) {
            player.runCommand("/playsound random.break @s");
            switch (SlotType) {
              case "inventory":
                const playerContainer = player.getComponent("inventory").container;
                playerContainer.setItem(undefined);
                break;
              case "Mainhand":
                const MainHand = player.getComponent("equippable").getEquipmentSlot(EquipmentSlot.Mainhand);
                MainHand.setItem(undefined);
                break;
              default:
                break;
            }
            return;
          } else {
            durability.damage = durability.damage + LowerAmount;
            switch (SlotType) {
              case "inventory":
                const playerContainer = player.getComponent("inventory").container;
                playerContainer.setItem(Slot, Item);
                break;
              case "Mainhand":
                const MainHand = player.getComponent("equippable").getEquipmentSlot(EquipmentSlot.Mainhand);
                MainHand.setItem(Item);
                break;
              default:
                break;
            }
          }
        }
      }
    } else {
      const durability = Item.getComponent("durability");
      if (durability != undefined) {
        // ////world.sendMessage("wsss");
        // ////world.sendMessage("durabluiedy damamge: " + durability.damage);
        if (durability.damage + LowerAmount > durability.maxDurability) {
          // ////world.sendMessage("wsss");
          player.runCommand("/playsound random.break @s");
          switch (SlotType) {
            case "inventory":
              const playerContainer = player.getComponent("inventory").container;
              playerContainer.setItem(undefined);
              break;
            case "Mainhand":
              const MainHand = player.getComponent("equippable").getEquipmentSlot(EquipmentSlot.Mainhand);
              MainHand.setItem(undefined);
              break;
            default:
              break;
          }
          return;
        } else {
          // ////world.sendMessage("sdasd");
          durability.damage = durability.damage + LowerAmount;
          switch (SlotType) {
            case "inventory":
              const playerContainer = player.getComponent("inventory").container;
              playerContainer.setItem(Slot, Item);
              break;
            case "Mainhand":
              const MainHand = player.getComponent("equippable").getEquipmentSlot(EquipmentSlot.Mainhand);
              MainHand.setItem(Item);
              break;
            default:
              break;
          }
        }
      }
    }
  }
}
