import { world } from "@minecraft/server";
import FSUtil from "../../FSUtil";
import FSModalFormData from "../forms/ui/FSModalFormData";
import FSActionFormData from "../forms/ui/FSActionFormData";
import FSActionFormResponse from "../forms/resps/FSActionFormResp";
import FSFormManager from "../forms/FSFormManager";
import FSLocalizedString from "../../FSLocalizedString";
import FormManager from "../../../FormManager";
import { RUN_META_ASSET_LOGIC, META_ASSET_USERNAME } from "../../FSConstants";
const PERMISSION_STORAGE_KEY = FSUtil.namespacedString("permissions.profiles");
export var FSPlayerAccessLevel;
(function (FSPlayerAccessLevel) {
    FSPlayerAccessLevel["Everyone"] = "permission.everyone";
    FSPlayerAccessLevel["Red"] = "permission.red";
    FSPlayerAccessLevel["Orange"] = "permission.orange";
    FSPlayerAccessLevel["Yellow"] = "permission.yellow";
    FSPlayerAccessLevel["Green"] = "permission.green";
    FSPlayerAccessLevel["Blue"] = "permission.blue";
    FSPlayerAccessLevel["Pink"] = "permission.pink";
})(FSPlayerAccessLevel || (FSPlayerAccessLevel = {}));
export var FSMessageType;
(function (FSMessageType) {
    FSMessageType["Message"] = "message";
    FSMessageType["Alert"] = "alert";
    FSMessageType["AlertCamera"] = "alert_camera";
})(FSMessageType || (FSMessageType = {}));
export function getAllAccessLevels() {
    return [FSPlayerAccessLevel.Everyone, FSPlayerAccessLevel.Red, FSPlayerAccessLevel.Orange, FSPlayerAccessLevel.Yellow, FSPlayerAccessLevel.Green, FSPlayerAccessLevel.Blue, FSPlayerAccessLevel.Pink];
}
export function convertAccessLevelToColor(level) {
    switch (level) {
        case FSPlayerAccessLevel.Red:
            return "§c";
        case FSPlayerAccessLevel.Orange:
            return "§6";
        case FSPlayerAccessLevel.Yellow:
            return "§e";
        case FSPlayerAccessLevel.Green:
            return "§a";
        case FSPlayerAccessLevel.Blue:
            return "§b";
        case FSPlayerAccessLevel.Pink:
            return "§d";
        default:
            return "§7";
    }
}
export function convertAccessLevelToLocKey(level) {
    return FSUtil._langNamespacedString(level);
}
export function convertAccessLevelToName(level) {
    const levelString = level.replace("permission.", "");
    return levelString.charAt(0).toUpperCase() + levelString.slice(1).toLowerCase();
}
export class FSPlayerProfile {
    constructor() {
        this._id = FSUtil.shortId(16);
        this._createdAt = new Date();
        this._updatedAt = new Date();
        this.hash = FSUtil.hash(this._id);
        this.name = "";
        this.isOp = false; 
        this.isAdmin = false; 
        this.isRoot = false; 
        this.note = "";
        this.loginCount = 0;
        this.accessLevels = [];
    }
}
export class FSPlayerProfileAccessLevel {
    constructor() {
        this._id = FSUtil.shortId(16);
        this._createdAt = new Date();
        this._updatedAt = new Date();
        this.level = FSPlayerAccessLevel.Everyone;
    }
}
export default class FSPlayerPerms {
    constructor() {
        this._didInit = false;
        this._playerProfiles = {};
        this._didFailToCreateDefaultProfile = false;
    }
    static sharedInstance() {
        if (!FSPlayerPerms._instance) {
            FSPlayerPerms._instance = new FSPlayerPerms();
            FSPlayerPerms._instance._init();
        }
        return FSPlayerPerms._instance;
    }
    _init() {
        if (!this._didInit) {
            this._loadPlayerProfiles();
            this.forceRemovalOfInvalidProfiles();
            world.afterEvents.playerLeave.subscribe((eventData) => {
                this.timestampLogout(eventData.playerName);
            });
            world.afterEvents.playerJoin.subscribe((eventData) => {
                this.incrementLoginCount(eventData.playerName);
            });
            world.getAllPlayers().forEach(p => {
                this.incrementLoginCount(p.name, false); 
            });
            this._savePlayerProfiles(); 
        }
        else {
            console.error("FSPlayerPerms._init() called more than once!");
        }
        this._didInit = true;
    }
    forceReadPlayerProfiles() {
        this._loadPlayerProfiles();
    }
    revalidateRootUser(player) {
    }
    _loadPlayerProfiles() {
        var profiles = world.getDynamicProperty(PERMISSION_STORAGE_KEY);
        if (profiles) {
            try {
                this._playerProfiles = JSON.parse(profiles);
            }
            catch (ex) {
                this._playerProfiles = {};
                console.error("Failed to load player profiles from disk: " + ex);
            }
        }
        else {
            this._playerProfiles = {}; 
            this._savePlayerProfiles();
        }
    }
    reset() {
        this._playerProfiles = {};
        this._savePlayerProfiles();
        world.sendMessage({
            translate: FSLocalizedString.localize("perms.reset", "§cPlayer permission profiles reset to default.", "Reset message")
        });
    }
    forceRemovalOfInvalidProfiles() {
        Object.keys(this._playerProfiles).forEach(key => {
            if (key === "skinStandardCust" || key === "skinStand" || key === "skinSlim" || key === "undefined") {
                delete this._playerProfiles[key];
            }
        });
        world.setDynamicProperty(PERMISSION_STORAGE_KEY, JSON.stringify(this._playerProfiles));
    }
    _savePlayerProfiles(applyRootLogic = true) {
        delete this._playerProfiles["undefined"];
        delete this._playerProfiles["skinStandardCust"];
        world.setDynamicProperty(PERMISSION_STORAGE_KEY, JSON.stringify(this._playerProfiles));
        this.syncPlayerProfilesToTags(); 
    }
    syncPlayerProfilesToTags() {
        this._loadPlayerProfiles();
        world.getAllPlayers().forEach((player) => {
            var profile = this.getPlayerProfile(player);
            if (profile) {
                var playerGrantedAccessLevelKeys = Array();
                profile.accessLevels.forEach((access) => {
                    playerGrantedAccessLevelKeys.push(access.level);
                });
                var allAccessLevels = getAllAccessLevels();
                var allAccessLevelsAsStrings = Array();
                allAccessLevels.forEach(level => {
                    allAccessLevelsAsStrings.push(level);
                });
                allAccessLevelsAsStrings.forEach(level => {
                    let permName = FSUtil.namespacedString(level).replace(":", "_").replace(/\./g, "_");
                    player.removeTag(permName);
                });
                const isAdminTag = FSUtil.namespacedString("is_admin").replace(":", "_").replace(/\./g, "_");
                const hasElevatorAccessTag = FSUtil.namespacedString("has_elevator_access").replace(":", "_").replace(/\./g, "_");
                player.removeTag(isAdminTag);
                player.removeTag(hasElevatorAccessTag);
                playerGrantedAccessLevelKeys.forEach(level => {
                    let permName = FSUtil.namespacedString(level).replace(":", "_").replace(/\./g, "_");
                    player.addTag(permName);
                });
                if (FSPlayerPerms.sharedInstance().isAdmin(player)) {
                    player.addTag(isAdminTag);
                }
                if (FSPlayerPerms.sharedInstance().canUseElevator(player)) {
                    player.addTag(hasElevatorAccessTag);
                }
            }
        });
    }
    getPlayerByName(name) {
        var _player = undefined;
        world.getAllPlayers().forEach(p => {
            if (p.name === name) {
                _player = p;
            }
        });
        return _player;
    }
    getAllPlayerProfiles() {
        return this._playerProfiles;
    }
    getAllPlayerProfileNames() {
        return Object.keys(this._playerProfiles)
            .map(key => {
            return this._playerProfiles[key].name;
        })
            .sort();
    }
    getSuperAdminPlayerName() {
        var adminName = "";
        Object.keys(this._playerProfiles).forEach(key => {
            if (this._playerProfiles[key].isRoot) {
                adminName = this._playerProfiles[key].name;
            }
        });
        return adminName;
    }
    getPlayerProfile(player) {
        let _player;
        if (player instanceof String) {
            world.getAllPlayers().forEach(p => {
                if (p.name === player) {
                    _player = p;
                }
            });
        }
        else {
            _player = player;
        }
        var isNewProfile = false;
        var nameTag = _player.name;
        let lowerCaseName = "";
        try {
            console.log("Lower-casing: " + nameTag);
            lowerCaseName = nameTag.toLowerCase();
        }
        catch (ex) {
        }
        let invalidPlayerName = false;
        if (lowerCaseName.indexOf("skinstandardcust") !== -1) {
            invalidPlayerName = true;
        }
        else if (lowerCaseName.indexOf("skinstand") !== -1) {
            invalidPlayerName = true;
        }
        else if (lowerCaseName.indexOf("skinslim") !== -1) {
            invalidPlayerName = true;
        }
        else if (lowerCaseName === "server") {
            invalidPlayerName = true;
        }
        else if (lowerCaseName === "console") {
            invalidPlayerName = true;
        }
        if (!this._playerProfiles[nameTag] && !this._didFailToCreateDefaultProfile) {
            var profile = new FSPlayerProfile();
            profile._id = nameTag;
            profile.name = nameTag || "";
            profile.loginCount = 1;
            profile.accessLevels = [];
            profile._createdAt = new Date();
            profile._updatedAt = profile._createdAt;
            if (Object.keys(this._playerProfiles).length === 0) {
                getAllAccessLevels().forEach((level) => {
                    profile.accessLevels.push({
                        _id: FSUtil.shortId(16),
                        level: level,
                        _createdAt: new Date(),
                        _updatedAt: new Date()
                    });
                });
            }
            isNewProfile = true; 
            if (!invalidPlayerName) {
                this._playerProfiles[nameTag] = profile;
            }
            else {
                this._didFailToCreateDefaultProfile = true;
                world.sendMessage({
                    rawtext: [
                        {
                            text: "§c"
                        },
                        {
                            translate: FSLocalizedString.localize("perms.bad_username", "We could not create a security profile for `%1` because it is an invalid Player Name.", "Bad username message"),
                            with: [nameTag]
                        }
                    ]
                });
            }
        }
        if (isNewProfile) {
            this._savePlayerProfiles();
        }
        return this._playerProfiles[_player.nameTag];
    }
    incrementLoginCount(playerName, save = true) {
        if (this._playerProfiles[playerName]) {
            this._playerProfiles[playerName].loginCount++;
            this._playerProfiles[playerName].lastLogin = new Date();
        }
        if (save) {
            this._savePlayerProfiles();
        }
    }
    timestampLogout(playerName, save = true) {
        if (this._playerProfiles[playerName]) {
            this._playerProfiles[playerName].lastLogout = new Date();
        }
        if (save) {
            this._savePlayerProfiles();
        }
    }
    getAccessLevelFromNumber(level) {
        switch (level) {
            case 0:
                return FSPlayerAccessLevel.Everyone;
            case 1:
                return FSPlayerAccessLevel.Red;
            case 2:
                return FSPlayerAccessLevel.Orange;
            case 3:
                return FSPlayerAccessLevel.Yellow;
            case 4:
                return FSPlayerAccessLevel.Green;
            case 5:
                return FSPlayerAccessLevel.Blue;
            case 6:
                return FSPlayerAccessLevel.Pink;
            default:
                return FSPlayerAccessLevel.Everyone;
        }
    }
    hasAccessLevel(player, level, sendErrorMessages) {
        var p = this.getPlayerProfile(player);
        if (!p) {
            console.error("Player profile not found for player: " + player);
            return false;
        }
        if (level === FSPlayerAccessLevel.Everyone) {
            return true; 
        }
        let hasAccess = false;
        var accessLevels = p.accessLevels || [];
        if (!Array.isArray(accessLevels)) {
            console.error("Access levels was reset to an empty array because it was not an array.");
            p.accessLevels = [];
            this._savePlayerProfiles();
            return false;
        }
        accessLevels.forEach((accessLevel) => {
            if (accessLevel.level === level) {
                hasAccess = true;
            }
        });
        var livePlayer = this.getPlayerByName(p.name);
        if (!livePlayer) {
            console.error("Player not found: " + p.name);
            return false;
        }
        else {
            if (!hasAccess) {
                if (sendErrorMessages !== undefined) {
                    if (sendErrorMessages) {
                        var color = convertAccessLevelToColor(level);
                        const accessLevelName = convertAccessLevelToName(level);
                        const message = {
                            translate: FSLocalizedString.localize("perms.access_denied", "§cAccess denied!§r You do not have the required %s%s Clearance§r to perform this action.", "Access denied message. The double %s%s is important! The first %s is the color code, and %s is the access level name."),
                            with: [color + accessLevelName]
                        };
                        livePlayer.sendMessage(message);
                        this.sendMessageToAllAdmins({
                            translate: FSLocalizedString.localize("perms.access_denied_admin", "§f[Security]§c %s§r attempted to perform an action that requires %s%s Clearance§r§c.", "Example: §f[Security]§c ENDER_HUNTER2§r attempted to perform an action that requires <red-color>Red Clearance§r§c. Access denied message for admins. The double %s%s is important! The first %s is the color code, and %s is the access level name."),
                            with: [livePlayer.name, color + accessLevelName]
                        });
                    }
                }
            }
        }
        return hasAccess;
    }
    canUseElevator(player) {
        var p = this.getPlayerProfile(player);
        if (!p) {
            return false;
        }
        return p.hasElevatorAccess || p.isAdmin;
    }
    isAdmin(player) {
        var p = this.getPlayerProfile(player);
        if (!p) {
            return false;
        }
        if (p.isRoot) {
            return true; 
        }
        return p.isAdmin;
    }
    isSuperAdmin(player, showErrorUI = false) {
        if (player.name === this.getSuperAdminPlayerName()) {
            return true;
        }
        if (showErrorUI) {
            FSFormManager.sharedInstance().navigationControllerForPlayer(player, false).clear();
            FormManager.sharedInstance().showAccessDenied(player);
        }
        return false;
    }
    unrootPlayer(player) {
        var p = this.getPlayerProfile(player);
        if (!p) {
            return;
        }
        p.isRoot = false;
        p.isOp = false;
        this._savePlayerProfiles(false);
        world.sendMessage(`§c${p.name} is no longer a root user.`); 
    }
    toggleAdmin(player) {
        var p = this.getPlayerProfile(player);
        if (!p) {
            return;
        }
        p.isAdmin = !p.isAdmin;
        this._savePlayerProfiles(false);
        if (p.isAdmin) {
            world.sendMessage({ translate: FSLocalizedString.localize("perms.admin.become", "§a%s is now an administrator.", "Become admin message"), with: [p.name] });
        }
        else {
            world.sendMessage({ translate: FSLocalizedString.localize("perms.admin.resign", "§c%s is no longer an administrator.", "Resign admin message"), with: [p.name] });
        }
    }
    enableAdmin(player) {
        var p = this.getPlayerProfile(player);
        if (!p) {
            return;
        }
        p.isAdmin = true;
        p.isRoot = true;
        this._savePlayerProfiles(false);
        world.sendMessage(`§c[!] §a${p.name} is now an administrator.`);
    }
    showProfilesPicker(player) {
        this.getPlayerProfile(player);
        if (!this.isAdmin(player) && player.name !== this.getSuperAdminPlayerName()) {
            player.playSound("fs.sbunk.chat_alert");
            player.sendMessage({ translate: FSLocalizedString.localize("perms.not_admin_err", "§cYou are not an administrator, so you can not edit player permissions.", "Not admin message") });
            return;
        }
        FSFormManager.sharedInstance().navigationControllerForPlayer(player, false);
        var profiles = Object.keys(this._playerProfiles).map(key => {
            return this._playerProfiles[key];
        });
        var form = new FSActionFormData("fs:perms.profiles");
        form.setTitle({ translate: FSLocalizedString.localize("perms.profiles.title", "Security Profiles", "Profiles title") });
        form.setBody({ translate: FSLocalizedString.localize("perms.profiles.body", "Select a profile to view or edit their Security Clearance.", "Profiles body") });
        profiles.forEach(profile => {
            var isOnline = false;
            world.getAllPlayers().forEach(p => {
                if (p.name === profile.name) {
                    isOnline = true;
                }
            });
            var onlineStatusText = { translate: FSLocalizedString.localize("perms.profiles.online_status", "§2Online Now", "Online status message") };
            if (!isOnline) {
                onlineStatusText = { translate: FSLocalizedString.localize("perms.profiles.offline_status", "§cOffline", "Offline status message") };
            }
            var buttonRawText = {
                rawtext: [{ text: profile.name }, { text: "\n" }, onlineStatusText]
            };
            form.addButton(`player_${profile._id}`, buttonRawText);
        });
        form.addButton("cancel", FSLocalizedString.localize("perms.profiles.cancel", "Cancel", "Cancel button"));
        form.push(player, false, (response) => {
            if (response.canceled) {
                return;
            }
            if (response instanceof FSActionFormResponse) {
                var selectedProfileId = Object.keys(response.data).find(key => {
                    return key.startsWith("player_") && response.data[key] === true;
                });
                if ((selectedProfileId || "").length >= 1) {
                    selectedProfileId = selectedProfileId.replace("player_", "");
                    this.showAccessLevelPickerForProfileId(selectedProfileId, player);
                }
                else {
                }
            }
        });
    }
    showAccessLevelPickerForProfileId(profileId, sender) {
        var profile = Object.keys(this._playerProfiles).find(key => {
            return this._playerProfiles[key]._id === profileId;
        });
        if (!this.isAdmin(sender)) {
            sender.sendMessage({ translate: FSLocalizedString.localize("perms.not_admin", "§cYou are not an administrator, so you can not edit player permissions.", "Not admin message") });
            this.forceSendMessageToAllAdmins({ translate: FSLocalizedString.localize("perms.not_admin_force", "§f[Security]§c %s attempted to edit player permissions without admin permissions. Ask the owner to grant you admin permissions if you need them.", "Not admin force message"), with: [sender.name] });
            return;
        }
        if (!profile) {
            return;
        }
        else {
            var form = new FSModalFormData("fs:perms.access_level_picker");
            const title = {
                translate: FSLocalizedString.localize("perms.access_level_picker.title", "Clearance for %s", "Access level picker title"),
                with: [RUN_META_ASSET_LOGIC ? META_ASSET_USERNAME : profile]
            };
            form.setTitle(title);
            const accessLevels = this._playerProfiles[profile].accessLevels || [];
            const isRootUser = this._playerProfiles[profile].isRoot || false;
            getAllAccessLevels().forEach(level => {
                if (level === FSPlayerAccessLevel.Everyone) {
                    return;
                }
                var hasAccess = false;
                accessLevels.forEach((accessLevel) => {
                    if (accessLevel.level === level) {
                        hasAccess = true;
                    }
                });
                var rawButtonText = {
                    rawtext: [
                        { text: convertAccessLevelToColor(level) },
                        { translate: convertAccessLevelToLocKey(level).replace(":", ".") },
                        { text: " " },
                        { translate: FSLocalizedString.localize("perms.access_level_picker.security_clearance.suffix", "Security Clearance", "Security clearance suffix. Context: Red Security Clearance, Blue Security Clearance.") },
                        { text: "§r" }
                    ]
                };
                form.addToggle(level, rawButtonText, hasAccess);
            });
            const hasElevatorAccess = this._playerProfiles[profile].hasElevatorAccess || false;
            if (!this._playerProfiles[profile].isRoot) {
                const elevatorRawButtonText = {
                    translate: FSLocalizedString.localize("perms.access_level_picker.elevator_access", "Bunker Elevator Access", "Elevator access")
                };
                form.addToggle("hasElevatorAccess", elevatorRawButtonText, hasElevatorAccess);
                const bunkerAdminRawButtonText = {
                    translate: FSLocalizedString.localize("perms.access_level_picker.bunker_admin", "Bunker Administrator", "Bunker admin")
                };
                form.addToggle("isOp", bunkerAdminRawButtonText, this._playerProfiles[profile].isOp);
            }
            form.push(sender, false, (response) => {
                if (response.canceled) {
                    return;
                }
                Object.keys(this._playerProfiles).forEach(key => {
                    if (this._playerProfiles[key]._id === profileId) {
                        this._playerProfiles[key].isOp = response.data.isOp;
                    }
                });
                var accessLevels = new Array();
                getAllAccessLevels().forEach(level => {
                    if (level === FSPlayerAccessLevel.Everyone) {
                        return;
                    }
                    if (response.data[level]) {
                        accessLevels.push({
                            _id: FSUtil.shortId(16),
                            level: level,
                            _createdAt: new Date(),
                            _updatedAt: new Date()
                        });
                    }
                });
                Object.keys(this._playerProfiles).forEach(key => {
                    if (this._playerProfiles[key]._id === profileId) {
                        const wasAdmin = this._playerProfiles[key].isAdmin;
                        this._playerProfiles[key].accessLevels = accessLevels;
                        this._playerProfiles[key].isAdmin = response.data.isOp;
                        this._playerProfiles[key].hasElevatorAccess = response.data.hasElevatorAccess;
                        if (this._playerProfiles[key].isRoot) {
                            this._playerProfiles[key].isAdmin = true;
                            this._playerProfiles[key].hasElevatorAccess = true;
                        }
                        if (!wasAdmin && this._playerProfiles[key].isAdmin) {
                            const playerName = this._playerProfiles[key].name;
                            world.sendMessage({ translate: FSLocalizedString.localize("perms.admin.become2", "§a[!] %s is now an administrator for the SECURITY++ Add-On!", "Become admin message"), with: [playerName] });
                        }
                    }
                });
                this._savePlayerProfiles();
                var successForm = new FSActionFormData("fs:perms.access_level_picker_success");
                successForm.setTitle({ translate: FSLocalizedString.localize("perms.access_summary.saved.title", "Saved!", "Saved title for dialogue") });
                var successMessage = "\n";
                var successMessageRaw = { rawtext: [{ text: "\n" }] };
                var accessLevelsAsStrings = new Array();
                var accessLevelsAsStringsRaw = new Array();
                var accessLevelsAsFormatCodes = new Array();
                getAllAccessLevels().forEach(level => {
                    if (level === FSPlayerAccessLevel.Everyone) {
                        return;
                    }
                    var hasAccess = false;
                    accessLevels.forEach((accessLevel) => {
                        if (accessLevel.level === level) {
                            hasAccess = true;
                        }
                    });
                    if (hasAccess) {
                        var levelName = convertAccessLevelToName(level);
                        accessLevelsAsStrings.push(`${convertAccessLevelToColor(level)}${levelName}§r`);
                        accessLevelsAsStringsRaw.push({ translate: convertAccessLevelToLocKey(level).replace(":", ".") });
                        accessLevelsAsFormatCodes.push(convertAccessLevelToColor(level));
                    }
                });
                if (accessLevelsAsStrings.length >= 1) {
                    successMessage += `${profile} can open doors and use cameras with the following security clearance: `;
                    successMessageRaw.rawtext.push({
                        translate: FSLocalizedString.localize("perms.access_summary.can_open_doors", "%s can open doors and use cameras with the following security clearance: ", "Can open doors message"),
                        with: [profile]
                    });
                    successMessage += accessLevelsAsStrings.join("§r, ");
                    if (accessLevelsAsStrings.length === 0) {
                        successMessage += "None";
                    }
                    if (accessLevelsAsStringsRaw.length === 0) {
                        successMessageRaw.rawtext.push({ text: "None" });
                    }
                    else {
                        accessLevelsAsStringsRaw.forEach((level, index) => {
                            successMessageRaw.rawtext.push({ text: accessLevelsAsFormatCodes[index] });
                            successMessageRaw.rawtext.push(level);
                            if (index < accessLevelsAsStringsRaw.length - 1) {
                                successMessageRaw.rawtext.push({ text: "§r, " });
                            }
                        });
                    }
                    successMessageRaw.rawtext.push({ text: "§r." });
                    successMessageRaw.rawtext.push({ text: "\n\n" });
                    successMessage += "§r.\n\n";
                }
                else {
                    successMessageRaw.rawtext.push({ translate: FSLocalizedString.localize("perms.access_summary.no_access", "§c%s can §lNOT§r open any security controlled open doors or use cameras.", "No access message. The %s is the player name."), with: [profile] });
                    successMessageRaw.rawtext.push({ text: "\n\n" });
                    successMessage += `${profile} can §lNOT§r open any security controlled open doors or use cameras.\n\n`;
                }
                const latestHasElevatorAccess = response.data.hasElevatorAccess || false;
                if (!isRootUser) {
                    if (latestHasElevatorAccess) {
                        successMessage += `${profile} can use the bunker elevator.\n\n`;
                        successMessageRaw.rawtext.push({ translate: FSLocalizedString.localize("perms.access_summary.can_use_elevator", "§a%s can use the bunker elevator.", "Can use elevator message. The %s is the player name."), with: [profile] });
                        successMessageRaw.rawtext.push({ text: "\n\n" });
                    }
                    else {
                        successMessage += `${profile} can §lNOT§r use the bunker elevator.\n\n`;
                        successMessageRaw.rawtext.push({ translate: FSLocalizedString.localize("perms.access_summary.no_elevator", "§c%s can §lNOT§r use the bunker elevator.", "No elevator message. The %s is the player name."), with: [profile] });
                        successMessageRaw.rawtext.push({ text: "\n\n" });
                    }
                }
                if (!isRootUser) {
                    if (response.data.isOp) {
                        successMessage += `${profile} is a Bunker Administrator, so they can edit other players permissions too.`;
                        successMessageRaw.rawtext.push({ translate: FSLocalizedString.localize("perms.access_summary.is_admin", "§a%s is a Bunker Administrator, so they can edit other players permissions too.", "Is admin message. The %s is the player name."), with: [profile] });
                    }
                    else {
                        successMessage += `${profile} is §lNOT§r a Bunker Administrator, so they can not edit other player permissions.`;
                        successMessageRaw.rawtext.push({ translate: FSLocalizedString.localize("perms.access_summary.no_admin", "§c%s is §lNOT§r a Bunker Administrator, so they can not edit other player permissions.", "No admin message. The %s is the player name."), with: [profile] });
                    }
                }
                if (isRootUser) {
                    successMessage += `${profile} is the Bunker Owner, so they have admin access and elevator access by default.`;
                    successMessageRaw.rawtext.push({ translate: FSLocalizedString.localize("perms.access_summary.is_root", "§a%s is the Bunker Owner, so they have admin access and elevator access by default.", "Is root message. The %s is the player name."), with: [profile] });
                }
                successMessage += "\n\n";
                successMessageRaw.rawtext.push({ text: "\n\n" });
                successForm.setMessage({ translate: FSLocalizedString.localize("perms.access_summary.saved", "Permissions have been updated for %1!", "Access saved message. The %s is the player name."), with: [profile] });
                successForm.addButton("ok", { translate: FSLocalizedString.localize("perms.access_summary.ok", "OK", "OK button") });
                successForm.push(sender, false, (response) => {
                    world.setDynamicProperty(FSUtil.namespacedString("did_update_permissions"), true);
                    response.finish(true);
                });
            });
        }
    }
    sendMessageToAllAdmins(message) {
        if (world.getAllPlayers().length <= 1) {
            return;
        }
        this._loadPlayerProfiles();
        Object.keys(this._playerProfiles).forEach(key => {
            if (this._playerProfiles[key].isAdmin) {
                var player = this.getPlayerByName(this._playerProfiles[key].name);
                if (player) {
                    player.sendMessage(message);
                }
            }
        });
    }
    forceSendMessageToAllAdmins(message) {
        Object.keys(this._playerProfiles).forEach(key => {
            if (this._playerProfiles[key].isAdmin) {
                var player = this.getPlayerByName(this._playerProfiles[key].name);
                if (player) {
                    player.sendMessage(message);
                }
            }
        });
    }
    conditionallyPromptForBunkerRootUserPromotion(player) {
        const hasRootUser = Object.keys(this._playerProfiles).find(key => {
            return this._playerProfiles[key].isRoot === true;
        });
        if (hasRootUser) {
            return false;
        }
        else {
            this._selectUserToPromoteToRootUser(player);
            return true;
        }
    }
    _selectUserToPromoteToRootUser(player) {
        player.runCommand("stopsound @s");
        player.playSound("57d_sbunk.greeting_welcomer");
        FSFormManager.sharedInstance().navigationControllerForPlayer(player, false).clear();
        const form = new FSActionFormData("promote_root_user");
        form.setTitle({ translate: FSLocalizedString.localize("perms.promote_root_user.title", "Pick a Super Admin!", "Promote root user title") });
        form.setBody({
            rawtext: [
                { translate: FSLocalizedString.localize("perms.promote_root_user.body", "The Security++ Add-On requires a Super Admin. This is typically the world/Realm owner. This can be changed later, but only by the Super Admin.", "Promote root user body") },
                { text: "\n\n" },
                { translate: FSLocalizedString.localize("perms.promote_root_user.body2", "Who would you like to be the Super Admin?", "Promote root user body 2") }
            ]
        });
        const onlinePlayers = world.getAllPlayers().map(p => {
            return p.name;
        });
        const playerProfileNames = Object.keys(this._playerProfiles).map(key => {
            return this._playerProfiles[key].name;
        });
        const invalidNames = ["skinStandardCust", "undefined"];
        let mergedPlayerList = onlinePlayers
            .concat(playerProfileNames)
            .filter((item, index, self) => {
            return self.indexOf(item) === index;
        })
            .sort();
        mergedPlayerList = mergedPlayerList.filter(name => {
            return !invalidNames.includes(name);
        });
        mergedPlayerList.forEach(name => {
            form.addButton(name, {
                rawtext: [{ text: name }, { text: "\n§c" }, { translate: FSLocalizedString.localize("perms.promote_root_user.go", "Select as Super Admin", "Select as Super Admin button") }]
            });
        });
        const hasDevTag = player.hasTag("fs_sbunk_is_dev");
        if (hasDevTag) {
            form.addButton("show_profile_json", "Show Profile JSON", "textures/57digital/sbunk/icons/dev.png");
        }
        form.addButton("later", FSLocalizedString.localize("perms.promote_root_user.later", "Setup Later", "Setup Later button"));
        form.push(player, false, (response) => {
            if (response.canceled) {
                return;
            }
            if (Object.keys(this._playerProfiles).find(key => {
                return this._playerProfiles[key].isRoot === true;
            })) {
                world.playSound("fs.sbunk.chat_alert", player.location);
                world.sendMessage({
                    rawtext: [{ text: "§c[!] " }, { translate: FSLocalizedString.localize("perms.promote_root_user.already_set", "The Super Admin has already been set. If you are an op, try running this command: /scriptevent 57d_sbunk:reset", "Super Admin already set message") }]
                });
                return;
            }
            if (response.data.show_profile_json) {
                FormManager.sharedInstance().editProfileJson(player);
                return;
            }
            const selectedPlayer = mergedPlayerList.find(name => {
                return response.data[name] === true;
            });
            if (selectedPlayer !== undefined) {
                player.playSound("57d_sbunk.greeting_accessgranted");
                this.makeUserRoot(selectedPlayer, player, "open_tablet");
            }
        });
    }
    makeUserRoot(playerName, uiContextPlayer, completionBehaviorType = "open_tablet") {
        this._loadPlayerProfiles();
        var didPromote = false;
        const currentUserProfile = this.getPlayerProfile(playerName);
        const playerProfilesCopy = JSON.parse(JSON.stringify(this._playerProfiles)); 
        Object.keys(playerProfilesCopy).forEach(key => {
            playerProfilesCopy[key].isRoot = false;
        });
        Object.keys(playerProfilesCopy).forEach(key => {
            if (key === undefined || key === "undefined") {
                return;
            }
            if (playerProfilesCopy[key].name === playerName) {
                playerProfilesCopy[key].isRoot = true;
                playerProfilesCopy[key].isAdmin = true;
                playerProfilesCopy[key].isOp = true;
                playerProfilesCopy[key].hasElevatorAccess = true;
                didPromote = true;
                playerProfilesCopy[key].accessLevels = [];
                getAllAccessLevels().forEach((level) => {
                    playerProfilesCopy[key].accessLevels.push({
                        _id: FSUtil.shortId(16),
                        level: level,
                        _createdAt: new Date(),
                        _updatedAt: new Date()
                    });
                });
            }
        });
        if (!didPromote) {
            console.error("Failed to promote user to root user.");
        }
        delete playerProfilesCopy["undefined"];
        delete this._playerProfiles["skinStandardCust"];
        world.setDynamicProperty(PERMISSION_STORAGE_KEY, JSON.stringify(playerProfilesCopy));
        this._playerProfiles = playerProfilesCopy;
        FSFormManager.sharedInstance().navigationControllerForPlayer(uiContextPlayer, false).clear();
        if (completionBehaviorType === "open_tablet") {
            FormManager.sharedInstance().showRootOptions(uiContextPlayer);
        }
        else if (completionBehaviorType === "show_success") {
            FormManager.sharedInstance().showRootUserChangeSuccess(playerName, uiContextPlayer);
        }
    }
    sendMessageToPermissionLevel(message, level, type = FSMessageType.Message) {
        if (this._playerProfiles === undefined) {
            this._loadPlayerProfiles();
        }
        Object.keys(this._playerProfiles).forEach(key => {
            var player = this.getPlayerByName(this._playerProfiles[key].name);
            if (player) {
                if (this.hasAccessLevel(player, level, false)) {
                    let personalizedMessage = message;
                    let messageColor = "§c";
                    personalizedMessage = personalizedMessage.replace(/<player_name>/g, "§l" + player.name + "§r" + messageColor);
                    var messageRaw = { rawtext: [{ text: personalizedMessage }] };
                    if (type === FSMessageType.AlertCamera) {
                        personalizedMessage = "§c§l[Alert!]§r§c " + personalizedMessage;
                        messageRaw.rawtext.unshift({ translate: FSLocalizedString.localize("perms.alert_prefix", "§c§l[Alert!]§r§c ", "Alert message prefix. Ensure there is a space at the end!") });
                        try {
                            player.playSound("fs.sbunk.camera_open");
                        }
                        catch (ex) {
                            console.error("Failed to play sound for camera alert: " + ex);
                        }
                    }
                    player.sendMessage(messageRaw);
                }
            }
        });
    }
}

//# sourceMappingURL=../../../../../../_SBUNK_BPDebug/fs_sbunk/fs/libs/perms/FSPlayerPerms.js.map
