import * as mc from '@minecraft/server';
import { lazerBetweenLocations, lazerBetweenPoints } from './effects';
import { isEntityinCone } from './dragon_attacks';

const aoe_damage = 2;
const aoe_radius = 2;
const on_fire_duration = 5;

const trident_radius = 4;
const trident_damage = 5;

const hammer_radius = 5;
const hammer_damage = 1;

const spear_range = 8;
const spear_damage = 6;
const spear_cone = 15;
const spear_vertical_knockback = 0.5;
const spear_horizontal_knockback = 0.5;

const skull_range = 2.5;
const boss_skull_damage = 5;
const skull_damage = 8;
const skull_knockback = 0.3;

export function main() {
    impactController();
}

function impactController() {
    mc.system.afterEvents.scriptEventReceive.subscribe((eventData) => {
        const{id,sourceEntity,message} = eventData;
        if(sourceEntity == null) return;
        if(id!= "pb:fire_axe_projectile" && message!= "impact") return;

        let evt_location = sourceEntity.location;
        let dimension = sourceEntity.dimension.id;
        let ground_flag = false;

        let block = mc.world.getDimension(dimension).getBlock({x: evt_location.x,y: evt_location.y-1, z: evt_location.z});

        if(!block.isAir && !block.isLiquid)
        {
            ground_flag = true;
            mc.world.getDimension(dimension).spawnParticle('pb:fire_spread_medium', evt_location);
        }

        for (let entity of mc.world.getDimension(dimension).getEntities({ location: evt_location,  excludeFamilies: ["npc","player","projectile","item"], maxDistance: aoe_radius})) 
        {   
            if(ground_flag)
            {
                mc.world.sendMessage("spread fire: "+ entity.typeId);

                entity.applyDamage(aoe_damage);
                entity.setOnFire(on_fire_duration, true);
            }
        }

        try 
        {

        } 
        catch (error) {
            mc.world.sendMessage("fail fire: ");
        }     
    })
}

export function hammerReject(sourceEntity) {
   
    let evt_location = sourceEntity.location;
    let dimension = sourceEntity.dimension.id;

    mc.world.getDimension(dimension).spawnParticle('pb:hammer_shockwave_pixel', evt_location);
    mc.world.getDimension(dimension).spawnParticle('pb:smoke_curly_ground_ring', evt_location);

    for (let entity of mc.world.getDimension(dimension).getEntities({ location: evt_location,  families: ["monster"], maxDistance: hammer_radius})) 
    {   
        entity.addTag("hammer_reject");
        entity.applyKnockback(entity.location.x - evt_location.x, entity.location.z - evt_location.z, 6 , 0.75);
        entity.applyDamage(hammer_damage);
    }
}

export function tridentAttack(sourceEntity) {
   
    let evt_location = sourceEntity.location;
    let dimension = sourceEntity.dimension.id;

    let block = mc.world.getDimension(dimension).getBlock({x: evt_location.x,y: evt_location.y-1, z: evt_location.z});

    mc.world.getDimension(dimension).spawnParticle('pb:lightning_line_sparks_large_2', evt_location);
    mc.world.getDimension(dimension).spawnParticle('pb:lightning_impact_sparks', evt_location);
    mc.world.getDimension(dimension).spawnParticle('pb:lightning_trident_impact', evt_location);

    for (let entity of mc.world.getDimension(dimension).getEntities({ location: evt_location,  families: ["monster"], maxDistance: trident_radius})) 
    {   
        //mc.world.sendMessage("hit_by_lightning: "+ entity.typeId);

        mc.world.getDimension(dimension).spawnParticle('pb:lightning_strike_glow_large', entity.location);
        mc.world.getDimension(dimension).spawnParticle('pb:lightning_sparks_glow_large', entity.location);
        entity.applyDamage(trident_damage);

        
        
    }
}

export function spearAttack(sourceEntity) {
   
    mc.world.sendMessage("spear attack");

    let evt_location = sourceEntity.location;
    let dimension = sourceEntity.dimension.id;
    let view_vector = sourceEntity.getViewDirection();
    view_vector = {x: view_vector.x, y: 0, z: view_vector.z};
    //mc.world.sendMessage("view x:" + view_vector.x + " z:" + view_vector.z);

    for (let index = 0; index < spear_range; index++) {
        const loc = {x: evt_location.x+(view_vector.x*index), y: evt_location.y, z: evt_location.z+(view_vector.z*index)}
        mc.world.getDimension(dimension).spawnParticle('pb:physical_impact_sparks', loc);
    }

    try 
    {
        for (let entity of mc.world.getDimension(dimension).getEntities({ location: evt_location,  excludeFamilies: ["npc","player","projectile","prop"], maxDistance: spear_range})) 
        {
            if(isEntityinCone(evt_location, entity.location, view_vector, spear_cone))
            {
                entity.applyDamage(spear_damage);
                entity.applyKnockback(entity.location.x - evt_location.x, entity.location.z - evt_location.z, spear_horizontal_knockback , spear_vertical_knockback);
                mc.world.sendMessage("target:" + entity.typeId);
            }
        }
    } 
    catch (error) {}
}

export function spearSpin(sourceEntity) {
   
    let evt_location = sourceEntity.location;
    let dimension = sourceEntity.dimension.id;

    mc.world.getDimension(dimension).spawnParticle('pb:slash_storm_360', evt_location);

    for (let entity of mc.world.getDimension(dimension).getEntities({ location: evt_location,  families: ["monster"], maxDistance: spear_range})) 
    {   
        mc.world.getDimension(dimension).spawnParticle('pb:phys_hit', entity.location);
        entity.applyKnockback(entity.location.x - evt_location.x, entity.location.z - evt_location.z, spear_horizontal_knockback , spear_vertical_knockback);
        entity.applyDamage(spear_damage);
    }
}

export function skullimpact(sourceEntity) {
   
    let evt_location = sourceEntity.location;
    let dimension = sourceEntity.dimension.id;
    try 
    {
        for (let entity of mc.world.getDimension(dimension).getEntities({ location: evt_location, families: ["monster"], excludeFamilies: ["projectile", "prop", "npc", "spell"], maxDistance: skull_range})) 
        {
            entity.applyDamage(skull_damage);
            entity.applyKnockback(entity.location.x - evt_location.x, entity.location.z - evt_location.z, skull_knockback , skull_knockback);
        }
    } 
    catch (error) {}
}

export function skullimpactBoss(sourceEntity) {
   
    let evt_location = sourceEntity.location;
    let dimension = sourceEntity.dimension.id;
    try 
    {
        for (let entity of mc.world.getDimension(dimension).getEntities({ location: evt_location, excludeFamilies: ["mob","monster", "prop", "npc", "spell"], maxDistance: skull_range})) 
        {
            entity.applyDamage(boss_skull_damage);
            entity.applyKnockback(entity.location.x - evt_location.x, entity.location.z - evt_location.z, skull_knockback , skull_knockback);
        }
    } 
    catch (error) {}
}