import { system, EntityComponentTypes, world, Entity } from "@minecraft/server";


//geo pet special ability
system.afterEvents.scriptEventReceive.subscribe((event) => {
    const pet = event.sourceEntity;
    if (event.id != "oct_eg:geo_pet") return;
    switch (event.message) {
        //runs the slam attack
        case "slam_attack":
            pet.playAnimation("anim.pet.slam_attack");
            addCooldown(pet);
            pet?.triggerEvent("oct_eg:slam_attack.cooldown")
            pet?.clearVelocity;
            system.runTimeout(() => {
                if (pet != null)
                    slam_attack(pet);
            }, 0.83 * 20);
            break;

        //checks if it is still on cooldown
        case "cooldown_check":
            if (!isOnCooldown(pet))
                pet.triggerEvent("oct_eg:slam_attack.ready")
            break;
        default:
            break;
    }
});

/**
 * 
 * @param {Entity} pet 
 */
function slam_attack(pet) {
    const owner = pet.getComponent(EntityComponentTypes.Tameable).tamedToPlayer;

    const rayHit = pet.dimension.getBlockFromRay(pet.location, { x: 0, y: -1, z: 0 }, {
        maxDistance: 3,
        includeLiquidBlocks: true,
        includePassableBlocks: false,
    });

    let ground = pet.location;
    if (rayHit?.block) {
        ground = rayHit.block.above();
    }

    pet.dimension.spawnEntity("oct_eg:ground_spikes", ground);

    for (const element of pet.dimension.getEntities({ location: ground, maxDistance: 5, excludeTypes: ["minecraft:xp_orb", "minecraft:item"] })
        .filter(entities => entities != pet).filter(entities => entities != owner)) {

        const tameable = element.getComponent("minecraft:tameable");
        const ownerProp = element.getDynamicProperty("oct_eg:owner_id");
        const petOwner = pet.getComponent("minecraft:tameable")?.tamedToPlayer;
        const owner = tameable ? tameable?.tamedToPlayer : ownerProp !== undefined ? world.getEntity(ownerProp) : null;

        // Prevent damage to pets that have the same owner as this pet
        if(petOwner && owner && petOwner.id == owner.id)continue;

        element.applyKnockback(0, 0, 0, 1.5);
    }
    pet.dimension.spawnParticle("oct_eg:geo_pet.slam_attack", ground);
}

/**
 * @param {Entity} pet
 */
function addCooldown(pet) {
    const currentTime = system.currentTick;
    const cooldown = 10 * 20;
    pet.setDynamicProperty("oct_eg:cooldown", currentTime + cooldown);
}

/**
 * @param {Entity} pet
 */
function isOnCooldown(pet) {
    return pet.getDynamicProperty("oct_eg:cooldown") > system.currentTick;
}