const { getCollection } = require('../utils/collection');
const _ = require('lodash');

const PermissionManager = {};

/**
 * 获取用户所属组织ID（包括父组织）
 * @param {string} spaceId 工作区ID
 * @param {string} userId 用户ID
 * @returns {Promise<string[]>} 组织ID数组
 */
const _getUserOrganizationIds = async function (spaceId, userId) {
    const organizationsCollection = await getCollection('organizations');
    const organizations = await organizationsCollection.find(
        {
            space: spaceId,
            users: userId
        },
        {
            projection: { parents: 1 }
        }
    ).toArray();

    const orgIds = new Set();
    organizations.forEach(org => {
        orgIds.add(org._id);
        if (org.parents) {
            org.parents.forEach(parentId => orgIds.add(parentId));
        }
    });

    return Array.from(orgIds);
}

/**
 * 检查添加权限
 * @param {Object} perms 权限对象
 * @param {string} userId 用户ID
 * @param {string[]} orgIds 组织ID数组
 * @param {Set<string>} permissions 权限集合
 */
const _checkAddPermission = function(perms, userId, orgIds, permissions) {
    if (perms.users_can_add?.includes(userId)) {
        permissions.add('add');
        return;
    }

    if (perms.orgs_can_add) {
        const hasPermission = orgIds.some(orgId =>
            perms.orgs_can_add.includes(orgId)
        );
        if (hasPermission) permissions.add('add');
    }
}

/**
 * 检查监控权限
 * @param {Object} perms 权限对象
 * @param {string} userId 用户ID
 * @param {string[]} orgIds 组织ID数组
 * @param {Set<string>} permissions 权限集合
 */
const _checkMonitorPermission= function(perms, userId, orgIds, permissions) {
    if (perms.users_can_monitor?.includes(userId)) {
        permissions.add('monitor');
        return;
    }

    if (perms.orgs_can_monitor) {
        const hasPermission = orgIds.some(orgId =>
            perms.orgs_can_monitor.includes(orgId)
        );
        if (hasPermission) permissions.add('monitor');
    }
}

/**
 * 检查管理权限
 * @param {Object} perms 权限对象
 * @param {string} userId 用户ID
 * @param {string[]} orgIds 组织ID数组
 * @param {Set<string>} permissions 权限集合
 */
const _checkAdminPermission = function (perms, userId, orgIds, permissions) {
    if (perms.users_can_admin?.includes(userId)) {
        permissions.add('admin');
        return;
    }

    if (perms.orgs_can_admin) {
        const hasPermission = orgIds.some(orgId =>
            perms.orgs_can_admin.includes(orgId)
        );
        if (hasPermission) permissions.add('admin');
    }
}

/**
 * 获取用户对流程的权限
 * @param {string} flowId 流程ID
 * @param {string} userId 用户ID
 * @param {Object} [flowDoc] 可选的流程文档（避免重复查询）
 * @returns {Promise<string[]>} 权限数组（可能包含 'add', 'monitor', 'admin'）
 */
PermissionManager.getFlowPermissions = async function(flowId, userId, flowDoc) {
    const flowColl = await getCollection('flows');
    try {
        // 获取流程信息
        let flow = flowDoc;
        if(!flow){
            flow = await flowColl.findOne({_id: flowId}, {
                projection: { space: 1, perms: 1 }
            })
        }

        if (!flow) {
            throw new Error(`Flow not found: ${flowId}`);
        }

        const spaceId = flow.space;
        const myPermissions = new Set();

        // 获取用户所属组织ID（包括父组织）
        const orgIds = await _getUserOrganizationIds(spaceId, userId);

        // 检查流程权限
        if (flow.perms) {
            _checkAddPermission(flow.perms, userId, orgIds, myPermissions);
            _checkMonitorPermission(flow.perms, userId, orgIds, myPermissions);
            _checkAdminPermission(flow.perms, userId, orgIds, myPermissions);
        }

        return Array.from(myPermissions);
    } catch (error) {
        console.error('Error in getFlowPermissions:', error);
        throw error;
    }
}

module.exports = PermissionManager;