"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.opaMenusResolver = void 0;
const auth_base_1 = require("@things-factory/auth-base");
const menu_base_1 = require("@things-factory/menu-base");
const typeorm_1 = require("typeorm");
exports.opaMenusResolver = {
    async opaMenus(_, _params, context) {
        var _a, _b, _c, _d;
        let menus = [];
        if (((_b = (_a = context === null || context === void 0 ? void 0 : context.state) === null || _a === void 0 ? void 0 : _a.domain) === null || _b === void 0 ? void 0 : _b.id) && ((_d = (_c = context === null || context === void 0 ? void 0 : context.state) === null || _c === void 0 ? void 0 : _c.user) === null || _d === void 0 ? void 0 : _d.id)) {
            try {
                const qb = (0, typeorm_1.getRepository)(auth_base_1.User).createQueryBuilder('USER');
                const user = await qb
                    .leftJoinAndSelect('USER.roles', 'ROLES')
                    .leftJoinAndSelect('ROLES.domain', 'ROLES_DOMAIN')
                    .where('USER.id = :userId', { userId: context.state.user.id })
                    .andWhere('ROLES_DOMAIN.id = :domainId', { domainId: context.state.domain.id })
                    .getOne();
                // get menus which are non-restricted by any role.
                menus.push(...(await getNonRestrictedMenus(context.state.domain)));
                const userRoleIds = user.roles.map((role) => role.id);
                let restrictedMenus = [];
                if (userRoleIds === null || userRoleIds === void 0 ? void 0 : userRoleIds.length) {
                    // get menus which are restricted by role ()
                    restrictedMenus = [...(await getRestrictedMenus(userRoleIds, context.state.domain))];
                }
                const restrictedMenuIds = restrictedMenus.map((restrictedMenu) => restrictedMenu.id);
                menus.forEach(menu => {
                    const idx = restrictedMenuIds.indexOf(menu.id);
                    if (idx !== -1) {
                        menu.children = Array.from(new Set([...restrictedMenus[idx].children, ...menu.children]));
                    }
                });
                return menus.filter((groupMenu) => { var _a; return (_a = groupMenu === null || groupMenu === void 0 ? void 0 : groupMenu.children) === null || _a === void 0 ? void 0 : _a.length; });
            }
            catch (e) {
                throw e;
            }
        }
    }
};
async function getNonRestrictedMenus(domain) {
    const menus = await (0, typeorm_1.getRepository)(menu_base_1.Menu).find({
        where: { domain, hiddenFlag: false, menuType: 'MENU' },
        relations: ['parent', 'children', 'children.roles'],
        order: { rank: 'ASC' }
    });
    menus.forEach(menu => {
        menu.children = menu.children.filter(child => { var _a; return !child.hiddenFlag && !((_a = child.roles) === null || _a === void 0 ? void 0 : _a.length); });
    });
    return menus;
}
async function getRestrictedMenus(roleIds, domain) {
    const menus = await (0, typeorm_1.getRepository)(menu_base_1.Menu).find({
        where: { domain, hiddenFlag: false, menuType: 'MENU' },
        relations: ['parent', 'children', 'children.roles'],
        order: { rank: 'ASC' }
    });
    const userRoles = await (0, typeorm_1.getRepository)(auth_base_1.Role).find({ where: { domain, id: (0, typeorm_1.In)(roleIds) } });
    menus.forEach(menu => {
        menu.children = menu.children.filter(child => {
            var _a;
            if (child.hiddenFlag) {
                return false; // Exclude child if hiddenFlag is true
            }
            const childRoleIds = ((_a = child.roles) === null || _a === void 0 ? void 0 : _a.map(role => role.id)) || [];
            return userRoles.find(role => childRoleIds.includes(role.id)) || false;
        });
    });
    return menus;
}
//# sourceMappingURL=opa-menus.js.map