import {EquipmentSlot, system, world} from "@minecraft/server";
import {getScore, open_menu} from "menu";
import "inventory";
import "main2";
import {createJungleGolemSmash, createJungleGolemSmash2} from "./config/presets/attacks/shockwave";
import {breakLeaves} from "./armor_helpers";
import {getItemInSlot} from "./modules/helper/utils";

function get_integer(str) {
    return parseInt(str.replace(/\D/g, ""));
}

export function setScore(entity, scoreboard, value) {
    try {
        entity.runCommand(`scoreboard objectives add ${scoreboard} dummy`);
        entity.runCommand(`scoreboard players set @s ${scoreboard} ${value}`);
    } catch (e) {
    }
}

// Subscribe to function events
system.afterEvents.scriptEventReceive.subscribe((event) => {
    const {id, message, sourceEntity, sourceType} = event;
    if (id === "cubed:delay") {
        let delay = parseInt(message.split('/')[0], 10);
        let command = message.split('/').slice(1).join('/');

        system.runTimeout(() => {
            sourceEntity.runCommand(command);
        }, delay);
    }
    if (id === "cubed:repeat") {
        let data = message.split('/')[0];
        let command = message.split('/').slice(1).join('/');

        let repeat = get_integer(data.split(',')[0]);
        let delay = get_integer(data.split(',')[1]);

        for (let i = 0; i < repeat; i++) {
            system.runTimeout(() => {
                sourceEntity.runCommand(command);
            }, i * delay);
        }
    }

    if (id === "cubed:open_menu") {
        open_menu(sourceEntity)
    }

    if (id === "cubed:break_leaves") {
        breakLeaves(sourceEntity)
    }

    if (id === "cubed:set_on_fire") {
        sourceEntity.setOnFire(5);
    }

    if (id === "cubed:set_cooldown") {
        const item = getItemInSlot(sourceEntity, EquipmentSlot.Mainhand);
        const category = item.getComponent('cooldown').cooldownCategory;
        sourceEntity.startItemCooldown(category, parseFloat(message));
    }

    if (id === "cubed:fly") {
        sourceEntity.triggerEvent("cubed:no_knockback_resistance");
        system.runTimeout(() => {
            sourceEntity.applyKnockback(sourceEntity.getViewDirection().x, sourceEntity.getViewDirection().z, 0, 2.2);
            sourceEntity.triggerEvent("cubed:knockback_resistance");
        }, 1);
    }

    if (id === "cubed:knock_up") {
        sourceEntity.triggerEvent("cubed:no_knockback_resistance");
        system.runTimeout(() => {
            // CHeck if goat or dodo
            if (sourceEntity.typeId.includes("goat")) {
                sourceEntity.applyKnockback(sourceEntity.getViewDirection().x, sourceEntity.getViewDirection().z, 0, 1.6);
                sourceEntity.triggerEvent("cubed:knockback_resistance");
            } else {
                sourceEntity.applyKnockback(sourceEntity.getViewDirection().x, sourceEntity.getViewDirection().z, 0, 1);
                sourceEntity.triggerEvent("cubed:knockback_resistance");
            }

        }, 1);
    }

    if (id === "cubed:radius_knockback") {
        createJungleGolemSmash(sourceEntity)
        sourceEntity.runCommand("summon cubed:instant_knockback")
    }
    if (id === "cubed:radius_knockback2") {
        createJungleGolemSmash2(sourceEntity)
        sourceEntity.runCommand("summon cubed:launcher ~~~ ~~ cubed:player_launch")
    }
});

world.afterEvents.entityHurt.subscribe((event) => {
    let damager = event.damageSource.damagingEntity;
    if (damager === undefined)
        return;
    let damager_id = damager.typeId.replace('minecraft:', '');
    if (damager_id === "player") {
        event.hurtEntity.runCommand(`function weapon/hit`);
    }
});


world.afterEvents.entityHitEntity.subscribe((event) => {
    const damager = event.damagingEntity;

    damager.runCommand(`tag @e remove damager`);
    damager.runCommand(`tag @s add damager`);

    event.hitEntity.runCommand(`tag @e remove hit`);
    event.hitEntity.runCommand(`tag @s add hit`);

    // Dino hits a player
    const name = damager.typeId.replace('cubed:', '');
    damager.runCommand(`execute as @s[family=dino] run execute as @e[tag=hit] at @s run function dinos/player_hit/${name}`);
})

export function getClosestEntity(sourceEntity, identifier) {
    return sourceEntity.dimension.getEntities({
        type: identifier,
        closest: 1,
        location: sourceEntity.location,
        maxDistance: 10
    })[0];
}

world.afterEvents.itemUse.subscribe(eventData => {
    const item = eventData.itemStack
    const player = eventData.source
    const type_id = item.typeId;

    if (type_id.includes('cubed:')) {
        if (type_id.includes('book')) {
            player.runCommand(`execute if entity @s[scores={book_cd=0}] run function book/previous_page`);
            player.runCommand(`scoreboard players set @s[scores={book_cd=0}] book_cd 10`);
        }
    }
})

system.runInterval(() => {
    for (const player of world.getPlayers()) {
        try {
            const item = getItemInSlot(player, EquipmentSlot.Mainhand);
            const cooldown = item?.getComponent("minecraft:cooldown").getCooldownTicksRemaining(player);
            setScore(player, "item_cooldown", cooldown);
        } catch (e) {

        }
    }
}, 1);

system.runInterval(() => {
    let dimensions = ["overworld", "nether", "the_end"]
    for (const dimension of dimensions) {
        const tameDinos = world.getDimension(dimension).getEntities({
            families: ["tame"]
        });

        for (const tameDino of tameDinos) {
            if (!tameDino.hasTag("has_rider")) {
                const activityScore = getScore(tameDino, "activity");
                const heartEntity = getClosestEntity(tameDino, "cubed:heart");
                heartEntity.setProperty("cubed:texture_index", activityScore);
            }
        }
    }
}, 1);