import { world, ItemStack, GameMode } from '@minecraft/server';

// This array defines the tool items that will lose durability.
const toolTypeIds = [
    'old_nether:ruby_axe',
    'old_nether:ruby_pickaxe',
    'old_nether:ruby_hoe',
    'old_nether:ruby_axe',
    'old_nether:ruby_shovel',
    'old_nether:taaffeite_axe',
    'old_nether:taaffeite_pickaxe',
    'old_nether:taaffeite_hoe',
    'old_nether:taaffeite_axe',
    'old_nether:taaffeite_shovel',
    'old_nether:taaffeite_mace',
    'old_nether:gilded_axe',
    'old_nether:gilded_pickaxe',
    'old_nether:gilded_hoe',
    'old_nether:gilded_axe',
    'old_nether:gilded_shovel',
    'old_nether:gilded_battle_axe',
    'old_nether:ruby_battle_axe',
    'old_nether:wooden_battle_axe',
    'old_nether:stone_battle_axe',
    'old_nether:iron_battle_axe',
    'old_nether:golden_battle_axe',
    'old_nether:diamond_battle_axe',
    'old_nether:netherite_battle_axe'

];

// This array defines the weapon items that will lose durability.
const weaponTypeIds = [
    `old_nether:ruby_sword`,
    `old_nether:gilded_sword`,
    `old_nether:taaffeite_sword`
];

// This array defines the vanilla items that will lose durability when mining an addon block.
const vanillaToolIds = [
    'minecraft:wooden_sword',
    'minecraft:wooden_shovel',
    'minecraft:wooden_pickaxe',
    'minecraft:wooden_axe',
    'minecraft:wooden_hoe',
    'minecraft:stone_sword',
    'minecraft:stone_shovel',
    'minecraft:stone_pickaxe',
    'minecraft:stone_axe',
    'minecraft:stone_hoe',
    'minecraft:iron_sword',
    'minecraft:iron_shovel',
    'minecraft:iron_pickaxe',
    'minecraft:iron_axe',
    'minecraft:iron_hoe',
    'minecraft:golden_sword',
    'minecraft:golden_shovel',
    'minecraft:golden_pickaxe',
    'minecraft:golden_axe',
    'minecraft:golden_hoe',
    'minecraft:diamond_sword',
    'minecraft:diamond_shovel',
    'minecraft:diamond_pickaxe',
    'minecraft:diamond_axe',
    'minecraft:diamond_hoe',
    'minecraft:netherite_sword',
    'minecraft:netherite_shovel',
    'minecraft:netherite_pickaxe',
    'minecraft:netherite_axe',
    'minecraft:netherite_hoe'
];

