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:water_elemental",
    skills: [
        { delay: delayVelocityMultiplier * 2, damage: damageMultiplier, id: 0, chance: 3, anim: "attack" },
        { delay: delayVelocityMultiplier * 2, damagePS: damageMultiplier, id: 1, chance: 3, anim: "aqua_vortex" },
        { delay: delayVelocityMultiplier * 2, damage: damageMultiplier, id: 2, chance: 3, anim: "tidal_wave" },
        { delay: delayVelocityMultiplier * 3, damage: damageMultiplier, id: 3, chance: 3, anim: "frost_bite" }
    ]
}

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 locator = lib.locator(entity, { z: 2 })

            await mc.system.waitTicks(12)
            if (ifDead(entity)) return

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

            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, 2, 0.2) } catch {}
            })

            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)
            const locator = lib.locator(entity, { z: 2 })

            await mc.system.waitTicks(2)
            if (ifDead(entity)) return

            const spell = lib.locator(locator)
            await mc.system.waitTicks(2)
            if (ifDead(entity)) return

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

            lib.getEntities(locator, 10).filter(e => e !== entity).forEach(e => {
                e.applyDamage(entityType.skills[this.index].damagePS*difficultyDamageController)
                e.addEffect("levitation", 20, { showParticles: false, amplifier: 5 })
                const tick = mc.system.runInterval(() => {
                    if (!spell.isValid()) return mc.system.clearRun(tick)
                    e.applyDamage(entityType.skills[this.index].damagePS*difficultyDamageController)
                    lib.middleImpulse(e, spell, 1, 0.1)
                }, 10)
            })

            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: 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 locator = lib.locator(entity, { z: 2 })

            await mc.system.waitTicks(10)
            if (ifDead(entity)) return
            if (mc.world.getDynamicProperty("ld_eb:efeitos_sonoros"))
                mc.world.playSound("ld_eb.water_elemental.2", locator.location, { pitch: 1, volume: 20 })

            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, 4, 0.6) } catch {}
            })

            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
    },
    {
        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(18)
            if (ifDead(entity)) return
            if (mc.world.getDynamicProperty("ld_eb:efeitos_sonoros"))
                mc.world.playSound("ld_eb.water_elemental.3", entity.location, { pitch: 1, volume: 20 })

            lib.getEntities(entity, 16).filter(e => e !== entity).forEach(e => {
                e.applyDamage(entityType.skills[this.index].damage*difficultyDamageController)
                lib.middleImpulse(e, entity, -5, 0.9)
            })

            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: 3
    }
]

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
}