/*
    @author Hertz
    @version 1.0
*/
var $ResourceLocation = Java.loadClass('net.minecraft.resources.ResourceLocation');
var $ResourceKey = Java.loadClass("net.minecraft.resources.ResourceKey")
var DAMAGE_TYPE = $ResourceKey.createRegistryKey("damage_type")

var PlayerUtil = Java.loadClass('net.threetag.palladium.util.PlayerUtil');
global.playSoundToAll = function(entity, range, sound, category, volume, pitch) {
    PlayerUtil['playSoundToAll(net.minecraft.world.level.Level,double,double,double,double,net.minecraft.resources.ResourceLocation,net.minecraft.sounds.SoundSource,float,float)'](entity.getLevel(), entity.x, entity.y, entity.z, range, sound, category, volume, pitch);
}

function getDamageSourceBothSides(
    /** @type {Internal.Level}*/ level,
    /** @type {Internal.DamageType_}*/ damageType,
    /** @type {Internal.LivingEntity}*/ destEntity,
    /** @type {Internal.LivingEntity}*/ sourceEntity
    ) {
    var resourceKey = $ResourceKey.create(DAMAGE_TYPE, Utils.id(damageType))
    var holder = level.registryAccess().registryOrThrow(DAMAGE_TYPE).getHolderOrThrow(resourceKey)
    var damagesourceholder = holder
    return new DamageSource(damagesourceholder, sourceEntity, destEntity)
}

function resolveAllegedBooleanFromObject(thing) {
    if (thing.toString() == 'true') { return true; }
    if (thing.toString() == 'false') { return false; }
    return null
}

StartupEvents.registry('palladium:abilities', (event) => {
    
    event.create('arrzenhanced:raycast_damage_with_sound')
    .icon(palladium.createItemIcon('minecraft:note_block'))
    .addProperty('sound', 'string', 'minecraft:entity.player.attack.strong', 'Sound to play')
    .addProperty('distance', 'integer', 5, 'Max distance to raycast')
    .addProperty('damage', 'float', 3.5, 'Damage to deal')
    .addProperty('add_mainhand_damage', 'boolean', false, 'Add the damage of the player\'s mainhand item to the damage dealt')
    .tick((entity, entry, holder, enabled) => global.raycastDamageWithSound(entity, entry, holder, enabled));
});

global.raycastDamageWithSound = (entity, entry, holder, enabled) => {
    if (enabled) {
        var soundToPlay = new $ResourceLocation(entry.getPropertyByName('sound'));
        var dist = entry.getPropertyByName('distance');
        var damage = entry.getPropertyByName('damage');
        var mainhandDamage = resolveAllegedBooleanFromObject(entry.getPropertyByName('add_mainhand_damage'));
        var level = entity.getLevel()
        var victim = advancedRayTrace(entity, level, dist).entity
        if (!victim && entity.age % 10) {
            global.playSoundToAll(entity, 8, "minecraft:entity.player.attack.nodamage", "players", 1, 1)
        }
        if (!victim) return

        let damageSource = getDamageSourceBothSides(level, "minecraft:player_attack", entity, victim)
        if (mainhandDamage) {
            let item = entity.mainHandItem
            if (!item.isEmpty()) {
                let attackDamage = item.getAttributeModifiers('mainhand')
                attackDamage.keySet().forEach(attributeKey => {
                    var attributeName = attributeKey.getDescriptionId();
        
                    if (attributeName.includes('attack_damage')) {
                        var modifiers = attackDamage.get(attributeKey);
        
                        modifiers.forEach(modifier => {
                            damage += modifier.amount
                        });
                    }
                });
            }
        }
        if (damage > 8) {damage = 8}
        victim.attack(damageSource, damage)
        
        if (entity.age % 5) {
            global.playSoundToAll(entity, 8, soundToPlay, "players", 1, 1)
        }
    }
}

StartupEvents.registry('sound_event', event => {
    // event.create('hertz_heroes:heartbeat')
    // event.create('dampened:cuffs_activate')
    // event.create('dampened:cuffs_equip')
    // event.create('dampened:cuffs_failure')
    // event.create('dampened:cuffs_unlock')
})