import * as mc from "@minecraft/server";
import * as utils from "../../utils/index";
import * as comp from "../components/index";
import { BotBase } from "../bot";
const POWER = 3;
const VERTPOWER = 0.5;
const RANGE = 8;
const VERTICAL_RANGE = 3;
const WIND_STRENGTH = 1; //particle variable
export class FanBot extends BotBase {
    constructor() {
        super(...arguments);
        this.active = this.getProperty("active");
    }
    get EffectExceptions() {
        return {
            "invisibility": () => true,
        };
    }
    get Active() {
        return this.active;
    }
    get FaceUp() {
        return this.getProperty("face_up");
    }
    set Active(v) {
        if (!this.isValid())
            return;
        this.active = v;
        this.setProperty("active", v);
    }
    onConstructed() {
        super.onConstructed();
        this.addActorComponent(comp.BlockSnapComponent, { angle: 90 });
        this.addActorComponent(comp.SpawnPlacement);
        utils.waitForEvent(3, this.fanLoop.bind(this));
    }
    onInteract(player) {
        player.dimension.playSound(utils.addName("entity.bot.confirm"), player.location);
        this.Active = !this.Active;
        if (!this.Active)
            this.runCommand(`stopsound @a ldz_240927:entity.fan_bot.gust`);
        this.fanLoop();
    }
    async fanLoop() {
        if (!this.isValid() || !this.Active) {
            return;
        }
        while (this.isValid() && this.Active) {
            if (!this.FaceUp) {
                await this.fanBlowing();
                await this.particles();
            }
            if (this.FaceUp) {
                await this.fanBlowingVert();
                await this.particlesVert();
            }
        }
    }
    async fanBlowing() {
        //APPLY HORIZONTAL IMPULSE/KNOCKBACK TO PLAYERS & MOBS
        if (this.FaceUp)
            return;
        const direction = this.getViewDirection();
        utils.getEntitiesFromViewDirectionSafe(this, { excludeTypes: ["minecraft:item", "minecraft:boat"], excludeFamilies: ["ldz_240927:utility_bot"], excludeGameModes: [mc.GameMode.spectator], maxDistance: RANGE }).forEach(hit => {
            if (hit.entity.isValid()) {
                try {
                    hit.entity.clearVelocity();
                    hit.entity.applyImpulse(new utils.Vector3(direction));
                }
                catch (error) { }
                hit.entity.applyKnockback(direction.x, direction.z, POWER, 0);
            }
        });
        utils.getEntitiesFromViewDirectionSafe(this, { excludeTypes: ["minecraft:item", "minecraft:boat", "minecraft:player"], excludeFamilies: ["ldz_240927:utility_bot"], maxDistance: RANGE }).forEach(hit => {
            if (hit.entity.isValid()) {
                try {
                    hit.entity.clearVelocity();
                    hit.entity.applyImpulse(new utils.Vector3(direction));
                }
                catch (error) { }
                hit.entity.applyKnockback(direction.x, direction.z, POWER, 0);
            }
        });
        //APPLY HORIZONTAL IMPULSE TO ITEMS
        const origin = new utils.Vector3(this.location);
        for (let index = 1; index < RANGE; index++) {
            const magnitude = direction.multiply(new utils.Vector3(index));
            const destination = origin.add(magnitude);
            const found_entities = this.dimension.getEntitiesAtBlockLocation(destination);
            found_entities.forEach(hit => {
                if (this.isValid() && hit.isValid() && (hit.typeId === "minecraft:item" || hit.typeId === "minecraft:boat")) {
                    try {
                        hit.clearVelocity();
                        hit.applyImpulse(new utils.Vector3(direction));
                    }
                    catch (error) { }
                }
            });
        }
        await utils.waitForTicks(1);
    }
    async fanBlowingVert() {
        //APPLY VERTICAL IMPULSE/KNOCKBACK TO PLAYERS & MOBS
        const origin = new utils.Vector3(this.location);
        if (!this.FaceUp)
            return;
        if (this.FaceUp) {
            for (let index = 0; index < VERTICAL_RANGE; index++) {
                utils.getEntitiesFromRaySafe(this.dimension, origin, utils.Vector3.UP, { excludeTypes: ["minecraft:item", "minecraft:boat"], excludeFamilies: ["ldz_240927:utility_bot"], excludeGameModes: [mc.GameMode.spectator], maxDistance: RANGE }).forEach(hit => {
                    if (hit.entity.isValid()) {
                        hit.entity.applyKnockback(0, 0, 0, VERTPOWER);
                    }
                });
            }
            for (let index = 0; index < VERTICAL_RANGE; index++) {
                utils.getEntitiesFromRaySafe(this.dimension, origin, utils.Vector3.UP, { excludeTypes: ["minecraft:item", "minecraft:boat", "minecraft:player"], excludeFamilies: ["ldz_240927:utility_bot"], maxDistance: RANGE }).forEach(hit => {
                    if (hit.entity.isValid()) {
                        hit.entity.applyKnockback(0, 0, 0, VERTPOWER);
                    }
                });
            }
            //APPLY VERTICAL IMPULSE TO ITEMS
            for (let index = 0; index < VERTICAL_RANGE; index++) {
                let direction = utils.Vector3.UP;
                const magnitude = direction.multiply(new utils.Vector3(index));
                const destination = origin.add(magnitude);
                const found_entities = this.dimension.getEntitiesAtBlockLocation(destination);
                found_entities.forEach(hit => {
                    if (this.isValid() && hit.isValid() && (hit.typeId === "minecraft:item" || hit.typeId === "minecraft:boat")) {
                        try {
                            hit.clearVelocity();
                            hit.applyImpulse(utils.Vector3.UP);
                        }
                        catch (error) { }
                    }
                });
            }
            await utils.waitForTicks(1);
        }
    }
    //HORIZONTAL PARTICLE AND SFX CONTROL
    async particles() {
        const direction = this.getViewDirection();
        let origin = new utils.Vector3(this.location).add({ x: 0, y: 0.5, z: 0 });
        const map = new mc.MolangVariableMap();
        map.setFloat("variable.direction_x", direction.x);
        map.setFloat("variable.direction_y", direction.y);
        map.setFloat("variable.direction_z", direction.z);
        map.setFloat("variable.wind_strength", WIND_STRENGTH);
        mc.world.playSound("ldz_240927:entity.fan_bot.gust", origin, { volume: 0.3 });
        if (this.isValid() && !this.FaceUp) {
            for (let index = 1; index < RANGE; index++) {
                try {
                    this.dimension.spawnParticle("ldz_240927:fan_bot_wind_dust", origin.add(direction.multiply({ x: index, y: index, z: index })), map);
                    this.dimension.spawnParticle("ldz_240927:fan_bot_wind", origin.add(direction.multiply({ x: index, y: index, z: index })), map);
                }
                catch (error) { }
            }
        }
        await utils.waitForTicks(5);
    }
    //VERTICAL PARTICLE AND SFX CONTROL
    async particlesVert() {
        for (let index = 1; index < RANGE; index++) {
            const origin = new utils.Vector3(this.location);
            const direction = new utils.Vector3(this.getViewDirection().up());
            const map = new mc.MolangVariableMap();
            map.setFloat("variable.direction_x", direction.x);
            map.setFloat("variable.direction_y", direction.y);
            map.setFloat("variable.direction_z", direction.z);
            map.setFloat("variable.wind_strength", WIND_STRENGTH);
            mc.world.playSound("ldz_240927:entity.fan_bot.gust", origin, { volume: 0.3 });
            try {
                this.dimension.spawnParticle("ldz_240927:fan_bot_wind_dust_vertical", origin.add(direction.multiply({ x: 0, y: index, z: 0 })), map);
                this.dimension.spawnParticle("ldz_240927:fan_bot_wind_verticle", origin.add(direction.multiply({ x: 0, y: index, z: 0 })), map);
            }
            catch (error) { }
        }
        await utils.waitForTicks(5);
    }
}
utils.Actor.makeActors({ type: "ldz_240927:fan_bot" }, FanBot);