world.afterEvents.playerBreakBlock.subscribe(evd => {
    const { player, brokenBlockPermutation: block, itemStackBeforeBreak: itemUsed } = evd;

    // This returns if itemUsed is undefined or if the player is in Creative.
    if (!itemUsed || player.matches({ gameMode: GameMode.creative })) return;

    if (toolTypeIds.includes(itemUsed.typeId) || weaponTypeIds.includes(itemUsed.typeId)) {
        // This retrieves the player's equippable component.
        const playerEquippableComp = player.getComponent("equippable");

        // This returns if playerEquippableComp is undefined.
        if (!playerEquippableComp) return;

        // This retrieves the enchantable component of the item.
        const itemEnchantmentComp = itemUsed.getComponent("minecraft:enchantable");
        const unbreakingLevel = itemEnchantmentComp?.getEnchantment("unbreaking")?.level ?? 0;

        // Calculates the chance of an item breaking based on its unbreaking level. This is the vanilla unbreaking formula.
        const breakChance = 100 / (unbreakingLevel + 1);
        // Generates a random chance value between 0 and 100.
        const randomizeChance = Math.random() * 100;

        // This returns if breakChance is less than randomizeChance.
        if (breakChance < randomizeChance) return;

        // This retrieves the durability component of the item.
        const itemUsedDurabilityComp = itemUsed.getComponent("durability");

        // This returns if itemUsedDurabilityComp is undefined.
        if (!itemUsedDurabilityComp) return;

        let durabilityModifier = 0;
        if (toolTypeIds.includes(itemUsed.typeId)) {
            // If the item is a tool, then it will set the durability modifier to 1.
            durabilityModifier = 1;
        } else {
            // If the item is a weapon, then it will set the durability modifier to 2.
            durabilityModifier = 2;
        }

        // This will set the new durability value.
        itemUsedDurabilityComp.damage += durabilityModifier;

        // Declares and checks if the item is out of durability
        const maxDurability = itemUsedDurabilityComp.maxDurability
        const currentDamage = itemUsedDurabilityComp.damage
        if (currentDamage >= maxDurability) {

            // If the item is out of durability, plays the item breaking sound and removes the item
            player.playSound('random.break', { pitch: 1, location: player.location, volume: 1 })
            playerEquippableComp.setEquipment("Mainhand", new ItemStack('minecraft:air', 1));
        }
        else if (currentDamage < maxDurability) {

            // This sets the item in the player's selected slot.
            playerEquippableComp.setEquipment("Mainhand", itemUsed);
        }
    }
    else if (block.matches('old_nether:cooled_magma') || block.matches('old_nether:volcanic_rock') || block.matches('old_nether:ancient_quartz_block') || block.matches('old_nether:silica') || block.matches('old_nether:anomalous_door') || block.matches('old_nether:anomalous_fence') || block.matches('old_nether:anomalous_fence_gate') || block.matches('old_nether:anomalous_fungus') || block.matches('old_nether:anomalous_log') || block.matches('old_nether:anomalous_hyphae') || block.matches('old_nether:anomalous_hyphae_stripped') || block.matches('old_nether:anomalous_log_stripped') || block.matches('old_nether:anomalous_nylium') || block.matches('old_nether:anomalous_planks') || block.matches('old_nether:anomalous_roots') || block.matches('old_nether:anomalous_slab') || block.matches('old_nether:anomalous_trapdoor') || block.matches('old_nether:anomalous_vine') || block.matches('old_nether:anomalous_vine_head') || block.matches('old_nether:anomalous_wart_block') || block.matches('old_nether:blackstone_gold_ore') || block.matches('old_nether:blaze_block') || block.matches('old_nether:bloodstone') || block.matches('old_nether:bloodstone_gold_ore') || block.matches('old_nether:bloodstone_golden_ore') || block.matches('old_nether:bloodstone_silica_ore') || block.matches('old_nether:bloodstone_ruby_ore') || block.matches('old_nether:chiselled_gold_block') || block.matches('old_nether:compressed_gold_block') || block.matches('old_nether:dark_nether_wart_block') || block.matches('old_nether:deepslate_fragment_gold_ore') || block.matches('old_nether:gilded_block') || block.matches('old_nether:gilded_netherrack') || block.matches('old_nether:glowing_gold_block') || block.matches('old_nether:glowing_obsidian') || block.matches('old_nether:gold_fragment_ore') || block.matches('old_nether:head_pigman') || block.matches('old_nether:head_pigman_brute') || block.matches('old_nether:head_withered_zombie_pigman') || block.matches('old_nether:head_withered_zombie_pigman_brute') || block.matches('old_nether:head_zombie_pigman') || block.matches('old_nether:head_zombie_pigman_brute') || block.matches('old_nether:iron_reactor_core_structure') || block.matches('old_nether:luminous_stone') || block.matches('old_nether:nether_reactor_core_structure') || block.matches('old_nether:nether_ruby_ore') || block.matches('old_nether:netherrack_gold_ore') || block.matches('old_nether:old_chiseled_nether_bricks') || block.matches('old_nether:old_chiseled_quartz_block') || block.matches('old_nether:old_crying_obsidian') || block.matches('old_nether:old_nether_bricks') || block.matches('old_nether:old_obsidian') || block.matches('old_nether:old_quartz_pillar') || block.matches('old_nether:old_respawn_anchor') || block.matches('old_nether:old_respawn_anchor2') || block.matches('old_nether:pebble') || block.matches('old_nether:ash_block') || block.matches('old_nether:reactor1') || block.matches('old_nether:reactor1_obsidian') || block.matches('old_nether:reactor1_obsidian_ruby') || block.matches('old_nether:reactor1_ruby') || block.matches('old_nether:reactor2') || block.matches('old_nether:reactor1_inferno') || block.matches('old_nether:reactor2_inferno') || block.matches('old_nether:reactor2_obsidian') || block.matches('old_nether:reactor2_obsidian_ruby') || block.matches('old_nether:reactor2_ruby') || block.matches('old_nether:reactor3') || block.matches('old_nether:reactor3_inferno') || block.matches('old_nether:reactor3_obsidian') || block.matches('old_nether:reactor3_obsidian_ruby') || block.matches('old_nether:reactor3_ruby') || block.matches('old_nether:reactor4_inferno') || block.matches('old_nether:reactor5_inferno') || block.matches('old_nether:reactor6_inferno') || block.matches('old_nether:ruby_block') || block.matches('old_nether:ruby_iron_reactor_core_structure') || block.matches('old_nether:ruby_jukebox') || block.matches('old_nether:ruby_jukebox_hopelessness') || block.matches('old_nether:ruby_jukebox_pigman_invasion') || block.matches('old_nether:ruby_ore') || block.matches('old_nether:ruby_reactor_core_structure') || block.matches('old_nether:sculk_door') || block.matches('old_nether:sculk_fence') || block.matches('old_nether:sculk_fence_gate') || block.matches('old_nether:sculk_log') || block.matches('old_nether:sculk_hyphae') || block.matches('old_nether:sculk_hyphae_stripped') || block.matches('old_nether:sculk_log_stripped') || block.matches('old_nether:sculk_planks') || block.matches('old_nether:sculk_slab') || block.matches('old_nether:sculk_trapdoor') || block.matches('old_nether:skull_wither_skeleton_brute') || block.matches('old_nether:skull_wither_skeleton_brute_invulnerable') || block.matches('old_nether:skull_withered_zombie_pigman') || block.matches('old_nether:skull_withered_zombie_pigman_brute') || block.matches('old_nether:skull_zombie_pigman') || block.matches('old_nether:skull_zombie_pigman_brute') || block.matches('old_nether:soul_door') || block.matches('old_nether:soul_fence') || block.matches('old_nether:soul_fence_gate') || block.matches('old_nether:soul_fungus') || block.matches('old_nether:soul_glowstone') || block.matches('old_nether:soul_log') || block.matches('old_nether:soul_hyphae') || block.matches('old_nether:soul_hyphae_stripped') || block.matches('old_nether:soul_log_stripped') || block.matches('old_nether:soul_nylium') || block.matches('old_nether:soul_planks') || block.matches('old_nether:soul_pumpkin') || block.matches('old_nether:soul_roots') || block.matches('old_nether:soul_rose') || block.matches('old_nether:soul_shroomlight') || block.matches('old_nether:soul_slab') || block.matches('old_nether:soul_trapdoor') || block.matches('old_nether:soul_wart_block') || block.matches('old_nether:spiritual_gravel') || block.matches('old_nether:spectral_sand') || block.matches('old_nether:stray_bone_block') || block.matches('old_nether:taaffeite_block') || block.matches('old_nether:taaffeite_ore') || block.matches('old_nether:trypophobic_nylium') || block.matches('old_nether:trypophobic_wart_block') || block.matches('old_nether:volcano_block') || block.matches('old_nether:warped_nether_bricks') || block.matches('old_nether:wart_door') || block.matches('old_nether:wart_fence') || block.matches('old_nether:wart_fence_gate') || block.matches('old_nether:wart_fungus') || block.matches('old_nether:wart_log') || block.matches('old_nether:wart_hyphae') || block.matches('old_nether:wart_hyphae_stripped') || block.matches('old_nether:wart_log_stripped') || block.matches('old_nether:wart_nylium') || block.matches('old_nether:wart_planks') || block.matches('old_nether:wart_roots') || block.matches('old_nether:wart_slab') || block.matches('old_nether:wart_trapdoor') || block.matches('old_nether:wart_vine') || block.matches('old_nether:wart_vine_head') || block.matches('old_nether:ash_door') || block.matches('old_nether:ash_fence') || block.matches('old_nether:ash_fence_gate') || block.matches('old_nether:ash_fungus') || block.matches('old_nether:ash_log') || block.matches('old_nether:ash_hyphae') || block.matches('old_nether:ash_hyphae_stripped') || block.matches('old_nether:ash_log_stripped') || block.matches('old_nether:ash_planks') || block.matches('old_nether:ash_roots') || block.matches('old_nether:ash_shroomlight') || block.matches('old_nether:ash_slab') || block.matches('old_nether:ash_trapdoor') || block.matches('old_nether:wither_bone_block') || block.matches('old_nether:withered_beacon_inactive') || block.matches('old_nether:withered_beacon_negative') || block.matches('old_nether:withered_beacon_positive') || block.matches('old_nether:withered_door') || block.matches('old_nether:withered_fence') || block.matches('old_nether:withered_fence_gate') || block.matches('old_nether:withered_fungus') || block.matches('old_nether:withered_glowstone') || block.matches('old_nether:withered_log') || block.matches('old_nether:withered_hyphae') || block.matches('old_nether:withered_hyphae_stripped') || block.matches('old_nether:withered_log_stripped') || block.matches('old_nether:withered_nether_bricks') || block.matches('old_nether:withered_nether_bricks_fence') || block.matches('old_nether:withered_nylium') || block.matches('old_nether:withered_planks') || block.matches('old_nether:withered_roots') || block.matches('old_nether:withered_shroomlight') || block.matches('old_nether:withered_slab') || block.matches('old_nether:withered_trapdoor') || block.matches('old_nether:withered_vine') || block.matches('old_nether:withered_vine_head') || block.matches('old_nether:withered_wart_block')) {
        if (vanillaToolIds.includes(itemUsed.typeId)) {

            // This retrieves the player's equippable component.
            const playerEquippableComp = player.getComponent("equippable");

            // This returns if playerEquippableComp is undefined.
            if (!playerEquippableComp) return;

            // This retrieves the enchantable component of the item.
            const itemEnchantmentComp = itemUsed.getComponent("minecraft:enchantable");
            const unbreakingLevel = itemEnchantmentComp?.getEnchantment("unbreaking")?.level ?? 0;

            // Calculates the chance of an item breaking based on its unbreaking level. This is the vanilla unbreaking formula.
            const breakChance = 100 / (unbreakingLevel + 1);
            // Generates a random chance value between 0 and 100.
            const randomizeChance = Math.random() * 100;

            // This returns if breakChance is less than randomizeChance.
            if (breakChance < randomizeChance) return;

            // This retrieves the durability component of the item.
            const itemUsedDurabilityComp = itemUsed.getComponent("durability");

            // This returns if itemUsedDurabilityComp is undefined.
            if (!itemUsedDurabilityComp) return;

            // This will set the new durability value.
            itemUsedDurabilityComp.damage += 1;

            // Declares and checks if the item is out of durability
            const maxDurability = itemUsedDurabilityComp.maxDurability
            const currentDamage = itemUsedDurabilityComp.damage
            if (currentDamage >= maxDurability) {

                // If the item is out of durability, plays the item breaking sound and removes the item
                player.playSound('random.break', { pitch: 1, location: player.location, volume: 1 })
                playerEquippableComp.setEquipment("Mainhand", new ItemStack('minecraft:air', 1));
            }
            else if (currentDamage < maxDurability) {

                // This sets the item in the player's selected slot.
                playerEquippableComp.setEquipment("Mainhand", itemUsed);
            }
        }
    }
})