import { world, EntityInventoryComponent, EntityComponentTypes, ItemStack, system, EquipmentSlot, GameMode, Player, EntityEquippableComponent, EntityProjectileComponent, ButtonState } from '@minecraft/server'
import { getRelative} from './UTILS/globalVars';
import "./weapons/weaponsInteract"
import "./armors/armorsHability"
import { dynamicWeaponsConfig } from './weapons/weapons.config';
Object.defineProperties(Player.prototype, {
    itemInHand: {
        get() {
            const equipment = this.getComponent(EntityEquippableComponent.componentId);
            const hand = equipment.getEquipment(EquipmentSlot.Mainhand);
            if (!hand) return undefined;

            return hand;
        },
        enumerable: false,
        configurable: false
    },
    itemInLeftHand: {
        get() {
            const equipment = this.getComponent(EntityEquippableComponent.componentId);
            const hand = equipment.getEquipment(EquipmentSlot.Offhand);
            if (!hand) return undefined;

            return hand;
        },
        enumerable: false,
        configurable: false
    },
    itemInHead: {
        get() {
            const equipment = this.getComponent(EntityEquippableComponent.componentId);
            const chest = equipment.getEquipment(EquipmentSlot.Head);
            if (!chest) return undefined;

            return chest;
        },
        enumerable: false,
        configurable: false
    },
    itemInChest: {
        get() {
            const equipment = this.getComponent(EntityEquippableComponent.componentId);
            const chest = equipment.getEquipment(EquipmentSlot.Chest);
            if (!chest) return undefined;

            return chest;
        },
        enumerable: false,
        configurable: false
    },
    itemInLegs: {
        get() {
            const equipment = this.getComponent(EntityEquippableComponent.componentId);
            const chest = equipment.getEquipment(EquipmentSlot.Legs);
            if (!chest) return undefined;

            return chest;
        },
        enumerable: false,
        configurable: false
    },
    itemInFeet: {
        get() {
            const equipment = this.getComponent(EntityEquippableComponent.componentId);
            const chest = equipment.getEquipment(EquipmentSlot.Feet);
            if (!chest) return undefined;

            return chest;
        },
        enumerable: false,
        configurable: false
    }
});
Object.defineProperty(Number.prototype, "checkProbability", {
    get() {
        return this === 1 || (this > 0 && Math.random() < this);
    },
    enumerable: false,
    configurable: false
});
/////////////////////////////
system.runInterval(() => {
    for (const player of world.getPlayers()) {
        const itemChestplate = player?.getComponent("minecraft:equippable")?.getEquipmentSlot(`Chest`).getItem();
        
        if (itemChestplate && itemChestplate?.typeId === "dive_hw:hacker_wings") {
            player.playAnimation(`animation.dive_hw.hacker_wings.tpp`, {blendOutTime: 0, controller: `ItemUseChestPerson`, stopExpression: `!q.is_item_name_any('slot.armor.chest', 0, 'dive_hw:hacker_wings')` });
            if (!player.isOnGround && player.hasTag("WingsRigt")) {
                player.playAnimation(`animation.dive_hw.hacker_player.fly`, {blendOutTime: 0, controller: `ItemUseFlyPerson`, stopExpression: `q.all_animations_finished` });
            }
        }
        const selectedItem = player?.itemInHand;
        if (!selectedItem) continue;
        if (selectedItem?.typeId === "dive_hw:hacker_wing" && !player.hasTag("dive_hw.stop_animations")) {
            player.playAnimation(`animation.dive_hw.hacker_wings.tpp`, { controller: `ItemUseThirdPerson`, stopExpression: `q.all_animations_finished` });
        }
        
    }
});
system.runInterval(() => {
    const players = world.getPlayers();

    players.forEach((player) => {
        const itemMainhand = player?.getComponent("minecraft:equippable")?.getEquipmentSlot(`Mainhand`).getItem();
        const itemOffhand = player?.getComponent("minecraft:equippable")?.getEquipmentSlot(`Offhand`).getItem();

        if (player?.isSneaking && (itemMainhand?.typeId === `dive_hw:hacker_shield`)) {
            player?.playAnimation(`animation.dive_hw.player.hacker_shield_block_main_hand`, { blendOutTime: 0, stopExpression: "!q.is_sneaking || v.attack_time > 0.0", controller: `shield` });
        }
        if (player?.isSneaking && (itemOffhand?.typeId === `dive_hw:hacker_shield`)) {
            player?.playAnimation(`animation.dive_hw.player.hacker_shield_block_off_hand`, { blendOutTime: 0, stopExpression: "!q.is_sneaking || v.attack_time > 0.0", controller: `shield` });
        }
        if(itemMainhand?.typeId==="dive_hw:hacker_pickaxe") {
            player.addEffect("haste", 30);
            player.addEffect("night_vision", 30);
        }
        if(!player?.isSneaking && itemMainhand?.typeId==="dive_hw:hacker_shield") {
            player.playAnimation(`animation.dive_hw.hacker_shield.tpp_hold`, { stopExpression: `q.is_sneaking || v.attack_time > 0.0 || !q.is_item_name_any('slot.weapon.mainhand', 0, 'dive_hw:hacker_shield')`, controller: "ItemUseThirdPerson" });
        }
        
    })
}, 1);
////////////////////////////
world.afterEvents.playerSpawn.subscribe(e => {
    const player = e.player
    if (e.initialSpawn) {
        if (player.hasTag('dive_hw.guidebook_given')) return
        player.dimension.spawnItem(new ItemStack('dive_hw:book_start', 1), player.location)
        player.addTag('dive_hw.guidebook_given')
    }
})
world.beforeEvents.worldInitialize.subscribe(e => {
    e.itemComponentRegistry.registerCustomComponent('dive_hw:book', {
        onUse: e => {
            const itemName = e.itemStack.typeId;
            const player = e.source;
            const mainHand = player.getComponent(EntityComponentTypes.Equippable).getEquipmentSlot(EquipmentSlot.Mainhand);
            const pages = ['dive_hw:book_start', 'dive_hw:page_0', 'dive_hw:page_1', 'dive_hw:page_2', 'dive_hw:page_3', 'dive_hw:page_4', 'dive_hw:page_5', 'dive_hw:page_6', 'dive_hw:page_7', 'dive_hw:page_8', 'dive_hw:page_9', 'dive_hw:page_10', 'dive_hw:page_12', 'dive_hw:page_13', 'dive_hw:page_14', 'dive_hw:page_15', 'dive_hw:page_16', 'dive_hw:page_17', 'dive_hw:page_18', 'dive_hw:page_19', 'dive_hw:page_20', 'dive_hw:page_21', 'dive_hw:page_22', 'dive_hw:page_23', 'dive_hw:page_24', 'dive_hw:page_25', 'dive_hw:page_26', 'dive_hw:page_27', 'dive_hw:page_28', 'dive_hw:page_29'];
            let index = pages.indexOf(itemName);

            player.playSound('item.book.page_turn');
            if (!player.isSneaking) {
                index = (index + 1) % pages.length;
            } else {
                index = (index - 1 + pages.length) % pages.length;
            }
            mainHand.setItem(new ItemStack(pages[index], 1));
        }
    })
})
world.afterEvents.itemUse.subscribe((event) => {
    const {itemStack, source} =event;
    const player = source;
    const item = itemStack.typeId;
    const inventory = player.getComponent("minecraft:inventory")?.container;
    let hasArrows = false;
    
    if(item=="dive_hw:hacker_bow" &&!player.hasTag("dive_hw.stop_animations")) {
        if (inventory) {
        for (let i = 0; i < inventory.size; i++) {
            const itemStack = inventory.getItem(i);
            if (!itemStack || !itemStack.typeId) continue;
            const arrowIds = [
            "minecraft:arrow",
            "minecraft:tipped_arrow",
            "minecraft:spectral_arrow"
            ];
            if (arrowIds.includes(itemStack.typeId)) {
            hasArrows = true;
            break;
            }
        }
    }
        if(hasArrows) player.runCommand(`playanimation @s animation.dive_hw.hacker_bow.tpp_aim none 0 "!q.is_using_item"`)
    }
    else if(item=="dive_hw:hacker_crossbow" &&!player.hasTag("dive_hw.stop_animations")) {
        if (inventory) {
        for (let i = 0; i < inventory.size; i++) {
            const itemStack = inventory.getItem(i);
            if (!itemStack || !itemStack.typeId) continue;

            const arrowIds = [
            "minecraft:arrow",
            "minecraft:tipped_arrow",
            "minecraft:spectral_arrow"
            ];

            if (arrowIds.includes(itemStack.typeId)) {
            hasArrows = true;
            break;
            }
        }
    }
        if(hasArrows) player.playAnimation("animation.dive_hw.hacker_crossbow.tpp_aim", {stopExpression: "!q.is_using_item"})
    }
})
function damageItemIfNeeded(player) {
    if (!(player instanceof Player)) return;

    const equippable = player.getComponent("minecraft:equippable");
    if (!equippable) return;

    const mainhand = equippable.getEquipmentSlot(EquipmentSlot.Mainhand);
    if (!mainhand.hasItem()) return;

    if (player.getGameMode() === GameMode.creative) return;

    const itemStack = mainhand.getItem();
    const durability = itemStack.getComponent("minecraft:durability");
    if (!durability) return;

    const enchantable = itemStack.getComponent("minecraft:enchantable");
    const unbreakingLevel = enchantable?.getEnchantment("unbreaking")?.level ?? 0;
    const damageChance = durability.getDamageChance(unbreakingLevel) / 100;

    if (Math.random() > damageChance) return;

    // Aplicar daño
    if (durability.damage + 1 >= durability.maxDurability) {
        mainhand.setItem(undefined);
        player.playSound("random.break");
    } else {
        durability.damage++;
        mainhand.setItem(itemStack);
    }
}
world.afterEvents.itemStopUse.subscribe((event)=>{
    const {itemStack, source} = event;
    const player = source;
    const item = itemStack.typeId;
    const cooldown = itemStack.getComponent("cooldown");
            if (item === "dive_hw:hacker_bow") {
                const inventory = player.getComponent("minecraft:inventory")?.container;
                let hasArrows = false;
                if (inventory) {
                for (let i = 0; i < inventory.size; i++) {
                    const itemStack = inventory.getItem(i);
                    if (!itemStack) continue;
                    const arrowIds = [
                    "minecraft:arrow",
                    "minecraft:tipped_arrow",
                    "minecraft:spectral_arrow"
                    ];
                    if (arrowIds.includes(itemStack.typeId)) {
                    hasArrows = true;
                    if (itemStack.amount === 1) {
                        inventory.setItem(i, undefined);
                    } else {
                        const newStack = itemStack.clone();
                        newStack.amount -= 1;
                        inventory.setItem(i, newStack);
                    }
                    break;
                    }
                }
                }
                if (hasArrows) {
                    damageItemIfNeeded(player);
                    player.playAnimation(`animation.dive_hw.hacker_bow.tpp_use`, {
                        controller: `ItemUseThirdPerson`,
                        stopExpression: `query.all_animations_finished`
                    });
                    player.addTag("dive_hw.stop_animations");
                    if (player.hasTag("dive_hw.stop_animations")) {
                        system.runTimeout(() => {
                            world.playSound(`random.bow`, {
                                x: player.location.x,
                                y: player.location.y,
                                z: player.location.z
                            });
                            const { hacker_bow: { secondsToShoot, secondsToRemoveProjectile } } = dynamicWeaponsConfig;
                            system.runTimeout(() => {
                                const rel = getRelative(source, source.getViewDirection(), [1.3, source.isSneaking ? 1.3 : 1.6, 0]);
                                const rot = source.getRotation();
                                const pro = source.dimension.spawnEntity("dive_hw:hacker_bow_projectile", rel);
                                pro.setProperty("dive_hw:rotation_x", rot.x);
                                pro.setProperty("dive_hw:rotation_y", rot.y);
                                pro.setProperty("dive_hw:special", source.isSneaking);
                                const proyectil = pro.getComponent(EntityProjectileComponent.componentId);
                                const vw = source.getViewDirection();
                                proyectil.shoot({
                                    x: (vw.x * 2),
                                    y: vw.y,
                                    z: (vw.z * 2)
                                });
                                proyectil.owner = source;
                                system.runTimeout(() => {
                                    try {
                                    pro.remove();
                                    } catch (error) { }
                                }, secondsToRemoveProjectile * 20);
                            }, secondsToShoot * 20);    
                            system.runTimeout(() => {
                                player.removeTag("dive_hw.stop_animations");
                                player.removeTag("animation_bow_aim");
                            }, 18);
                        }, 4);
                    }
            }
        }
        else if(item==="dive_hw:hacker_crossbow") {
            const inventory = player.getComponent("minecraft:inventory")?.container;
                let hasArrows = false;
                if (inventory) {
                for (let i = 0; i < inventory.size; i++) {
                    const itemStack = inventory.getItem(i);
                    if (!itemStack) continue;
                    const arrowIds = [
                    "minecraft:arrow",
                    "minecraft:tipped_arrow",
                    "minecraft:spectral_arrow"
                    ];
                    if (arrowIds.includes(itemStack.typeId)) {
                    hasArrows = true;
                    if (itemStack.amount === 1) {
                        inventory.setItem(i, undefined);
                    } else {
                        const newStack = itemStack.clone();
                        newStack.amount -= 1;
                        inventory.setItem(i, newStack);
                    }
                    break;
                    }
                }
                }
                if(hasArrows) {
                    damageItemIfNeeded(player);
                    player.playAnimation(`animation.dive_hw.hacker_crossbow.tpp_use`, { controller: `ItemUseThirdPerson`, stopExpression: `q.all_animations_finished` });
                player.addTag("dive_hw.stop_animations");
                if (player.hasTag("dive_hw.stop_animations")) {
                    system.runTimeout(() => {
                    world.playSound(`crossbow.shoot`, { x: player.location.x, y: player.location.y, z: player.location.z });
                    system.runTimeout(() => {
                        player.removeTag("dive_hw.stop_animations");
                    }, 18
                    );
                    }, 4);
                };
                const { hacker_crossbow: { secondsToShoot, secondsToRemoveProjectile } } = dynamicWeaponsConfig;
                system.runTimeout(() => {
                const rel = getRelative(source, source.getViewDirection(), [1.3, source.isSneaking ? 1.3 : 1.6, 0]);
                const rot = source.getRotation();
                const pro = source.dimension.spawnEntity("dive_hw:hacker_crossbow_projectile", rel);
                pro.setProperty("dive_hw:rotation_x", rot.x);
                pro.setProperty("dive_hw:rotation_y", rot.y);
                if(source.isSneaking) {pro.setProperty("dive_hw:special", source.isSneaking);} else pro.setProperty("dive_hw:special", !source.isSneaking);
                const proyectil = pro.getComponent(EntityProjectileComponent.componentId);
                const vw = source.getViewDirection();
                proyectil.shoot({
                    x: (vw.x * 2),
                    y: vw.y,
                    z: (vw.z * 2)
                });
                proyectil.owner = source;
                system.runTimeout(() => {
                    try {
                    pro.remove();
                    } catch (error) { }
                }, secondsToRemoveProjectile * 20);
                }, secondsToShoot * 20);
                    }
                
        }
})
const jumpTracker = new Map(); 
world.afterEvents.playerButtonInput.subscribe(({ player, button, newButtonState }) => {
    if (newButtonState !== "Pressed" || button !== "Jump") return;
    const playerId = player.id;
    const currentTick = system.currentTick; 
    const lastJumpTick = jumpTracker.get(playerId) || 0;
    if (currentTick - lastJumpTick < 10) {
        player.addTag("WingsRigt");
    }
    jumpTracker.set(playerId, currentTick);

    
});

world.afterEvents.playerButtonInput.subscribe(({ player, button, newButtonState }) => {
    if (button === "Jump") {
        if (newButtonState === "Pressed") {
        player.addTag("jetpack_rider_hacker");
        } else if (newButtonState === "Released") {
        player.removeTag("jetpack_rider_hacker");
        }
    }
    if (button === "Sneak") {
        if (newButtonState === "Pressed") {
        player.addTag("jetpack_descend_hacker");
        } else if (newButtonState === "Released") {
        player.removeTag("jetpack_descend_hacker");
        }
    }
});