import * as mc from "@minecraft/server";
import { NAMESPACE } from "../anvilConstants";
import { dinoList, morphAttackId, morphGrabId, morphRoarId, morphSleepId, morphSprintId, morphChargeId, morphSwitch_VariantId } from "../constants";
const morphActions = [morphAttackId, morphGrabId, morphRoarId, morphSprintId, morphChargeId, morphSleepId, morphSwitch_VariantId];
function morphAttack(player, morph, morphName) {
    const attackDamage = dinoList[morphName].damage;
    const attackAnimations = [
        dinoList[morphName].attack_animation,
        dinoList[morphName].attack_animation2,
        dinoList[morphName].attack_animation3,
    ].filter(animation => animation);
    const attackDelay = dinoList[morphName].attack_delay;
    const attackRange = dinoList[morphName].attack_range;
    if (attackAnimations.length > 0 && attackDelay && attackDamage) {
        const randomAnimation = attackAnimations[Math.floor(Math.random() * attackAnimations.length)];
        morph.playAnimation(randomAnimation, { blendOutTime: 0.1 });
        mc.system.runTimeout(() => {
            if (morph.isValid()) {
                player.getEntitiesFromViewDirection({ maxDistance: attackRange }).forEach((entity) => {
                    if (!entity.entity.hasTag(`${NAMESPACE}.owner.${player.id.toString()}`)) {
                        entity.entity.applyDamage(attackDamage, { cause: mc.EntityDamageCause.entityAttack, damagingEntity: player });
                    }
                });
            }
        }, attackDelay * 20);
    }
}
function morphGrab(player, morph) {
    const GrabAttack = morph.getProperty(`${NAMESPACE}:grab_attack`) === true;
    if (GrabAttack === true) {
        morph.triggerEvent("end_grab");
    }
    else if (GrabAttack === false) {
        morph.triggerEvent("grab_attack");
        player.runCommand(`titleraw @s actionbar ${JSON.stringify({ rawtext: [{ translate: `${NAMESPACE}.grab_attack` }] })}`);
    }
}
function morphRoar(player, morph) {
    morph.triggerEvent("is_roaring");
    mc.system.runTimeout(() => {
        if (morph.isValid()) {
            morph.dimension.getEntities({ location: morph.location, maxDistance: 10 }).forEach((entity) => {
                if (!entity.hasTag(`${NAMESPACE}.owner.${player.id.toString()}`)) {
                    const vector = {
                        x: entity.location.x - morph.location.x,
                        y: entity.location.y - morph.location.y,
                        z: entity.location.z - morph.location.z,
                    };
                    try {
                        entity.applyKnockback(vector.x, vector.z, 8, 0.8);
                    }
                    catch (e) { }
                }
            });
        }
    }, 20);
}
function morphSprint(morph) {
    morph.addEffect("speed", 15 * 20, { amplifier: 2, showParticles: false });
}
function morphCharge(player, morph) {
    morph.addEffect("speed", 15 * 20, {
        amplifier: 4, showParticles: false
    });
    player.runCommand(`titleraw @s actionbar ${JSON.stringify({ rawtext: [{ translate: `${NAMESPACE}.charge` }] })}`);
    player.runCommand(`/playsound ${NAMESPACE}:dino_charge @a[r=16]`);
}
function morphSleep(player, morph) {
    const isSleeping = morph.getProperty(`${NAMESPACE}:sleep_state`) === "sleeping";
    if (isSleeping === true) {
        morph.setProperty(`${NAMESPACE}:sleep_state`, "awake");
        morph.removeEffect("slowness");
        morph.removeEffect("regeneration");
        player.runCommand("/inputpermission set @s camera enabled");
        player.runCommand("/inputpermission set @s movement enabled");
    }
    else if (isSleeping === false) {
        morph.setProperty(`${NAMESPACE}:sleep_state`, "sleeping");
        morph.addEffect("slowness", 9999999, { amplifier: 255, showParticles: false });
        morph.addEffect("regeneration", 9999999, { amplifier: 3, showParticles: false });
        player.runCommand("/inputpermission set @s camera disabled");
        player.runCommand("/inputpermission set @s movement disabled");
    }
}
function morphSwitch_Variant(player, morph) {
    morph.triggerEvent("switch_variant");
    player.runCommand(`/playsound ${NAMESPACE}:dino_switch_variant @s`);
}
export function morphActionManager(eventData) {
    const itemStack = eventData.itemStack;
    if (morphActions.includes(itemStack.typeId)) {
        const player = eventData.source;
        const morphName = player.getDynamicProperty(`${NAMESPACE}:morph_name`);
        const morph = player.dimension.getEntities({
            location: player.location,
            closest: 1,
            tags: [`${NAMESPACE}.owner.${player.id.toString()}`],
            excludeTypes: ["minecraft:player"],
        })[0];
        const isSleeping = morph.getProperty(`${NAMESPACE}:sleep_state`) === "sleeping";
        switch (itemStack.typeId) {
            case `${NAMESPACE}:morph_attack`:
                if (!isSleeping) {
                    morphAttack(player, morph, morphName);
                }
                break;
            case `${NAMESPACE}:morph_grab`:
                if (!isSleeping) {
                    morphGrab(player, morph);
                }
                break;
            case `${NAMESPACE}:morph_roar`:
                if (!isSleeping) {
                    morphRoar(player, morph);
                }
                break;
            case `${NAMESPACE}:morph_sprint`:
                if (!isSleeping) {
                    morphSprint(morph);
                }
                break;
            case `${NAMESPACE}:morph_charge`:
                if (!isSleeping) {
                    morphCharge(player, morph)
                }
                break;
            case `${NAMESPACE}:morph_sleep`:
                morphSleep(player, morph);
                break;
            case `${NAMESPACE}:morph_switch_variant`:
                morphSwitch_Variant(player, morph);
                break;
        }
    }
}
