import { system } from "@minecraft/server";
import FSUtil from "./FSUtil";
import { FSCompassDirection } from "./FSCompassDirection";
export default class FSEntityHelper {
    static getCompassDirection(entity) {
        const rotation = entity.getRotation();
        if (rotation.y > -45 && rotation.y < 45) {
            return FSCompassDirection.South;
        }
        else if (rotation.y > 45 && rotation.y < 135) {
            return FSCompassDirection.West;
        }
        else if (rotation.y >= -180 && rotation.y < -135) {
            return FSCompassDirection.North;
        }
        else if (rotation.y > 135 && rotation.y <= 180) {
            return FSCompassDirection.North;
        }
        else if (rotation.y > -135 && rotation.y < -45) {
            return FSCompassDirection.East;
        }
        return FSCompassDirection.Unknown;
    }
    static snapRotation(entity, jump_up_amount = 0) {
        try {
            let new_rotation = 0;
            const compass_direction = FSEntityHelper.getCompassDirection(entity);
            switch (compass_direction) {
                case FSCompassDirection.South:
                    new_rotation = 0;
                    break;
                case FSCompassDirection.West:
                    new_rotation = 90;
                    break;
                case FSCompassDirection.North:
                    new_rotation = 180;
                    break;
                case FSCompassDirection.East:
                    new_rotation = 270;
                    break;
                default:
                    break;
            }
            entity.teleport({ x: entity.location.x, y: entity.location.y + jump_up_amount, z: entity.location.z });
            entity.setRotation({ x: 0, y: new_rotation });
            system.runTimeout(() => {
                if (entity.isValid()) {
                    FSEntityHelper.snapRotationAgain(entity);
                }
            }, 20);
        }
        catch (error) { }
    }
    static snapRotationAgain(entity, jump_up_amount = 0) {
        try {
            let new_rotation = 0;
            const compass_direction = FSEntityHelper.getCompassDirection(entity);
            switch (compass_direction) {
                case FSCompassDirection.South:
                    new_rotation = 0;
                    break;
                case FSCompassDirection.West:
                    new_rotation = 90;
                    break;
                case FSCompassDirection.North:
                    new_rotation = 180;
                    break;
                case FSCompassDirection.East:
                    new_rotation = 270;
                    break;
                default:
                    break;
            }
            entity.teleport({ x: entity.location.x, y: entity.location.y + jump_up_amount, z: entity.location.z });
            entity.setRotation({ x: 0, y: new_rotation });
        }
        catch (error) { }
    }
    static getClosestPlayer(entity, maxDistance = 16) {
        const eqo = {
            closest: 1,
            location: entity.location,
            maxDistance: maxDistance
        };
        let players = entity.dimension.getPlayers(eqo);
        if (players.length > 0) {
            return players[0];
        }
        return undefined;
    }
    static getClosestPlayers(entity, maxDistance = 16, maxPlayers = 1) {
        const eqo = {
            closest: maxPlayers,
            location: entity.location,
            maxDistance: maxDistance
        };
        let players = entity.dimension.getPlayers(eqo);
        if (players.length > 0) {
            return players;
        }
        return undefined;
    }
    static getClosestEntity(entity, maxDistance = 16) {
        const eqo = {
            closest: 1,
            location: entity.location,
            maxDistance: maxDistance,
            families: ["mob"]
        };
        let entities = entity.dimension.getEntities(eqo);
        if (entities.length > 0) {
            return entities[0];
        }
        return undefined;
    }
    static getClosestEntities(entity, typePrefix = "", maxDistance = 16, maxCount = 512) {
        const eqo = {
            closest: maxCount,
            location: entity.location,
            maxDistance: maxDistance,
            minDistance: 0
        };
        let entities = entity.dimension.getEntities(eqo);
        if (typePrefix.length > 0) {
            entities = entities.filter(e => e.typeId.startsWith(typePrefix));
        }
        entities = entities.slice(0, maxCount);
        return entities;
    }
    static getClosestEntityOfType(player, typeId, filterTags = []) {
        const segments = typeId.split(":");
        if (segments.length > 1) {
            typeId = segments[0];
        }
        const playerPos = player.getHeadLocation();
        const entities = player.dimension.getEntities();
        const deliveryBoxes = entities.filter(entity => entity.typeId === FSUtil.namespacedString(typeId));
        let nearbyBoxes = deliveryBoxes.filter(box => {
            const boxPos = box.getHeadLocation();
            const distance = Math.sqrt(Math.pow(playerPos.x - boxPos.x, 2) + Math.pow(playerPos.y - boxPos.y, 2) + Math.pow(playerPos.z - boxPos.z, 2));
            return distance < 6;
        });
        if (filterTags.length > 0) {
            nearbyBoxes = nearbyBoxes.filter(box => {
                const tags = box.getTags();
                for (const tag of filterTags) {
                    if (tag.startsWith("!")) {
                        if (tags.includes(tag.substring(1))) {
                            return false;
                        }
                    }
                    else {
                        if (!tags.includes(tag)) {
                            return false;
                        }
                    }
                }
                return true;
            });
        }
        if (nearbyBoxes.length === 0) {
            return undefined;
        }
        const closestBox = nearbyBoxes.reduce((prev, curr) => {
            const prevPos = prev.getHeadLocation();
            const currPos = curr.getHeadLocation();
            const prevDistance = Math.sqrt(Math.pow(playerPos.x - prevPos.x, 2) + Math.pow(playerPos.y - prevPos.y, 2) + Math.pow(playerPos.z - prevPos.z, 2));
            const currDistance = Math.sqrt(Math.pow(playerPos.x - currPos.x, 2) + Math.pow(playerPos.y - currPos.y, 2) + Math.pow(playerPos.z - currPos.z, 2));
            return prevDistance < currDistance ? prev : curr;
        });
        return closestBox;
    }
    static getClosestEntityOfTypeAtLocation(dimension, location, typeId) {
        const segments = typeId.split(":");
        if (segments.length > 1) {
            typeId = segments[0];
        }
        const entities = dimension.getEntities();
        const deliveryBoxes = entities.filter(entity => entity.typeId === FSUtil.namespacedString(typeId));
        const nearbyBoxes = deliveryBoxes.filter(box => {
            const boxPos = box.getHeadLocation();
            const distance = Math.sqrt(Math.pow(location.x - boxPos.x, 2) + Math.pow(location.y - boxPos.y, 2) + Math.pow(location.z - boxPos.z, 2));
            return distance < 6;
        });
        if (nearbyBoxes.length === 0) {
            return undefined;
        }
        const closestBox = nearbyBoxes.reduce((prev, curr) => {
            const prevPos = prev.getHeadLocation();
            const currPos = curr.getHeadLocation();
            const prevDistance = Math.sqrt(Math.pow(location.x - prevPos.x, 2) + Math.pow(location.y - prevPos.y, 2) + Math.pow(location.z - prevPos.z, 2));
            const currDistance = Math.sqrt(Math.pow(location.x - currPos.x, 2) + Math.pow(location.y - currPos.y, 2) + Math.pow(location.z - currPos.z, 2));
            return prevDistance < currDistance ? prev : curr;
        });
        return closestBox;
    }
    static getBlockUnderEntity(entity) {
        try {
            let location = { x: entity.location.x, y: entity.location.y - 1, z: entity.location.z };
            if (location.y < entity.dimension.heightRange.min) {
                return undefined;
            }
            return entity.dimension.getBlock(location);
        }
        catch (ex) {
            return undefined;
        }
    }
    static getBlockAboveEntity(entity) {
        try {
            let location = { x: entity.location.x, y: entity.location.y + 1, z: entity.location.z };
            if (location.y > entity.dimension.heightRange.max) {
                return undefined;
            }
            return entity.dimension.getBlock(location);
        }
        catch (ex) {
            return undefined;
        }
    }
    static getBlockAtEntity(entity) {
        try {
            let location = { x: entity.location.x, y: entity.location.y, z: entity.location.z };
            if (location.y > entity.dimension.heightRange.max) {
                return undefined;
            }
            return entity.dimension.getBlock(location);
        }
        catch (ex) {
            return undefined;
        }
    }
    static hasFamily(entity, family) {
        const familyComponent = entity.getComponent(`minecraft:type_family`);
        if (familyComponent) {
            return familyComponent.hasTypeFamily(family);
        }
        return false;
    }
    static hasComponent(entity, component) {
        return entity.hasComponent(component);
    }
}

//# sourceMappingURL=../../../../_SBUNK_BPDebug/fs_sbunk/fs/FSEntityHelper.js.map
