package com.njcn.rdms.module.project.service.datascope;

import cn.hutool.core.collection.CollUtil;
import com.njcn.rdms.module.project.dal.dataobject.member.UserObjectRoleDO;
import com.njcn.rdms.module.project.dal.mysql.member.UserObjectRoleMapper;
import com.njcn.rdms.module.system.api.dept.OrgLeaderApi;
import com.njcn.rdms.module.system.api.permission.PermissionApi;
import com.njcn.rdms.module.system.api.permission.UserVisibilityConfigApi;
import com.njcn.rdms.module.system.api.permission.dto.UserVisibilityConfigRespDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 数据权限 scope 计算实现。3 通道并集 + 超管短路。
 *
 * 设计：docs/superpowers/specs/2026-05-14-object-data-scope-design.md 第 3.3 节
 *
 * 3 通道全接通 + 超管短路：通道 1（自己参与）+ 通道 2（组织负责人反推）+ 通道 3（用户可见性配置）。
 */
@Service
@Slf4j
public class ObjectDataScopeServiceImpl implements ObjectDataScopeService {

    @Resource
    private PermissionApi permissionApi;

    @Resource
    private UserObjectRoleMapper userObjectRoleMapper;
    // channel1 用 Mapper 直接查（同模块）；channel3 在阶段 2 注入跨模块 API

    @Resource
    private OrgLeaderApi orgLeaderApi;

    @Resource
    private UserVisibilityConfigApi userVisibilityConfigApi;

    @Override
    public ObjectDataScope compute(Long userId, String objectType) {
        if (Boolean.TRUE.equals(permissionApi.isSuperAdmin(userId).getCheckedData())) {
            return ObjectDataScope.all();
        }

        Set<Long>   ids = new HashSet<>();
        Set<String> directionCodes = new HashSet<>();

        ids.addAll(computeChannel1(userId, objectType));
        ids.addAll(computeChannel2(userId, objectType));

        UserVisibilityConfigRespDTO cfg = userVisibilityConfigApi.getConfig(userId).getCheckedData();
        if (cfg != null) {
            if ("all".equals(cfg.getType())) {
                return ObjectDataScope.all();   // 短路
            }
            if ("directions".equals(cfg.getType()) && CollUtil.isNotEmpty(cfg.getDirectionCodes())) {
                directionCodes.addAll(cfg.getDirectionCodes());
            }
            // projects 当前不消费（设计文档明示）
        }

        log.info("[ObjectDataScope] user={} type={} ids.size={} directions.size={}",
                userId, objectType, ids.size(), directionCodes.size());

        if (ids.isEmpty() && directionCodes.isEmpty()) {
            return ObjectDataScope.empty();
        }
        return ObjectDataScope.idList(ids, directionCodes);
    }

    Set<Long> computeChannel1(Long userId, String objectType) {
        return userObjectRoleMapper.selectActiveListByObjectTypeAndUserId(objectType, userId).stream()
                .map(UserObjectRoleDO::getObjectId)
                .collect(Collectors.toSet());
    }

    /**
     * 通道 2：组织负责人反推。
     * 通过 OrgLeaderApi 拿到当前用户作为负责人可覆盖的下属 userId 集合，
     * 再查这批下属参与了哪些同类型对象，合并进 ids。
     */
    Set<Long> computeChannel2(Long userId, String objectType) {
        Set<Long> reachableUserIds = orgLeaderApi.getReachableUserIds(userId).getCheckedData();
        if (CollUtil.isEmpty(reachableUserIds)) {
            return Set.of();
        }
        return userObjectRoleMapper.selectListByUserIdsAndObjectType(reachableUserIds, objectType).stream()
                .map(UserObjectRoleDO::getObjectId)
                .collect(Collectors.toSet());
    }
}
