package com.njcn.rdms.module.project.framework.notify;

import com.njcn.rdms.module.project.constant.ObjectRoleConstants;
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.permission.ObjectPermissionApi;
import com.njcn.rdms.module.system.api.permission.dto.ObjectRoleRespDTO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/** 项目 / 产品团队通知接收人解析：仅 active、排除创建者角色、按 userId 取代表角色（经理优先）+ 中文名 */
@Component
public class TeamNotifyRecipientResolver {

    @Resource
    private UserObjectRoleMapper userObjectRoleMapper;
    @Resource
    private ObjectPermissionApi objectPermissionApi;

    public List<TeamRecipient> resolveActiveExcludingCreator(
            String objectType, Long objectId, String creatorRoleCode, String managerRoleCode) {
        // 1. 取对象全部成员行，仅保留有效（active）成员
        List<UserObjectRoleDO> active = userObjectRoleMapper.selectListByObject(objectType, objectId).stream()
                .filter(r -> ObjectRoleConstants.MEMBER_STATUS_ACTIVE.equals(r.getStatus()))
                .collect(Collectors.toList());
        if (active.isEmpty()) {
            return Collections.emptyList();
        }
        // 2. 批量取角色摘要（含 code / 中文名），构建 roleId → 角色 映射
        Set<Long> roleIds = active.stream().map(UserObjectRoleDO::getRoleId).collect(Collectors.toSet());
        List<ObjectRoleRespDTO> roles = objectPermissionApi
                .getObjectRoleList(roleIds, ObjectRoleConstants.ROLE_SCOPE_OBJECT, objectType)
                .getCheckedData();
        if (roles == null || roles.isEmpty()) {
            return Collections.emptyList();
        }
        Map<Long, ObjectRoleRespDTO> roleMap = roles.stream()
                .collect(Collectors.toMap(ObjectRoleRespDTO::getId, Function.identity()));

        // 3. 逐行排除创建者角色行；同时有创建者+其它角色的用户仍按其它角色保留，纯创建者用户被剔除
        List<UserObjectRoleDO> kept = active.stream()
                .filter(r -> {
                    ObjectRoleRespDTO role = roleMap.get(r.getRoleId());
                    return role != null && !creatorRoleCode.equals(role.getCode());
                })
                .collect(Collectors.toList());

        // 4. 按 userId 聚合，取代表角色：经理优先，否则 roleId 升序兜底；保持首次出现顺序
        Map<Long, List<UserObjectRoleDO>> byUser = kept.stream()
                .collect(Collectors.groupingBy(UserObjectRoleDO::getUserId, LinkedHashMap::new, Collectors.toList()));
        List<TeamRecipient> result = new ArrayList<>();
        byUser.forEach((userId, rows) -> {
            UserObjectRoleDO primary = rows.stream()
                    .filter(r -> {
                        ObjectRoleRespDTO role = roleMap.get(r.getRoleId());
                        return role != null && managerRoleCode.equals(role.getCode());
                    })
                    .findFirst()
                    .orElseGet(() -> rows.stream()
                            .min(Comparator.comparing(UserObjectRoleDO::getRoleId))
                            .orElse(rows.get(0)));
            ObjectRoleRespDTO role = roleMap.get(primary.getRoleId());
            result.add(new TeamRecipient(userId, role == null ? "" : role.getName()));
        });
        return result;
    }
}
