var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { BaseEngine, RegisterForStartup } from "@memberjunction/core";
import { UUIDsEqual } from "@memberjunction/global";
/**
 * Caching of metadata for dashboards and related data, including permission management
 */
let DashboardEngine = class DashboardEngine extends BaseEngine {
    constructor() {
        super(...arguments);
        this._dashboards = [];
        this._partTypes = [];
        this._dashboardUserPreferences = [];
        this._dashboardCategories = [];
        this._dashboardUserStates = [];
        this._dashboardPermissions = [];
        this._dashboardCategoryPermissions = [];
        this._dashboardCategoryLinks = [];
    }
    /**
     * Returns the global instance of the class. This is a singleton class, so there is only one instance of it in the application. Do not directly create new instances of it, always use this method to get the instance.
     */
    static get Instance() {
        return super.getInstance();
    }
    async Config(forceRefresh, contextUser, provider) {
        const c = [
            {
                Type: 'entity',
                EntityName: "MJ: Dashboard Part Types",
                PropertyName: "_partTypes",
                CacheLocal: true
            },
            {
                Type: 'entity',
                EntityName: 'MJ: Dashboards',
                PropertyName: "_dashboards",
                CacheLocal: true
            },
            {
                Type: 'entity',
                EntityName: 'MJ: Dashboard User Preferences',
                PropertyName: "_dashboardUserPreferences",
                CacheLocal: true
            },
            {
                Type: 'entity',
                EntityName: 'MJ: Dashboard Categories',
                PropertyName: "_dashboardCategories",
                CacheLocal: true
            },
            {
                Type: 'entity',
                EntityName: 'MJ: Dashboard User States',
                PropertyName: "_dashboardUserStates",
                CacheLocal: true
            },
            {
                Type: 'entity',
                EntityName: 'MJ: Dashboard Permissions',
                PropertyName: "_dashboardPermissions",
                CacheLocal: true
            },
            {
                Type: 'entity',
                EntityName: 'MJ: Dashboard Category Permissions',
                PropertyName: "_dashboardCategoryPermissions",
                CacheLocal: true
            },
            {
                Type: 'entity',
                EntityName: 'MJ: Dashboard Category Links',
                PropertyName: "_dashboardCategoryLinks",
                CacheLocal: true
            }
        ];
        await this.Load(c, provider, forceRefresh, contextUser);
    }
    // ========================================
    // Getters for cached data
    // ========================================
    get Dashboards() {
        return this.GetConfigData('_dashboards');
    }
    get DashboardPartTypes() {
        return this.GetConfigData('_partTypes');
    }
    get DashboardUserPreferences() {
        return this.GetConfigData('_dashboardUserPreferences');
    }
    get DashboardCategories() {
        return this.GetConfigData('_dashboardCategories');
    }
    get DashboardUserStates() {
        return this.GetConfigData('_dashboardUserStates');
    }
    get DashboardPermissions() {
        return this.GetConfigData('_dashboardPermissions');
    }
    get DashboardCategoryPermissions() {
        return this.GetConfigData('_dashboardCategoryPermissions');
    }
    get DashboardCategoryLinks() {
        return this.GetConfigData('_dashboardCategoryLinks');
    }
    // ========================================
    // Permission Checking Methods
    // ========================================
    /**
     * Gets the effective permissions for a user on a specific dashboard.
     * Permission priority: Owner > Direct Permission > Category Permission
     * @param dashboardId - The ID of the dashboard
     * @param userId - The ID of the user to check permissions for
     * @returns The effective permissions for the user on this dashboard
     */
    GetDashboardPermissions(dashboardId, userId) {
        const dashboard = this._dashboards.find(d => UUIDsEqual(d.ID, dashboardId));
        // Default: no permissions
        const noPermissions = {
            DashboardID: dashboardId,
            CanRead: false,
            CanEdit: false,
            CanDelete: false,
            CanShare: false,
            IsOwner: false,
            PermissionSource: 'none'
        };
        if (!dashboard) {
            return noPermissions;
        }
        // Check if user is the owner - owners have full permissions
        if (UUIDsEqual(dashboard.UserID, userId)) {
            return {
                DashboardID: dashboardId,
                CanRead: true,
                CanEdit: true,
                CanDelete: true,
                CanShare: true,
                IsOwner: true,
                PermissionSource: 'owner'
            };
        }
        // Check for direct dashboard permission
        const directPermission = this._dashboardPermissions.find(p => UUIDsEqual(p.DashboardID, dashboardId) && UUIDsEqual(p.UserID, userId));
        if (directPermission) {
            return {
                DashboardID: dashboardId,
                CanRead: directPermission.CanRead,
                CanEdit: directPermission.CanEdit,
                CanDelete: directPermission.CanDelete,
                CanShare: directPermission.CanShare,
                IsOwner: false,
                PermissionSource: 'direct'
            };
        }
        // Check for category-level permission (if dashboard has a category)
        if (dashboard.CategoryID) {
            const categoryPermission = this.GetCategoryPermissions(dashboard.CategoryID, userId);
            if (categoryPermission.PermissionSource !== 'none') {
                return {
                    DashboardID: dashboardId,
                    CanRead: categoryPermission.CanRead,
                    CanEdit: categoryPermission.CanEdit,
                    // Category permissions don't grant delete on individual dashboards
                    CanDelete: false,
                    CanShare: false,
                    IsOwner: false,
                    PermissionSource: 'category'
                };
            }
        }
        return noPermissions;
    }
    /**
     * Gets the effective permissions for a user on a specific dashboard category.
     * @param categoryId - The ID of the category
     * @param userId - The ID of the user to check permissions for
     * @returns The effective permissions for the user on this category
     */
    GetCategoryPermissions(categoryId, userId) {
        const category = this._dashboardCategories.find(c => UUIDsEqual(c.ID, categoryId));
        // Default: no permissions
        const noPermissions = {
            CategoryID: categoryId,
            CanRead: false,
            CanEdit: false,
            CanAddRemove: false,
            CanShare: false,
            IsOwner: false,
            PermissionSource: 'none'
        };
        if (!category) {
            return noPermissions;
        }
        // Check if user is the owner - owners have full permissions
        if (UUIDsEqual(category.UserID, userId)) {
            return {
                CategoryID: categoryId,
                CanRead: true,
                CanEdit: true,
                CanAddRemove: true,
                CanShare: true,
                IsOwner: true,
                PermissionSource: 'owner'
            };
        }
        // Check for direct category permission
        const directPermission = this._dashboardCategoryPermissions.find(p => UUIDsEqual(p.DashboardCategoryID, categoryId) && UUIDsEqual(p.UserID, userId));
        if (directPermission) {
            return {
                CategoryID: categoryId,
                CanRead: directPermission.CanRead,
                CanEdit: directPermission.CanEdit,
                CanAddRemove: directPermission.CanAddRemove,
                CanShare: directPermission.CanShare,
                IsOwner: false,
                PermissionSource: 'direct'
            };
        }
        return noPermissions;
    }
    /**
     * Checks if a user can read/view a dashboard
     * @param dashboardId - The ID of the dashboard
     * @param userId - The ID of the user
     * @returns true if the user can read the dashboard
     */
    CanUserReadDashboard(dashboardId, userId) {
        return this.GetDashboardPermissions(dashboardId, userId).CanRead;
    }
    /**
     * Checks if a user can edit a dashboard
     * @param dashboardId - The ID of the dashboard
     * @param userId - The ID of the user
     * @returns true if the user can edit the dashboard
     */
    CanUserEditDashboard(dashboardId, userId) {
        return this.GetDashboardPermissions(dashboardId, userId).CanEdit;
    }
    /**
     * Checks if a user can delete a dashboard
     * @param dashboardId - The ID of the dashboard
     * @param userId - The ID of the user
     * @returns true if the user can delete the dashboard
     */
    CanUserDeleteDashboard(dashboardId, userId) {
        return this.GetDashboardPermissions(dashboardId, userId).CanDelete;
    }
    /**
     * Checks if a user can share a dashboard
     * @param dashboardId - The ID of the dashboard
     * @param userId - The ID of the user
     * @returns true if the user can share the dashboard
     */
    CanUserShareDashboard(dashboardId, userId) {
        return this.GetDashboardPermissions(dashboardId, userId).CanShare;
    }
    /**
     * Gets all dashboards the user has read access to (owned or shared)
     * @param userId - The ID of the user
     * @returns Array of dashboards the user can read
     */
    GetAccessibleDashboards(userId) {
        return this._dashboards.filter(dashboard => this.CanUserReadDashboard(dashboard.ID, userId));
    }
    /**
     * Gets all dashboard category links for a user (shared dashboards linked to their folder structure)
     * @param userId - The ID of the user
     * @returns Array of category links for the user
     */
    GetUserCategoryLinks(userId) {
        return this._dashboardCategoryLinks.filter(link => UUIDsEqual(link.UserID, userId));
    }
    /**
     * Gets the dashboards shared with a specific user (excludes owned dashboards)
     * @param userId - The ID of the user
     * @returns Array of dashboards shared with the user
     */
    GetSharedDashboards(userId) {
        return this._dashboards.filter(dashboard => {
            // Exclude owned dashboards
            if (UUIDsEqual(dashboard.UserID, userId)) {
                return false;
            }
            // Check if user has read permission
            return this.CanUserReadDashboard(dashboard.ID, userId);
        });
    }
    /**
     * Gets the users a dashboard is shared with and their permissions
     * @param dashboardId - The ID of the dashboard
     * @returns Array of permission records for this dashboard
     */
    GetDashboardShares(dashboardId) {
        return this._dashboardPermissions.filter(p => UUIDsEqual(p.DashboardID, dashboardId));
    }
    /**
     * Gets the users a category is shared with and their permissions
     * @param categoryId - The ID of the category
     * @returns Array of permission records for this category
     */
    GetCategoryShares(categoryId) {
        return this._dashboardCategoryPermissions.filter(p => UUIDsEqual(p.DashboardCategoryID, categoryId));
    }
    /**
     * Checks if a user can access a category (view it in their category list).
     * A user can access a category if they:
     * 1. Own the category (category.UserID === userId)
     * 2. Have direct permission on the category
     * @param categoryId - The ID of the category
     * @param userId - The ID of the user
     * @returns true if the user can access the category
     */
    CanUserAccessCategory(categoryId, userId) {
        const permissions = this.GetCategoryPermissions(categoryId, userId);
        return permissions.PermissionSource !== 'none';
    }
    /**
     * Gets all categories the user has access to (owned or shared).
     * Only returns categories the user explicitly owns or has permissions on.
     * @param userId - The ID of the user
     * @returns Array of categories the user can access
     */
    GetAccessibleCategories(userId) {
        return this._dashboardCategories.filter(category => this.CanUserAccessCategory(category.ID, userId));
    }
};
DashboardEngine = __decorate([
    RegisterForStartup()
], DashboardEngine);
export { DashboardEngine };
//# sourceMappingURL=dashboards.js.map