import { jsx as _jsx } from "react/jsx-runtime";
import { ErrorBox, useFetch } from "@vertesia/ui/core";
import { useUserSession } from "@vertesia/ui/session";
import { createContext, useContext, useMemo } from "react";
import { isAnyOf } from "./helpers";
export class UserPermissions {
    system_roles; // all roles defined in the system
    roles; // all roles of the current user
    permissions; // all permissions of the current user
    constructor(session, roles) {
        if (!session.authToken) {
            throw new Error('No auth token found in user session');
        }
        this.system_roles = roles;
        const userRoles = new Set(session.authToken.account_roles || []);
        if (session.authToken.project_roles) {
            for (const role of session.authToken.project_roles) {
                userRoles.add(role);
            }
        }
        this.roles = userRoles;
        // build a temporary role to permissions map
        const map = {};
        for (const role of roles) {
            map[role.name] = role.permissions;
        }
        const permissions = new Set();
        for (const role of userRoles) {
            const rolePermissions = map[role];
            if (rolePermissions) {
                for (const permission of rolePermissions) {
                    permissions.add(permission);
                }
            }
        }
        this.permissions = permissions;
    }
    hasPermission(permission) {
        if (typeof permission === 'string') {
            return this.permissions.has(permission);
        }
        else if (isAnyOf(permission)) {
            return permission.some(p => this.permissions.has(p));
        }
        else { // all of
            for (const p of permission) {
                if (!this.permissions.has(p)) {
                    return false;
                }
            }
            return true;
        }
    }
}
const UserPermissionsContext = createContext(undefined);
export { UserPermissionsContext };
export function useUserPermissions() {
    const perms = useContext(UserPermissionsContext);
    if (!perms) {
        throw new Error('UserPermissionContext cannot be used outside UserPermissionProvider');
    }
    return perms;
}
export function UserPermissionProvider({ children }) {
    const session = useUserSession();
    const { data, error, isLoading } = useFetch(() => {
        if (session.user) {
            return session.client.iam.roles.list();
        }
        else {
            return Promise.resolve(undefined);
        }
    }, [session.user]);
    const perms = useMemo(() => {
        if (session.authToken && data && !isLoading) {
            return new UserPermissions(session, data);
        }
        else {
            return undefined;
        }
    }, [session, data, isLoading]);
    if (error) {
        return _jsx(ErrorBox, { title: "Failed to fetch role mappings", children: error.message });
    }
    return perms && (_jsx(UserPermissionsContext.Provider, { value: perms, children: children }));
}
//# sourceMappingURL=UserPermissionsProvider.js.map