import * as mc from "@minecraft/server"
import * as lib from "../../lib"
import { itemStack, startAnimations } from "./item"

const type = {
    delay: 1,
    damage: lib.damage.extremo,
    damageMultiplier: 1.3
}

mc.world.afterEvents.itemUse.subscribe(async data => {
    const item = data.itemStack,
        player = data.source
    if (item.typeId !== itemStack.typeId) return
    if (player.getItemCooldown(item.typeId) !== 0) return
    if (!player.isSneaking || player.isOnGround) return
    if (player.getDynamicProperty("ld_eb:is_in_ult")) return
    if (player.getDynamicProperty(item.typeId + ".lvl") < 5) {
        player.onScreenDisplay.setActionBar(
            "§cYou must be at least level 5 to use this skill."
        )
        !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null: player.playSound("note.bass")
        return
    }
    if (player.getDynamicProperty(item.typeId + ".ult") < 10) {
            player.onScreenDisplay.setActionBar(
                "§cYour power is not strong enough... Kill hostile mobs to earn Ultimate points!"
            )
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("note.bass")
            return
        }
    player.setDynamicProperty(item.typeId + ".ult", 0)
    player.startItemCooldown(item.typeId, type.delay * 20)
    player.onScreenDisplay.setActionBar({
        translate: "actionbar.ld_eb:ld_eb_frostbound_glaive.glacial_cataclysm"    
    })
    /** @type { mc.Entity } */
    const locator = lib.locatorEntity(player, { z: 3 }, false, false)
    locator.owner = player
    const size = 7
    lib.spawnBox(locator, size)
    const players = locator.dimension.getEntities({
        type: "minecraft:player",
        location: locator.location,
        maxDistance: size
    })
    players.forEach(p => p.playSound("ld_eb.ice_soundtrack", { volume: 20, pitch: 1 }))

    players.forEach(p => lib.startUlt(p, player))

    await mc.system.waitTicks(0.3 * 20)

    player.playAnimation("animation.ld_eb_frostbound_glaive.glacial_cataclysm")

    players.forEach(p => lib.cameraToPlayer(p, player, { z: 2, x: 0, y: 1 }, { y: 1.8, z: 0 }))
    /** @type { mc.Entity } */
    const spell = lib.spell(
        "ld_eb:ld_eb_frostbound_glaive.glacial_cataclysm",
        player,
        { z: 0, y: 0 },
        { y: player.getRotation().y },
        true,
        false
    )
    
    await mc.system.waitTicks(0.3 * 20)
    players.forEach(p => lib.cameraToPlayer(p, player, { z: 18, x: 0, y: 5 }, { y: 1, z: 8 }))
    players.forEach(p => lib.shakeBlend(p, { power: 0.3, holdTime: 0.1, outTime: 0.3 }))
    players.forEach(p => p.playSound("ld_eb.rockpunch", { volume: 20, pitch: lib.random(2, 2.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_armor", { volume: 20, pitch: lib.random(0.6, 0.9) }))

    await mc.system.waitTicks(0.8 * 20)
    players.forEach(p => lib.cameraToPlayer(p, player, { z: -6, x: 0, y: 6 }, { y: 4 }))

    await mc.system.waitTicks(1 * 20)
    players.forEach(p => lib.cameraToPlayer(p, player, { z: 16, x: -8, y: 3 }, { z: 8, y: 4 }))

    await mc.system.waitTicks(0.1 * 20)
    players.forEach(p => lib.fade(p, "white", [0.1, 0.1, 0.4]))
    players.forEach(p => lib.shakeBlend(p, { power: 0.6, holdTime: 0.3, outTime: 2.5 }))
    players.forEach(p => p.playSound("ld_eb.rockpunch", { volume: 20, pitch: lib.random(1, 1.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_smash", { volume: 20, pitch: lib.random(0.9, 1.9) }))
    
    await mc.system.waitTicks(0.5 * 20)
    players.forEach(p => lib.shakeBlend(p, { power: 0.6, holdTime: 0.3, outTime: 2.5 }))
    players.forEach(p => p.playSound("ld_eb.rockpunch", { volume: 20, pitch: lib.random(1, 1.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_smash", { volume: 20, pitch: lib.random(0.9, 1.9) }))

    await mc.system.waitTicks(0.5 * 20)
    players.forEach(p => lib.shakeBlend(p, { power: 0.6, holdTime: 0.3, outTime: 2.5 }))
    players.forEach(p => p.playSound("ld_eb.rockpunch", { volume: 20, pitch: lib.random(1, 1.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_smash", { volume: 20, pitch: lib.random(0.9, 1.9) }))

    await mc.system.waitTicks(2.5 * 20)
    players.forEach(p => lib.cameraToPlayer(p, player, { z: -6, x: 0, y: 3 }, { y: 1.8 }))

    await mc.system.waitTicks(0.6 * 20)
    players.forEach(p => lib.shakeBlend(player, { power: 0.3, holdTime: 0.2, outTime: 0.3 }))
    players.forEach(p => p.playSound("ld_eb.airblow", { volume: 20, pitch: lib.random(3, 3.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_smash", { volume: 20, pitch: lib.random(1.2, 1.4) }))

    await mc.system.waitTicks(1 * 20)
    players.forEach(p => lib.shakeBlend(p, { power: 0.6, holdTime: 0.3, outTime: 2.5 }))
    players.forEach(p => p.playSound("ld_eb.rockpunch", { volume: 20, pitch: lib.random(1, 1.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_smash", { volume: 20, pitch: lib.random(0.9, 1.9) }))

    await mc.system.waitTicks(0.2 * 20)
    players.forEach(p => lib.shakeBlend(p, { power: 0.6, holdTime: 0.3, outTime: 2.5 }))
    players.forEach(p => p.playSound("ld_eb.rockpunch", { volume: 20, pitch: lib.random(1, 1.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_smash", { volume: 20, pitch: lib.random(0.9, 1.9) }))

    await mc.system.waitTicks(0.2 * 20)
    players.forEach(p => lib.shakeBlend(p, { power: 0.6, holdTime: 0.3, outTime: 2.5 }))
    players.forEach(p => p.playSound("ld_eb.rockpunch", { volume: 20, pitch: lib.random(1, 1.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_smash", { volume: 20, pitch: lib.random(0.9, 1.9) }))

    await mc.system.waitTicks(0.2 * 20)
    players.forEach(p => lib.shakeBlend(p, { power: 0.6, holdTime: 0.3, outTime: 2.5 }))
    players.forEach(p => p.playSound("ld_eb.rockpunch", { volume: 20, pitch: lib.random(1, 1.5) }))
    players.forEach(p => p.playSound("ld_eb.ice_smash", { volume: 20, pitch: lib.random(0.9, 1.9) }))
    spell.remove()

    await mc.system.waitTicks(0.8 * 20)
    players.forEach(p => lib.fade(player, "black", [0.3, 0.1, 0.8]))
    lib.rayCast(locator, 10, 1,
        /** @param  { mc.Entity } target */
        function (target) {
            target.applyDamage(type.damage + ((type.damageMultiplier - 1) + ((type.damage * (player.getDynamicProperty(item.typeId + ".lvl") >= 10 ? 3: player.getDynamicProperty(item.typeId + ".lvl") >= 5 ? 2: 1) - type.damage))), {
                cause: "contact",
                damagingEntity: player
            })
            target.addEffect("slowness", 2 * 20, {
                amplifier: 1,
                showParticles: false
            })
        }
    )

    await mc.system.waitTicks(0.3 * 20)
    lib.despawnBox(locator)
    players.forEach(p => lib.finalUlt(p, player))
    locator.remove()
    startAnimations(player)
})