
import * as mc from "@minecraft/server";
import * as lib from "../lib";
import { difficultyDamageController } from './index'

let damageMultiplier = 7;
const delayVelocityMultiplier = 0.5;
const entityType = {
    typeId: "ld_eb:earth_elemental",
    skills: [
        { delay: delayVelocityMultiplier*2, damage: damageMultiplier * 1, id: 0, chance: 3, anim: "attack" },
        { delay: delayVelocityMultiplier*2, damage: damageMultiplier * 1, id: 1, chance: 3, anim: "seismic_slam" },
        { delay: delayVelocityMultiplier*3, damagePS: damageMultiplier * 1, id: 2, chance: 3, anim: "vine_snare" },
        { delay: delayVelocityMultiplier*3, damage: damageMultiplier * 1, id: 3, chance: 20, anim: "boulder_crush" }
    ]
};

mc.Entity.prototype.ld_eb_inAttack = false;

mc.system.afterEvents.scriptEventReceive.subscribe(async data => {
    const entity = data.sourceEntity;
    const id = data.id;
    if (entity.typeId !== entityType.typeId || entity.ld_eb_inAttack) return;

    entity.triggerEvent("ld_eb:cancel_rotation");

    const index = parseInt(id.split("_").pop());
    if (skills[index]) skills[index].start(entity);

    entity.setProperty("ld_eb:proximo_ataque", lib.randomWithChances(entityType.skills));
    entity.triggerEvent("ld_eb:skill_" + entity.getProperty("ld_eb:proximo_ataque") + "_intention");
});

