import { world, Direction, EasingType, system } from "@minecraft/server";
import { FSCompassDirection } from "./fs/FSCompassDirection";
import FSDynamicProperty from "./fs/libs/FSDynamicProperty";
import CameraManager from "./CameraManager";
import FSEntityPerms from "./fs/libs/perms/FSEntityPerms";
import { FSMessageType } from "./fs/libs/perms/FSPlayerPerms";
import JigComputer from "./jig/JigComputer";
import * as mcui from "@minecraft/server-ui";
import FSLocalizedString from "./fs/FSLocalizedString";
import FormManager from "./FormManager";
export default class PlayerHelper {
    static getCompassDirection(player) {
        if (player.getRotation().y > -45 && player.getRotation().y < 45) {
            return FSCompassDirection.South;
        }
        else if (player.getRotation().y > 45 && player.getRotation().y < 135) {
            return FSCompassDirection.West;
        }
        else if (player.getRotation().y > -180 && player.getRotation().y < -135) {
            return FSCompassDirection.North;
        }
        else if (player.getRotation().y > 135 && player.getRotation().y < 180) {
            return FSCompassDirection.North;
        }
        else if (player.getRotation().y > -135 && player.getRotation().y < -45) {
            return FSCompassDirection.East;
        }
        return FSCompassDirection.Unknown;
    }
    static getSnappedRotation(player, inverted = false) {
        let rotation = 0;
        if (player.getRotation().y > -45 && player.getRotation().y < 45) {
            rotation = inverted ? 180 : 0;
        }
        else if (player.getRotation().y > 45 && player.getRotation().y < 135) {
            rotation = inverted ? -90 : 90;
        }
        else if (player.getRotation().y > -180 && player.getRotation().y < -135) {
            rotation = inverted ? 0 : -180;
        }
        else if (player.getRotation().y > 135 && player.getRotation().y < 180) {
            rotation = inverted ? 0 : -180;
        }
        else if (player.getRotation().y > -135 && player.getRotation().y < -45) {
            rotation = inverted ? 90 : -90;
        }
        return rotation;
    }
    static getDirection(player) {
        if (player.getRotation().y > -45 && player.getRotation().y < 45) {
            return Direction.South;
        }
        else if (player.getRotation().y > 45 && player.getRotation().y < 135) {
            return Direction.West;
        }
        else if (player.getRotation().y > -180 && player.getRotation().y < -135) {
            return Direction.North;
        }
        else if (player.getRotation().y > 135 && player.getRotation().y < 180) {
            return Direction.North;
        }
        else if (player.getRotation().y > -135 && player.getRotation().y < -45) {
            return Direction.East;
        }
        return Direction.South;
    }
    static getInvertedDirection(player) {
        if (player.getRotation().y > -45 && player.getRotation().y < 45) {
            return Direction.North;
        }
        else if (player.getRotation().y > 45 && player.getRotation().y < 135) {
            return Direction.East;
        }
        else if (player.getRotation().y > -180 && player.getRotation().y < -135) {
            return Direction.South;
        }
        else if (player.getRotation().y > 135 && player.getRotation().y < 180) {
            return Direction.South;
        }
        else if (player.getRotation().y > -135 && player.getRotation().y < -45) {
            return Direction.West;
        }
        return Direction.North;
    }
    static offsetLocation(player, dx, dy, dz) {
        return { x: player.location.x + dx, y: player.location.y + dy, z: player.location.z + dz };
    }
    static getBlockUnderPlayer(player) {
        try {
            let location = PlayerHelper.offsetLocation(player, 0, -1, 0);
            if (location.y < -64) {
                return undefined;
            }
            let block = world.getDimension(player.dimension.id).getBlock(location);
            return block;
        }
        catch (ex) {
            return undefined;
        }
    }
    static getBlockOffsetFromPlayer(player, dx, dy, dz) {
        let location = PlayerHelper.offsetLocation(player, dx, dy, dz);
        if (location.y < -64) {
            return undefined;
        }
        let block = world.getDimension(player.dimension.id).getBlock(location);
        return block;
    }
    static setOffsetLocation(player, dx, dy, dz) {
        let location = PlayerHelper.offsetLocation(player, dx, dy, dz);
        player.teleport(location);
    }
    static getPlayerIsAdmin(player) {
        return FSDynamicProperty.getBoolean(player, "is_admin");
    }
    static setPlayerIsAdmin(player, is_admin) {
        FSDynamicProperty.setBoolean(player, "is_admin", is_admin);
    }
    static setPlayerJumpCount(player, count) {
        FSDynamicProperty.setNumber(player, "jump_count", count);
    }
    static getPlayerJumpCount(player) {
        return FSDynamicProperty.getNumber(player, "jump_count");
    }
    static outputAdminAccessRequired(player) {
        let msg0 = FSLocalizedString.localize("chat.access_error.msg.1", "§l§cAccess Denied!§r You do not have the required §cBunker Admin Clearance§r to perform this action.", "Access Denied message");
        let msg1 = FSLocalizedString.localize("chat.access_error.msg.2", "Speak with the §lBunker Admin§r to request access", "Access Denied message");
        system.runTimeout(() => {
            FormManager.sharedInstance().showAccessDenied(player);
        }, 10);
        player.sendMessage({ translate: msg0 });
        player.sendMessage({ translate: msg1 });
    }
    static outputElevatorAccessRequired(player) {
        let sfx = "fs.sbunk.access_denied";
        let msg0 = FSLocalizedString.localize("chat.access_error.elevator.msg.1", "§l§cAccess Denied!§r You require §lElevator Access§r to use this elevator!", "Access Denied message");
        let msg1 = FSLocalizedString.localize("chat.access_error.elevator.msg.2", "Speak with the §lBunker Admin§r to request access", "Access Denied message");
        player.playSound(sfx);
        player.sendMessage({ translate: msg0 });
        player.sendMessage({ translate: msg1 });
    }
    static becomeCameraWithId(player, cameraId) {
        let loc_data = CameraManager.sharedInstance().getLocationDataForCameraId(cameraId);
        if (loc_data) {
            PlayerHelper.becomeCamera(player, loc_data);
        }
        else {
            player.sendMessage({ translate: FSLocalizedString.localize("chat.camera_connection_error", "Error: Unable to connect to camera!", "Camera connection error message") });
        }
    }
    static confirmTeleportToCameraWithId(player, cameraId, viewAfterTeleport = false) {
        const form = new mcui.ActionFormData();
        form.title({ translate: FSLocalizedString.localize("ui.teleport_camera.title", "Teleport to Camera", "Title for teleport to camera") });
        form.body({ translate: FSLocalizedString.localize("ui.teleport_camera.body", "Are you sure you want to teleport to the camera?", "Body text for teleport to camera") });
        form.button({ translate: FSLocalizedString.localize("ui.teleport_camera.teleport", "Teleport to Camera", "Button text for teleporting to camera") });
        form.button({ translate: FSLocalizedString.localize("ui.teleport_camera.stay_here", "Stay Here", "Button text for staying in current location") });
        form.show(player).then(resp => {
            if (resp.canceled) {
                return;
            }
            let selection = resp.selection || 0;
            switch (selection) {
                case 0: {
                    PlayerHelper.teleportToCameraWithId(player, cameraId, viewAfterTeleport);
                    break;
                }
            }
        });
    }
    static teleportToCameraWithId(player, cameraId, viewAfterTeleport = false) {
        let loc_data = CameraManager.sharedInstance().getLocationDataForCameraId(cameraId);
        let error_message = FSLocalizedString.localize("chat.camera.teleport_error", "§4Error:§r Unable to teleport to camera! The location around the camera was obstructed.", "Teleport error message");
        if (loc_data) {
            try {
                let teleport_timeout = 5;
                FSDynamicProperty.setVector3(player, "prev_loc", player.location);
                player.teleport(loc_data.location);
                system.runTimeout(() => {
                    let rco = {
                        maxDistance: 256,
                        includeLiquidBlocks: true,
                        includePassableBlocks: false
                    };
                    let raycast_hit = player.dimension.getBlockFromRay(loc_data.location, { x: 0, y: -1, z: 0 }, rco);
                    if (raycast_hit && raycast_hit.block) {
                        let block_above = player.dimension.getBlock({ x: raycast_hit.block.location.x, y: raycast_hit.block.location.y + 2, z: raycast_hit.block.location.z });
                        if (block_above && (block_above.permutation.matches("minecraft:air") || block_above.permutation.matches("minecraft:light_block"))) {
                            let location = { x: raycast_hit.block.location.x, y: raycast_hit.block.location.y + 1, z: raycast_hit.block.location.z };
                            player.teleport(location);
                            let successMessage = {
                                translate: FSLocalizedString.localize("chat.teleport_success", "§aSuccess!§r You have been teleported to below the camera.", "Teleport success message")
                            };
                            player.sendMessage(successMessage);
                            player.playSound("fs.sbunk.chat_ping");
                            if (viewAfterTeleport) {
                                system.runTimeout(() => {
                                    PlayerHelper.becomeCamera(player, loc_data);
                                }, teleport_timeout);
                            }
                        }
                        else {
                            player.sendMessage({ translate: error_message });
                            player.playSound("fs.sbunk.chat_ping");
                            let prev_loc = FSDynamicProperty.getVector3(player, "prev_loc");
                            player.teleport(prev_loc);
                            FSDynamicProperty.clear(player, "prev_loc");
                        }
                    }
                }, teleport_timeout);
            }
            catch (error) {
                player.sendMessage({ translate: error_message });
                player.playSound("fs.sbunk.chat_ping");
            }
        }
        else {
            player.sendMessage({ translate: error_message });
            player.playSound("fs.sbunk.chat_ping");
        }
    }
    static becomeNextCamera(player) {
        const current_access_level = FSDynamicProperty.getString(player, "camera_access_level");
        const camera_locs = CameraManager.sharedInstance().getLocs([current_access_level]);
        const camera_id = FSDynamicProperty.getString(player, "camera_id");
        let current_index = camera_locs.findIndex(loc => loc.id === camera_id);
        let next_index = current_index + 1;
        if (next_index >= camera_locs.length) {
            next_index = 0;
        }
        let next_loc = camera_locs[next_index];
        PlayerHelper.becomeCamera(player, next_loc);
    }
    static becomeCamera(player, loc) {
        const camera_max_chunks = 16;
        const camera_max_distance = 16 * camera_max_chunks;
        let eqo = {
            type: "57d_sbunk:camera",
            maxDistance: camera_max_distance,
            location: player.location
        };
        let cameras = player.dimension.getEntities(eqo);
        let camera = cameras.find(camera => {
            return camera.id === loc.id;
        });
        if (!camera || !camera.isValid()) {
            const form = new mcui.ActionFormData();
            form.title({ translate: FSLocalizedString.localize("ui.camera_connection_error.title", "Camera Connection Error", "Title for camera connection error") });
            form.body({ translate: FSLocalizedString.localize("ui.camera_connection_error.body", "This camera is out of range. Would you like to teleport closer to the camera?", "Body text for camera connection error") });
            form.button({ translate: FSLocalizedString.localize("ui.camera_connection_error.teleport", "Teleport to Camera", "Button text for teleporting to camera") });
            form.button({ translate: FSLocalizedString.localize("ui.camera_connection_error.stay_here", "Stay Here", "Button text for staying in current location") });
            form.show(player).then(resp => {
                if (resp.canceled) {
                    return;
                }
                let selection = resp.selection || 0;
                switch (selection) {
                    case 0: {
                        PlayerHelper.teleportToCameraWithId(player, loc.id, true);
                        break;
                    }
                }
            });
            return;
        }
        let cameraLocation = {
            x: loc.location.x,
            y: loc.location.y,
            z: loc.location.z
        };
        if (loc.placement === "floor") {
            cameraLocation.y += 0.75;
        }
        const cameraRotation = loc.rotation;
        FSDynamicProperty.setNumber(player, "camera_rot", 0);
        FSDynamicProperty.setNumber(player, "camera_dir", 0);
        FSDynamicProperty.setString(player, "camera_access_level", FSEntityPerms.getEntityPermission(camera));
        FSDynamicProperty.setString(player, "camera_id", camera.id);
        FSDynamicProperty.setBoolean(player, "is_camera", true);
        FSDynamicProperty.setVector3(player, "camera_loc", cameraLocation);
        FSDynamicProperty.setNumber(player, "camera_rot_y", cameraRotation);
        FSDynamicProperty.setString(player, "camera_name", loc.name);
        FSDynamicProperty.setString(player, "camera_placement", loc.placement);
        player.playSound("fs.sbunk.camera_open");
        player.camera.setCamera("minecraft:free", { location: cameraLocation, rotation: { x: 0, y: 0 }, easeOptions: { easeTime: 1, easeType: EasingType.Linear } });
    }
    static giveBook(player) {
        let command = "/structure load 57d_sbunk:book_void ~ ~ ~";
        player.runCommand(command);
    }
    static seenByCamera(player, camera) {
        let timeout = FSDynamicProperty.getNumber(player, `${camera.id}_timeout`);
        if (timeout <= 0) {
            timeout = 50;
            FSDynamicProperty.setNumber(player, `${camera.id}_timeout`, timeout);
            FSEntityPerms.sendPlayerAlertForMatchingEntityPermissions(camera, `Player <player_name> seen by <entity_name>.`, FSMessageType.AlertCamera);
            let customName = FSEntityPerms.getEntityCustomName(camera, true, false);
            JigComputer.sharedInstance().sendEmail(camera.typeId, customName, "Player spotted", `${player.name} was spotted by ${customName}.`); 
        }
    }
    static tickCameraTimeout(player, camera) {
        let timeout = FSDynamicProperty.getNumber(player, `${camera.id}_timeout`);
        timeout--;
        FSDynamicProperty.setNumber(player, `${camera.id}_timeout`, timeout);
        if (timeout <= 0) {
            FSDynamicProperty.clear(player, `${camera.id}_timeout`);
        }
    }
}

//# sourceMappingURL=../../../_SBUNK_BPDebug/fs_sbunk/PlayerHelper.js.map
