package jnpf.authority.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import jnpf.authority.service.FtbPermissionPositionService;
import jnpf.model.authority.dto.permission.OrganizeWithPositionsDTO;
import jnpf.model.personnels.dto.turnover.FtbDepUserDTO;
import jnpf.permission.V2PositionApi;
import jnpf.permission.dto.v2.position.AuthOrganizePositionDTO;
import jnpf.permission.dto.v2.position.AuthPositionUserNodeDTO;
import jnpf.permission.eum.v2.TargetAuthEnums;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.vo.organize.OrganizeAndPositionListVO;
import jnpf.permission.vo.v2.TargetAuthIdsVO;
import jnpf.permission.vo.v2.position.PositionBaseInfoVO;
import jnpf.permission.vo.v2.position.PositionListOrganizeUserVO;
import jnpf.permission.vo.v2.position.PositionListUserVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.service.FtbPersonnelsTurnoverManagementService;
import jnpf.util.UserProvider;
import jnpf.util.auth.V2AuthPermissionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 带权限的岗位管理功能
 *
 * @author Flynn Chan
 * @create 2025-05-07
 */
@Service
@Slf4j
public class FtbPermissionPositionServiceImpl implements FtbPermissionPositionService {
    @Resource
    private V2AuthPermissionUtils authPermissionUtils;
    @Resource
    private V2PositionApi positionApi;
    @Resource
    private FtbPersonnelsTurnoverManagementService turnoverManagementService;

    @Override
    public List<PositionListUserVO> authListPositionTreeUser(List<UserWorkStatusEnums> workStatusEnums, Boolean includeResigned) {
        TargetAuthIdsVO authIdsVO = authPermissionUtils.processAuthIds();
        AuthPositionUserNodeDTO dto = new AuthPositionUserNodeDTO(authIdsVO, UserProvider.getUser().getTenantId());
        if (CollUtil.isEmpty(workStatusEnums)) {
            dto.setWorkStatusEnums(UserWorkStatusEnums.getSelectUserFilterWorkStatusEnums());
        } else {
            dto.setWorkStatusEnums(workStatusEnums);
        }
        dto.setHavaAuth(authIdsVO != null);
        List<PositionListUserVO> vos = positionApi.authListPositionTreeUser(dto).getData();
        //搜索离职的人
        if (includeResigned) {
            FtbDepUserDTO ftbDepUserDTO = new FtbDepUserDTO();
            if (authIdsVO != null) {
                //组织权限
                if (authIdsVO.getTargetAuthEnums().equals(TargetAuthEnums.ORGANIZE)) {
                    ftbDepUserDTO.setOrganizeIds(authIdsVO.getIds());
                }
                //岗位权限
                if (authIdsVO.getTargetAuthEnums().equals(TargetAuthEnums.POSITION)) {
                    ftbDepUserDTO.setPositionIds(authIdsVO.getIds());
                }
                //人员权限
                if (authIdsVO.getTargetAuthEnums().equals(TargetAuthEnums.USER)) {
                    ftbDepUserDTO.setUserIds(authIdsVO.getIds());
                }
            } else {
                ftbDepUserDTO = new FtbDepUserDTO();
            }
            List<UserBoundVO> ftbDepUsers = turnoverManagementService.getInformationAboutTheDepartingPerson(ftbDepUserDTO);
            if (CollUtil.isEmpty(ftbDepUsers)) {
                log.error("没有离职的人,权限参数情况[{}],  离职请求参数情况[{}]", authIdsVO, ftbDepUserDTO);
            } else {
                // 预过滤，去掉 organizeId 或 positionId 为空的
                Map<String, List<UserBoundVO>> usersByPosition = ftbDepUsers.stream()
                        .filter(u -> StrUtil.isNotBlank(u.getOrganizeId()) && StrUtil.isNotBlank(u.getPositionId()))
                        .collect(Collectors.groupingBy(UserBoundVO::getPositionId));
                // 遍历 vos，直接按 positionId 取对应离职人员列表
                vos.forEach(vo -> {
                    List<UserBoundVO> matchedUsers = usersByPosition.get(vo.getId());
                    if (CollUtil.isNotEmpty(matchedUsers)) {
                        vo.getUserList().addAll(matchedUsers);
                    }
                });
            }
        }

        return vos;
    }

    @Override
    public List<PositionBaseInfoVO> authListPositionAuth() {
        TargetAuthIdsVO authIdsVO = authPermissionUtils.processAuthIds();
        AuthPositionUserNodeDTO dto = new AuthPositionUserNodeDTO(authIdsVO, UserProvider.getUser().getTenantId());
        dto.setHavaAuth(authIdsVO != null);
        return positionApi.authListPositionAuth(dto);
    }

    @Override
    public List<PositionListOrganizeUserVO> listPositionOrganizeUser(List<UserWorkStatusEnums> filterUserWorkStatusEnumsList) {
        List<PositionListOrganizeUserVO> vos = positionApi.listPositionOrganizeUserApi(UserProvider.getUser().getTenantId(), filterUserWorkStatusEnumsList);
        if (CollUtil.isNotEmpty(vos)) {
            //搜索离职的人
            FtbDepUserDTO ftbDepUserDTO = new FtbDepUserDTO();
            List<String> positionIds = vos.stream().map(PositionListOrganizeUserVO::getId).collect(Collectors.toList());
            ftbDepUserDTO.setPositionIds(positionIds);
            List<UserBoundVO> ftbDepUsers = turnoverManagementService.getInformationAboutTheDepartingPerson(ftbDepUserDTO);

            if (CollUtil.isNotEmpty(ftbDepUsers)) {
                // 一次性过滤掉 organizeId、positionId 为空的
                List<UserBoundVO> filteredUsers = ftbDepUsers.stream()
                        .filter(u -> StrUtil.isNotBlank(u.getOrganizeId()) && StrUtil.isNotBlank(u.getPositionId()))
                        .collect(Collectors.toList());

                // 构建两层 map：positionId -> organizeId -> List<UserBoundVO>
                Map<String, Map<String, List<UserBoundVO>>> userMap = filteredUsers.stream()
                        .collect(Collectors.groupingBy(
                                UserBoundVO::getPositionId,
                                Collectors.groupingBy(UserBoundVO::getOrganizeId)
                        ));

                // 遍历 vos，直接按 map 获取对应数据
                vos.forEach(vo -> {
                    Map<String, List<UserBoundVO>> organizeMap = userMap.get(vo.getId());
                    if (CollUtil.isEmpty(organizeMap)) {
                        return;
                    }

                    vo.getList().forEach(organizeUserListVO -> {
                        List<UserBoundVO> matchedUsers = organizeMap.get(organizeUserListVO.getId());
                        if (CollUtil.isNotEmpty(matchedUsers)) {
                            organizeUserListVO.getUserList().addAll(matchedUsers);
                        }
                    });
                });
            }

            return vos;
        } else {
            return new ArrayList<>();
        }
    }

    @Override
    public List<OrganizeAndPositionListVO> authOrganizeWithPositions(OrganizeWithPositionsDTO thisDto) {
        TargetAuthIdsVO authIdsVO = authPermissionUtils.processAuthIds();
        AuthOrganizePositionDTO dto = new AuthOrganizePositionDTO(authIdsVO, UserProvider.getUser().getTenantId());
        dto.setOrganizeIds(dto.getOrganizeIds());
        dto.setHavaAuth(authIdsVO != null);
        return positionApi.authOrganizeWithPositions(dto);
    }
}
