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:void_monster",
    skills: [
        {
            delay: delayVelocityMultiplier * 2,
            damagePS: damageMultiplier * 1,
            id: 0,
            chance: 3,
            anim: "void_lash"
        },
        {
            delay: delayVelocityMultiplier * 0.1,
            damagePS: damageMultiplier * 1,
            id: 1,
            chance: 3,
            anim: "dimensional_shift"
        },
        {
            delay: delayVelocityMultiplier * 3,
            damagePS: damageMultiplier * 1,
            id: 2,
            chance: 3,
            anim: "eclipse_strike"
        }
    ]
}

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 skillIndex = parseInt(id.replace("ld_eb:skill_", ""))
    if (!isNaN(skillIndex)) skills[skillIndex].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 = [
    {
        start: async function (entity) {
            if (ifDead(entity)) return
            entity.ld_eb_inAttack = true
            entity.addEffect("slowness", 9999999, { showParticles: false, amplifier: 255 })
            entity.playAnimation(entityType.skills[this.index].anim)
            const spell = lib.locatorEntity(entity, { z: 2, y: 1 })

            await mc.system.waitTicks(12)
            if (ifDead(entity)) return
            mc.world.playSound("ld_eb.void_monster.1", entity.location, { pitch: 1, volume: 20 })

            lib.getEntities(spell, 4).filter(e => e !== entity).forEach(e => {
                e.applyDamage(entityType.skills[this.index].damagePS*difficultyDamageController)
                try { e.applyKnockback(entity.getViewDirection().x, entity.getViewDirection().z, 3, 0.3) } catch {}
            })

            await mc.system.waitTicks(30)
            if (spell?.isValid?.()) spell.remove()

            await mc.system.waitTicks(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: 0
    },
    {
        start: async function (entity) {
            if (ifDead(entity)) return
            entity.ld_eb_inAttack = true
            entity.addEffect("slowness", 9999999, { showParticles: false, amplifier: 255 })
            entity.playAnimation(entityType.skills[this.index].anim)

            await mc.system.waitTicks(9)
            if (ifDead(entity)) return
            mc.world.playSound("ld_eb.void_monster.2", entity.location, { pitch: 1, volume: 20 })

            entity.teleport({
                x: entity.location.x + lib.random(-6, 6),
                y: entity.location.y,
                z: entity.location.z + lib.random(-6, 6)
            })

            await mc.system.waitTicks(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
    },
    {
        start: async function (entity) {
            if (ifDead(entity)) return
            entity.ld_eb_inAttack = true
            entity.addEffect("slowness", 9999999, { showParticles: false, amplifier: 255 })
            entity.playAnimation(entityType.skills[this.index].anim)
            const spell = lib.locatorEntity(entity, { z: 2, y: 1 })

            await mc.system.waitTicks(12)
            if (ifDead(entity)) return
            mc.world.playSound("ld_eb.void_monster.3", entity.location, { pitch: 1, volume: 20 })

            entity.teleport({
                x: entity.location.x + lib.random(-4, 4),
                y: entity.location.y,
                z: entity.location.z + lib.random(-4, 4)
            })

            await mc.system.waitTicks(16)

            lib.getEntities(spell, 9).filter(e => e !== entity).forEach(e => {
                e.applyDamage(entityType.skills[this.index].damagePS*difficultyDamageController)
                try { e.applyKnockback(entity.getViewDirection().x, entity.getViewDirection().z, 3, 0.3) } catch {}
            })

            await mc.system.waitTicks(30)
            if (spell?.isValid?.()) spell.remove()

            await mc.system.waitTicks(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
    }
]

skills.forEach((skill, index) => skill.index = index)

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

function ifDead(entity) {
    const health = entity.getComponent(mc.EntityHealthComponent.componentId)
    return !health || health.currentValue <= 1
}
