package jnpf.util.auth;

import cn.hutool.core.collection.CollUtil;
import jnpf.authority.utils.PermissionsApplicableEnums;
import jnpf.authority.utils.PermissionsApplicableObject;
import jnpf.authority.utils.PermissionsUtils;
import jnpf.base.ActionResult;
import jnpf.cultivate.utils.UserApiV2Util;
import jnpf.permission.V2OrganizeApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.dto.v2.organzie.QueryOrganizeListTargetTypesDTO;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.eum.v2.TargetAuthEnums;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.vo.v2.TargetAuthIdsVO;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.user.UserBoundInfoVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.permission.vo.v2.user.UserPageListVO;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

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

/**
 * 权限校验公共工具
 *
 * @author Flynn Chan
 * @create 2025-05-20
 */
@Component
@Slf4j
public class V2AuthPermissionUtils {
    @Resource
    private PermissionsUtils permissionsUtils;
    @Resource
    private V2OrganizeApi organizeV2Api;
    @Resource
    private V2UserApi userV2Api;

    /**
     * 获取登录人权限范围内的门店id/组织id, null为全部,[]为无,  人的权限都算[]
     */
    public List<String> getLoginUserAuthOrganizeIds() {
        String userId = UserProvider.getLoginUserId();
        //超级管理员也返回null,也获取全部
        if (UserProvider.getUser().getIsAdministrator()) {
            return null;
        }
        PermissionsApplicableObject applicableObject = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(userId);
        if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.ALL) {
            //全部返回null
            return null;
        } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_ORGANIZATION_AND_SUBORDINATE_EMPLOYEES) {
            UserBoundInfoVO usersBound = userV2Api.getUsersBound(userId, null).getData();
            if (null != usersBound) {
                List<OrganizeGeneralDetailVO> organizeGeneralDetailVOS = organizeV2Api.organizesOrHaveChildByOrganizeIds(List.of(usersBound.getOrganizeId()), true, null).getData();
                //过滤班组
                organizeGeneralDetailVOS = organizeGeneralDetailVOS.stream().filter(ctx -> !OrganizeCategoryEnums.TEAM.equals(ctx.getOrganizeCategoryEnums())).collect(Collectors.toList());
                return organizeGeneralDetailVOS.stream().map(OrganizeGeneralDetailVO::getId).collect(Collectors.toList());
            } else {
                return new ArrayList<>();
            }
        } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_ORGANIZATION_EMPLOYEES) {
            return new ArrayList<>();
        } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SUBORDINATE) {
            return new ArrayList<>();
        } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SPECIFIC_ORGANIZATION) {
            return applicableObject.getOrgIds();
        } else {
            log.error("未得到用户[" + userId + "]对应权限!");
            return new ArrayList<>();
        }
    }

    /**
     * 获取当前登录人权限
     *
     * @param sourceCategoryEnum
     * @return
     */
    public TargetAuthIdsVO processAuthIds() {
        TargetAuthIdsVO targetAuthIdsVO = new TargetAuthIdsVO();
        //停用 主动传userid
        String userId = UserProvider.getLoginUserId();
        //超级管理员也返回null,也获取全部
        if (UserProvider.getUser().getIsAdministrator()) {
            return null;
        }
        PermissionsApplicableObject applicableObject = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(userId);
        if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.ALL) {
            //全部返回null
            return null;
        } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_ORGANIZATION_AND_SUBORDINATE_EMPLOYEES) {
            targetAuthIdsVO.setTargetAuthEnums(TargetAuthEnums.ORGANIZE);
            UserBoundInfoVO usersBound = userV2Api.getUsersBound(userId, null).getData();
            if (null != usersBound) {
                List<OrganizeGeneralDetailVO> organizeGeneralDetailVOS = organizeV2Api.organizesOrHaveChildByOrganizeIds(List.of(usersBound.getOrganizeId()), true, null).getData();
                //过滤班组
                organizeGeneralDetailVOS = organizeGeneralDetailVOS.stream().filter(ctx -> !OrganizeCategoryEnums.TEAM.equals(ctx.getOrganizeCategoryEnums())).collect(Collectors.toList());
                targetAuthIdsVO.setIds(organizeGeneralDetailVOS.stream().map(OrganizeGeneralDetailVO::getId).collect(Collectors.toList()));
            } else {
                targetAuthIdsVO.setIds(new ArrayList<>());
            }
        } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_ORGANIZATION_EMPLOYEES) {
            targetAuthIdsVO.setTargetAuthEnums(TargetAuthEnums.USER);
            UserBoundInfoVO usersBound = userV2Api.getUsersBound(userId, null).getData();
            if (null != usersBound) {
                //当前组织的人 todo 这里处理冗余没效率,后期可以优化
                List<UserBoundVO> userBoundVOList = userV2Api.listTargetOrganizesOrHaveChild(List.of(usersBound.getOrganizeId()), false, UserWorkStatusEnums.getAllUserWorkStatusEnums(), null).getData();
                targetAuthIdsVO.setIds(userBoundVOList.stream().map(UserBoundVO::getId).distinct().collect(Collectors.toList()));
            } else {
                targetAuthIdsVO.setIds(new ArrayList<>());
            }
        } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SUBORDINATE) {
            targetAuthIdsVO.setTargetAuthEnums(TargetAuthEnums.USER);
            List<UserPageListVO> userPageListVO = userV2Api.listUnderlingTargetUser(userId, null).getData();
            targetAuthIdsVO.setIds(userPageListVO.stream().map(UserPageListVO::getId).collect(Collectors.toList()));
        } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SPECIFIC_ORGANIZATION) {
            targetAuthIdsVO.setTargetAuthEnums(TargetAuthEnums.ORGANIZE);
            targetAuthIdsVO.setIds(applicableObject.getOrgIds());
        } else {
            log.error("未得到用户[" + userId + "]对应权限!");
            targetAuthIdsVO.setTargetAuthEnums(TargetAuthEnums.NONE);
            targetAuthIdsVO.setIds(new ArrayList<>());
        }

        return targetAuthIdsVO;
    }

    /**
     * 批量查询用户的权限范围的门店
     *
     * @param userIds
     * @param status  状态 1：禁用 0：启用 -1-所有
     * @return
     */
    public Map<String, List<String>> batchAuthOrganizesForUserIds(List<String> userIds, Integer status) {
        log.info("[批量]未登录人的门店,userIds={}", userIds);
        List<String> cacheAllOrgIds = new ArrayList<>();//所有门店id
        QueryOrganizeListTargetTypesDTO dto = new QueryOrganizeListTargetTypesDTO();
        dto.setOrganizeCategoryEnums(List.of(OrganizeCategoryEnums.STORE));
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = organizeV2Api.listOrganizeByTargetTypes(dto);
        if (listActionResult != null && CollUtil.isNotEmpty(listActionResult.getData())) {
            for (OrganizeGeneralDetailVO vo : listActionResult.getData()) {
                if (status.equals(-1)) {
                    cacheAllOrgIds.add(vo.getId());
                } else if (status.equals(1)) {
                    if (!vo.getEnabled()) {
                        cacheAllOrgIds.add(vo.getId());
                    }
                } else if (status.equals(0)) {
                    if (vo.getEnabled()) {
                        cacheAllOrgIds.add(vo.getId());
                    }
                }
            }
        }

        Map<String, List<String>> cacheOrgIds = new HashMap<>();
        Map<String, List<String>> returnMap = new HashMap<>();
        Map<String, UserBoundVO> userPrimaryBoundBatchReturnMap = getUserPrimaryBoundBatchReturnMap(userIds, UserProvider.getUser().getTenantId());
        String moduleId = getModuleForHeader();
        for (String userId : userIds) {
            returnMap.put(userId, new ArrayList<>());
            //判断用户是否是管理员
            UserBoundVO usersBound = userPrimaryBoundBatchReturnMap.get(userId);
            if (null == usersBound) {
                continue;
            }
            if (usersBound.getIsAdministrator()) {
                returnMap.put(userId, cacheAllOrgIds);
                continue;
            }
            try {
                PermissionsApplicableObject applicableObject = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(userId, moduleId,UserProvider.getUser().getTenantId());
                if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.ALL) {
                    returnMap.put(userId, cacheAllOrgIds);
                } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_ORGANIZATION_AND_SUBORDINATE_EMPLOYEES) {
                    List<String> cacheIds = cacheOrgIds.get(usersBound.getOrganizeId());
                    if (CollUtil.isNotEmpty(cacheIds)) {
                        returnMap.put(userId, cacheIds);
                        continue;
                    }
                    List<OrganizeGeneralDetailVO> organizeGeneralDetailVOS = organizeV2Api.organizesOrHaveChildByOrganizeIds(List.of(usersBound.getOrganizeId()), true, null).getData();
                    //过滤门店
                    cacheIds = new ArrayList<>();
                    if (CollUtil.isNotEmpty(organizeGeneralDetailVOS)) {
                        for (OrganizeGeneralDetailVO organizeGeneralDetailVO : organizeGeneralDetailVOS) {
                            if (OrganizeCategoryEnums.STORE.equals(organizeGeneralDetailVO.getOrganizeCategoryEnums())) {
                                if (status.equals(-1)) {
                                    cacheIds.add(organizeGeneralDetailVO.getId());
                                } else if (status.equals(1)) {
                                    if (!organizeGeneralDetailVO.getEnabled()) {
                                        cacheIds.add(organizeGeneralDetailVO.getId());
                                    }
                                } else if (status.equals(0)) {
                                    if (organizeGeneralDetailVO.getEnabled()) {
                                        cacheIds.add(organizeGeneralDetailVO.getId());
                                    }
                                }
                            }
                        }
                        cacheOrgIds.put(usersBound.getOrganizeId(), cacheIds);
                        returnMap.put(userId, cacheIds);
                    }
                } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_ORGANIZATION_EMPLOYEES) {
                    if (cacheAllOrgIds.contains(usersBound.getOrganizeId())) {
                        returnMap.put(userId, List.of(usersBound.getOrganizeId()));
                    }
                } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SUBORDINATE) {

                    List<UserPageListVO> userPageListVO = userV2Api.listUnderlingTargetUser(userId, null).getData();
                    if(CollUtil.isNotEmpty(userPageListVO)){
                        List<String> cacheIds = new ArrayList<>();
                        for (UserPageListVO pageListVO : userPageListVO) {
                            if(cacheAllOrgIds.contains(pageListVO.getOrganizeId())){
                                cacheIds.add(pageListVO.getOrganizeId());
                            }
                        }
                        returnMap.put(userId, cacheIds);
                    }

                } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SPECIFIC_ORGANIZATION) {
                    returnMap.put(userId, UserApiV2Util.getIntersection(applicableObject.getOrgIds(), cacheAllOrgIds));
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("[批量]未登录人的门店,userId={},e={}", userId, e);
            }
        }
        log.info("[批量]未登录人的门店,returnMap= {}", returnMap);
        return returnMap;
    }
    /**
     * 批量用户有权限的门店
     *
     * @param userIds 用户ids
     * @param status  状态 1：禁用 0：启用 -1-所有
     * @param moduleId 模块id
     * @param tenantId 租户id
     * @return
     */
    public Map<String, List<String>> batchAuthOrganizesForUserIdsAndTenantId(List<String> userIds, Integer status, String moduleId, String tenantId) {
        return batchAuthOrganizesForUserIdsAndTenantId(userIds, List.of(OrganizeCategoryEnums.STORE), status, moduleId, tenantId);
    }
    public Map<String, List<String>> batchAuthOrganizesAll(List<String> userIds, Integer status, String moduleId, String tenantId) {
        return batchAuthOrganizesForUserIdsAndTenantId(userIds, List.of(OrganizeCategoryEnums.STORE, OrganizeCategoryEnums.DEPARTMENT, OrganizeCategoryEnums.COMPANY), status, moduleId, tenantId);
    }
    /**
     * 批量用户有权限的门店
     *
     * @param userIds 用户ids
     * @param status  状态 1：禁用 0：启用 -1-所有
     * @param moduleId 模块id
     * @param tenantId 租户id
     * @return
     */
    public Map<String, List<String>> batchAuthOrganizesForUserIdsAndTenantId(List<String> userIds, List<OrganizeCategoryEnums> organizeCategoryEnums, Integer status, String moduleId, String tenantId) {
        log.info("[批量]未登录人的门店,userIds={}", userIds);
        List<String> cacheAllOrgIds = new ArrayList<>();//所有门店id
        QueryOrganizeListTargetTypesDTO dto = new QueryOrganizeListTargetTypesDTO();
        dto.setTenantId(tenantId);
        dto.setOrganizeCategoryEnums(organizeCategoryEnums);
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = organizeV2Api.listOrganizeByTargetTypes(dto);
        if (listActionResult != null && CollUtil.isNotEmpty(listActionResult.getData())) {
            for (OrganizeGeneralDetailVO vo : listActionResult.getData()) {
                if (status.equals(-1)) {
                    cacheAllOrgIds.add(vo.getId());
                } else if (status.equals(1)) {
                    if (!vo.getEnabled()) {
                        cacheAllOrgIds.add(vo.getId());
                    }
                } else if (status.equals(0)) {
                    if (vo.getEnabled()) {
                        cacheAllOrgIds.add(vo.getId());
                    }
                }
            }
        }

        Map<String, List<String>> cacheOrgIds = new HashMap<>();
        Map<String, List<String>> returnMap = new HashMap<>();
        Map<String, UserBoundVO> userPrimaryBoundBatchReturnMap = getUserPrimaryBoundBatchReturnMap(userIds,tenantId);
      //  Map<String, PermissionsApplicableObject> objectMap = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(userIds, moduleId, tenantId);
        for (String userId : userIds) {
            returnMap.put(userId, new ArrayList<>());
            //判断用户是否是管理员
            UserBoundVO usersBound = userPrimaryBoundBatchReturnMap.get(userId);
            if (null == usersBound) {
                continue;
            }
            if (usersBound.getIsAdministrator()) {
                returnMap.put(userId, cacheAllOrgIds);
                continue;
            }
            try {
                PermissionsApplicableObject applicableObject = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(userId, moduleId, tenantId);
                log.error("permissionsApplicableEnums={}", applicableObject.getPermissionsApplicableEnums());
                if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.ALL) {
                    returnMap.put(userId, cacheAllOrgIds);
                } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_ORGANIZATION_AND_SUBORDINATE_EMPLOYEES) {
                    List<String> cacheIds = cacheOrgIds.get(usersBound.getOrganizeId());
                    if (CollUtil.isNotEmpty(cacheIds)) {
                        returnMap.put(userId, cacheIds);
                        continue;
                    }
                    List<OrganizeGeneralDetailVO> organizeGeneralDetailVOS = organizeV2Api.organizesOrHaveChildByOrganizeIds(List.of(usersBound.getOrganizeId()), true, tenantId).getData();
                    //过滤门店
                    cacheIds = new ArrayList<>();
                    if (CollUtil.isNotEmpty(organizeGeneralDetailVOS)) {
                        for (OrganizeGeneralDetailVO organizeGeneralDetailVO : organizeGeneralDetailVOS) {
                            if (OrganizeCategoryEnums.STORE.equals(organizeGeneralDetailVO.getOrganizeCategoryEnums())) {
                                if (status.equals(-1)) {
                                    cacheIds.add(organizeGeneralDetailVO.getId());
                                } else if (status.equals(1)) {
                                    if (!organizeGeneralDetailVO.getEnabled()) {
                                        cacheIds.add(organizeGeneralDetailVO.getId());
                                    }
                                } else if (status.equals(0)) {
                                    if (organizeGeneralDetailVO.getEnabled()) {
                                        cacheIds.add(organizeGeneralDetailVO.getId());
                                    }
                                }
                            }
                        }
                        cacheOrgIds.put(usersBound.getOrganizeId(), cacheIds);
                        returnMap.put(userId, cacheIds);
                    }
                } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_ORGANIZATION_EMPLOYEES) {
                    if (cacheAllOrgIds.contains(usersBound.getOrganizeId())) {
                        returnMap.put(userId, List.of(usersBound.getOrganizeId()));
                    }
                } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SUBORDINATE) {

                    List<UserPageListVO> userPageListVO = userV2Api.listUnderlingTargetUser(userId, tenantId).getData();
                    if (CollUtil.isNotEmpty(userPageListVO)) {
                        List<String> cacheIds = new ArrayList<>();
                        for (UserPageListVO pageListVO : userPageListVO) {
                            if (cacheAllOrgIds.contains(pageListVO.getOrganizeId())) {
                                cacheIds.add(pageListVO.getOrganizeId());
                            }
                        }
                        returnMap.put(userId, cacheIds);
                    }

                } else if (applicableObject.getPermissionsApplicableEnums() == PermissionsApplicableEnums.SCOPE_SPECIFIC_ORGANIZATION) {
                    returnMap.put(userId, UserApiV2Util.getIntersection(applicableObject.getOrgIds(), cacheAllOrgIds));
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("[批量]未登录人的门店,userId={},e={}", userId, e);
            }
        }
        log.info("[批量]未登录人的门店,returnMap= {}", returnMap);
        return returnMap;
    }

    /**
     * 批量获取用户信息
     *
     * @param userIds  用户id列表
     * @param tenantId
     * @return 用户信息映射，key为用户ID，value为用户信息对象
     */
    public Map<String, UserBoundVO> getUserPrimaryBoundBatchReturnMap(List<String> userIds, String tenantId) {
        Map<String, UserBoundVO> map = new HashMap<>();
        if (CollUtil.isEmpty(userIds)) {
            return map;
        }
        if (StringUtils.isEmpty(tenantId)) {
            tenantId = UserProvider.getUser().getTenantId();
        }
        ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = userV2Api.getUserPrimaryBoundBatch(userIds, tenantId);
        if (userPrimaryBoundBatch == null || CollUtil.isEmpty(userPrimaryBoundBatch.getData())) {
            return map;
        }
        for (UserBoundVO userPrimaryBoundVO : userPrimaryBoundBatch.getData()) {
            map.put(userPrimaryBoundVO.getId(), userPrimaryBoundVO);
        }
        return map;
    }

    /**
     * 从header头中获取module
     *
     * @return
     */
    private String getModuleForHeader() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            throw new RuntimeException("请传入权限菜单id");
        }
        String module = attributes.getRequest().getHeader("Module");
        if (StringUtil.isEmpty(module)) {
            throw new RuntimeException("请传入权限菜单id");
        }
        return module;
    }

    public  Map<String, PermissionsApplicableObject> batchAuthOrganizesAllForUserIds(List<String> userIds) {
        return permissionsUtils.obtainTheScopeOfUserPermissionsEnums(userIds, getModuleForHeader(), UserProvider.getUser().getTenantId());
    }
}