const skills = [
    {
        index: 0,
        async start(entity) {
            entity.ld_eb_inAttack = true;
            entity.addEffect("slowness", 9999999, { showParticles: false, amplifier: 255 });
            entity.playAnimation(entityType.skills[this.index].anim);
            const locator = lib.locator(entity, { z: 2 });

            await mc.system.waitTicks(0.4 * 20);
            if (ifDead(entity)) return;

            if (mc.world.getDynamicProperty("ld_eb:efeitos_sonoros"))
                mc.world.playSound("ld_eb.earth_elemental.attack", locator.location, { pitch: 1, volume: 20 });

            await mc.system.waitTicks(0.1 * 20);
            if (ifDead(entity)) return;

            lib.getEntities(locator, 10).filter(e => e !== entity).forEach(e => {
                e.applyDamage(entityType.skills[this.index].damage*difficultyDamageController);
                try { e.applyKnockback(entity.getViewDirection().x, entity.getViewDirection().z, 1, 0.3); } catch {}
            });

            await mc.system.waitTicks(Math.max(0.1, entityType.skills[this.index].delay) * 20);
            if (ifDead(entity)) return;

            entity.removeEffect("slowness");
            entity.ld_eb_inAttack = false;
            entity.triggerEvent("ld_eb:remove_cancel_rotation");
        }
    },
    {
        index: 1,
        async start(entity) {
            entity.ld_eb_inAttack = true;
            entity.addEffect("slowness", 9999999, { showParticles: false, amplifier: 255 });
            entity.playAnimation(entityType.skills[this.index].anim);
            const locator = lib.locator(entity, { z: 2 });

            await mc.system.waitTicks(0.5 * 20);
            if (ifDead(entity)) return;

            if (mc.world.getDynamicProperty("ld_eb:efeitos_sonoros"))
                mc.world.playSound("ld_eb.earth_elemental.1", locator.location, { pitch: 1, volume: 20 });

            await mc.system.waitTicks(0.2 * 20);
            if (ifDead(entity)) return;

            lib.getEntities(locator, 10).filter(e => e !== entity).forEach(e => {
                e.applyDamage(entityType.skills[this.index].damage*difficultyDamageController);
                try { e.applyKnockback(entity.getViewDirection().x, entity.getViewDirection().z, 1.3, 1); } catch {}
            });

            await mc.system.waitTicks(Math.max(0.1, entityType.skills[this.index].delay) * 20);
            if (ifDead(entity)) return;

            entity.removeEffect("slowness");
            entity.ld_eb_inAttack = false;
            entity.triggerEvent("ld_eb:remove_cancel_rotation");
        }
    },
    {
        index: 2,
        async start(entity) {
            entity.ld_eb_inAttack = true;
            entity.addEffect("slowness", 9999999, { showParticles: false, amplifier: 255 });
            entity.playAnimation(entityType.skills[this.index].anim);
            const locator = lib.locator(entity, { z: 2 });

            for (const e of lib.getEntities(locator, 15).filter(e => e !== entity)) {
                await mc.system.waitTicks(0.1 * 20);
                if (ifDead(entity)) return;

                if (mc.world.getDynamicProperty("ld_eb:efeitos_sonoros"))
                    mc.world.playSound("ld_eb.earth_elemental.3", locator.location, { pitch: 1, volume: 20 });

                await mc.system.waitTicks(0.6 * 20);
                if (ifDead(entity)) return;

                const spell = e.dimension.spawnEntity("ld_eb:ld_eb_earth_vine", e.location);
                for (let i = 1; i <= 8; i++) {
                    spell.dimension.spawnParticle(`ld_eb:earth_mob_vine_snare_${i}`, e.location);
                }
                spell.dimension.spawnParticle("ld_eb:earth_mob_boulder_crush_2", e.location);
                spell.dimension.spawnParticle("ld_eb:earth_mob_boulder_crush_4", e.location);

                const tick = mc.system.runInterval(() => {
                    if (!spell.isValid()) return mc.system.clearRun(tick);
                    e.applyDamage(entityType.skills[this.index].damagePS*difficultyDamageController);
                }, 10);

                if (e.typeId === "minecraft:player") {
                    e.inputPermissions.movementEnabled = false;
                } else {
                    e.addEffect("slowness", 9999999, { showParticles: false, amplifier: 255 });
                }

                await mc.system.waitTicks(3 * 20);
                if (e.typeId === "minecraft:player") {
                    e.inputPermissions.movementEnabled = true;
                } else {
                    e.removeEffect("slowness");
                }

                spell.remove();
            }

            await mc.system.waitTicks(Math.max(0.1, entityType.skills[this.index].delay) * 20);
            if (ifDead(entity)) return;

            entity.removeEffect("slowness");
            entity.ld_eb_inAttack = false;
            entity.triggerEvent("ld_eb:remove_cancel_rotation");
        }
    },
    {
        index: 3,
        async start(entity) {
            entity.ld_eb_inAttack = true;
            entity.addEffect("slowness", 9999999, { showParticles: false, amplifier: 255 });
            entity.playAnimation(entityType.skills[this.index].anim);
            const locator = lib.locator(entity, { x: -0.4, y: 0, z: 2 });
            const target = lib.getEntities(locator, 20).filter(e => e !== entity)[0];

            if (!target) return;

            entity.teleport(entity.location, { facingLocation: target.location });
            const spell = locator.dimension.spawnEntity("ld_eb:ld_eb_earth_rock", locator.location);
            spell.setRotation(entity.getRotation());

            await mc.system.waitTicks(0.2 * 20);
            if (ifDead(entity)) return;

            if (mc.world.getDynamicProperty("ld_eb:efeitos_sonoros"))
                mc.world.playSound("ld_eb.earth_elemental.attack", locator.location, { pitch: 1, volume: 20 });

            await mc.system.waitTicks(0.5 * 20);
            if (ifDead(entity)) return;

            lib.ProjectileShootLocation(locator, target.location, 1);

            const interval = mc.system.runInterval(() => {
                if (!spell.isValid()) return mc.system.clearRun(interval);
                ////console1-console.warn('damaging')
                lib.getEntities(locator, 3).filter(e => e !== entity).forEach(async e => {
                    await mc.system.waitTicks(0.2 * 20);
                    if (mc.world.getDynamicProperty("ld_eb:efeitos_sonoros"))
                        mc.world.playSound("ld_eb.earth_elemental.2", locator.location, { pitch: 1, volume: 20 });

                    e.applyDamage(entityType.skills[this.index].damage*difficultyDamageController);
                    try { e.applyKnockback(entity.getViewDirection().x, entity.getViewDirection().z, 2, 0.3); } catch {}
                });
            });

            await mc.system.waitTicks(Math.max(0.1, entityType.skills[this.index].delay) * 20);
            if (ifDead(entity)) return;

            entity.removeEffect("slowness");
            entity.ld_eb_inAttack = false;
            entity.triggerEvent("ld_eb:remove_cancel_rotation");
        }
    }
];

mc.world.afterEvents.entityLoad.subscribe(data => {
    const entity = data.entity;
    if (entity.typeId !== entityType.typeId) return;
    entity.removeEffect("slowness");
    entity.triggerEvent("ld_eb:remove_cancel_rotation");
});

/** @param { mc.Entity } entity */
function ifDead(entity) {
    const health = entity.getComponent(mc.EntityHealthComponent.componentId);
    return !health || health.currentValue <= 1;
}
