package jnpf.authority.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import jnpf.authority.service.FtbPermissionOrganizeService;
import jnpf.authority.utils.PermissionsApplicableObject;
import jnpf.model.personnels.dto.turnover.FtbDepUserDTO;
import jnpf.permission.StoreApi;
import jnpf.permission.V2OrganizeApi;
import jnpf.permission.dto.store.StoreListInfoDTO;
import jnpf.permission.dto.v2.AuthUserNodeDTO;
import jnpf.permission.dto.v2.organzie.AuthOrganizeUserNodeDTO;
import jnpf.permission.dto.v2.organzie.QueryOrganizeNodeDTO;
import jnpf.permission.eum.StoreDisabledEnum;
import jnpf.permission.eum.v2.NodeTypeEnum;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.eum.v2.TargetAuthEnums;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.vo.store.StoreBaseListInfo;
import jnpf.permission.vo.v2.TargetAuthIdsVO;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerFilterNodeVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerNodeVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.service.FtbPersonnelsTurnoverManagementService;
import jnpf.util.UserProvider;
import jnpf.util.auth.V2AuthPermissionUtils;
import jnpf.util.permssion.V2Utils;
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-06
 */
@Service
@Slf4j
public class FtbPermissionOrganizeServiceImpl implements FtbPermissionOrganizeService {
    @Resource
    private V2AuthPermissionUtils authPermissionUtils;
    @Resource
    private V2OrganizeApi organizeApi;
    @Resource
    private StoreApi storeApi;
    @Resource
    private FtbPersonnelsTurnoverManagementService turnoverManagementService;

    @Override
    public List<OrganizeManagerNodeVO> allOrganizeUsersTree(QueryOrganizeNodeDTO dto) {
        List<OrganizeManagerNodeVO> vos = organizeApi.allOrganizeUsersListApi(dto);
        //查询离职的人
        if (CollUtil.isNotEmpty(vos)) {
            FtbDepUserDTO ftbDepUserDTO = new FtbDepUserDTO();
            ftbDepUserDTO.setOrganizeIds(vos.stream().map(OrganizeManagerNodeVO::getId).collect(Collectors.toList()));
            List<UserBoundVO> ftbDepUsers = turnoverManagementService.getInformationAboutTheDepartingPerson(ftbDepUserDTO);
            if (CollUtil.isEmpty(ftbDepUsers)) {
                log.error("没有离职的人,查询参数情况[{}],  离职请求参数情况[{}]", dto, ftbDepUserDTO);
            } else {
                ftbDepUsers = ftbDepUsers.stream().filter(data -> StrUtil.isNotBlank(data.getOrganizeId())).collect(Collectors.toList());
                vos.addAll(
                        ftbDepUsers.stream().map(userBoundVO -> {
                            OrganizeManagerNodeVO organizeManagerNodeVO = new OrganizeManagerNodeVO();
                            organizeManagerNodeVO.setName(userBoundVO.getUserName());
                            organizeManagerNodeVO.setNodeTypeEnum(NodeTypeEnum.USER);
                            organizeManagerNodeVO.setNodeType(organizeManagerNodeVO.getNodeTypeEnum().getNum());
                            organizeManagerNodeVO.setNodeTypeName(organizeManagerNodeVO.getNodeTypeEnum().getCode());
                            organizeManagerNodeVO.setNodeTypeValue(organizeManagerNodeVO.getNodeTypeEnum().getDescription());
                            organizeManagerNodeVO.setLeaderId(userBoundVO.getLeaderId());
                            organizeManagerNodeVO.setPid(userBoundVO.getOrganizeId());
                            organizeManagerNodeVO.setId(userBoundVO.getId());
                            organizeManagerNodeVO.setHeadIcon(userBoundVO.getHeadIcon());
                            return organizeManagerNodeVO;
                        }).collect(Collectors.toList())
                );
            }
        }
        vos = V2Utils.changeToTreeNoParent(vos, OrganizeManagerNodeVO.class);
        return vos;
    }

    @Override
    public List<OrganizeManagerNodeVO> listOrganizeTreeUsers(List<OrganizeCategoryEnums> organizeCategoryEnums,
                                                             List<UserWorkStatusEnums> workStatusEnums, String organizeKeyword, Boolean withEmployee, Boolean includeResigned) {
        TargetAuthIdsVO authIdsVO = authPermissionUtils.processAuthIds();
        AuthOrganizeUserNodeDTO dto = new AuthOrganizeUserNodeDTO(authIdsVO, UserProvider.getUser().getTenantId());
        dto.setHavaAuth(authIdsVO != null);
        dto.setHaveUsers(withEmployee);
        dto.setOrganizeKeyword(organizeKeyword);
        dto.setOrganizeCategoryEnums(organizeCategoryEnums);
        if (CollUtil.isEmpty(workStatusEnums)) {
            dto.setWorkStatusEnums(UserWorkStatusEnums.getQueryUserFilterWorkStatusEnums());
        } else {
            dto.setWorkStatusEnums(workStatusEnums);
        }
        List<OrganizeManagerNodeVO> vos = organizeApi.listOrganizeTreeUsersApi(dto);
        //搜索离职的人
        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<String> userIds = vos.stream().filter(data -> data.getNodeTypeEnum().equals(NodeTypeEnum.USER)).map(OrganizeManagerNodeVO::getId).collect(Collectors.toList());
            List<UserBoundVO> ftbDepUsers = turnoverManagementService.getInformationAboutTheDepartingPerson(ftbDepUserDTO);
            if (CollUtil.isEmpty(ftbDepUsers)) {
                log.error("没有离职的人,权限参数情况[{}],  离职请求参数情况[{}]", authIdsVO, ftbDepUserDTO);
            } else {
                ftbDepUsers = ftbDepUsers.stream().filter(data ->
                        StrUtil.isNotBlank(data.getOrganizeId()) && !userIds.contains(data.getId())
                ).collect(Collectors.toList());
                vos.addAll(
                        ftbDepUsers.stream().map(userBoundVO -> {
                            OrganizeManagerNodeVO organizeManagerNodeVO = new OrganizeManagerNodeVO();
                            organizeManagerNodeVO.setName(userBoundVO.getUserName());
                            organizeManagerNodeVO.setNodeTypeEnum(NodeTypeEnum.USER);
                            organizeManagerNodeVO.setNodeType(organizeManagerNodeVO.getNodeTypeEnum().getNum());
                            organizeManagerNodeVO.setNodeTypeName(organizeManagerNodeVO.getNodeTypeEnum().getCode());
                            organizeManagerNodeVO.setNodeTypeValue(organizeManagerNodeVO.getNodeTypeEnum().getDescription());
                            organizeManagerNodeVO.setLeaderId(userBoundVO.getLeaderId());
                            organizeManagerNodeVO.setPid(userBoundVO.getOrganizeId());
                            organizeManagerNodeVO.setId(userBoundVO.getId());
                            organizeManagerNodeVO.setHeadIcon(userBoundVO.getHeadIcon());
                            return organizeManagerNodeVO;
                        }).collect(Collectors.toList())
                );
            }
        }

        vos = V2Utils.changeToTreeNoParent(vos, OrganizeManagerNodeVO.class);
        return vos;
    }

    @Override
    public List<OrganizeManagerFilterNodeVO> listOrganizeTreeUsersFilterNodeJson(List<OrganizeCategoryEnums> organizeCategoryEnums,
                                                                                 List<UserWorkStatusEnums> workStatusEnums,
                                                                                 Boolean withEmployee,
                                                                                 Boolean filterBindOtherStore,
                                                                                 Boolean filterBindPayStore
    ) {
        TargetAuthIdsVO authIdsVO = authPermissionUtils.processAuthIds();
        AuthOrganizeUserNodeDTO dto = new AuthOrganizeUserNodeDTO(authIdsVO, UserProvider.getUser().getTenantId());
        dto.setHavaAuth(authIdsVO != null);
        dto.setHaveUsers(null == withEmployee ? Boolean.TRUE : withEmployee);
        dto.setFilterBindOtherStore(filterBindOtherStore);
        dto.setFilterBindPayStore(filterBindPayStore);
        dto.setOrganizeCategoryEnums(organizeCategoryEnums);
        if (CollUtil.isEmpty(workStatusEnums)) {
            dto.setWorkStatusEnums(UserWorkStatusEnums.getQueryUserFilterWorkStatusEnums());
        } else {
            dto.setWorkStatusEnums(workStatusEnums);
        }
        List<OrganizeManagerFilterNodeVO> organizeManagerFilterNodes = organizeApi.listOrganizeTreeUsersFilterNodeJson(dto);
//        log.error("ftb组织树过滤节点isEnable 数量为:{}", organizeManagerFilterNodes.stream().filter(o -> o.getIsEnabled() != null && o.getIsEnabled()).count());
        return organizeManagerFilterNodes;
    }

    @Override
    public List<OrganizeGeneralDetailVO> authOrganizesByUserBound(List<OrganizeCategoryEnums> organizeCategoryEnums,
                                                                  String organizeKeyword,
                                                                  Boolean filterBindOtherStore,
                                                                  Boolean filterBindPayStore
    ) {
        TargetAuthIdsVO authIdsVO = authPermissionUtils.processAuthIds();
        AuthUserNodeDTO dto = new AuthUserNodeDTO(authIdsVO, UserProvider.getUser().getTenantId());
        dto.setHavaAuth(authIdsVO != null);
        dto.setOrganizeCategoryEnums(organizeCategoryEnums);
        dto.setOrganizeKeyword(organizeKeyword);
        dto.setFilterBindOtherStore(filterBindOtherStore);
        dto.setFilterBindPayStore(filterBindPayStore);
        dto.setOrganizeKeyword(organizeKeyword);
        return organizeApi.authOrganizesByUserBound(dto).getData();
    }

    /**
     * 批量获取有权限的门店
     *
     * @param userIds 用户id集合
     * @param status  状态 1：禁用 0：启用 -1-所有
     * @return 用户ID的map
     */
    @Override
    public Map<String, List<String>> batchAuthOrganizesForUserIds(List<String> userIds, Integer status) {
        return authPermissionUtils.batchAuthOrganizesForUserIds(userIds, status);
    }
    /**
     * 批量用户有权限的门店
     *
     * @param userIds 用户ids
     * @param status  状态 1：禁用 0：启用 -1-所有
     * @param moduleId 模块id
     * @param tenantId 租户id
     * @return
     */
    @Override
    public Map<String, List<String>> batchAuthOrganizesForUserIdsAndTenantId(List<String> userIds, Integer status, String moduleId, String tenantId) {
        return authPermissionUtils.batchAuthOrganizesForUserIdsAndTenantId(userIds, status, moduleId, tenantId);
    }

    @Override
    public  Map<String, PermissionsApplicableObject> batchAuthOrganizesAllForUserIds(List<String> userIds) {
        return authPermissionUtils.batchAuthOrganizesAllForUserIds(userIds);
    }

    @Override
    public TargetAuthIdsVO getUserAuth() {

        return authPermissionUtils.processAuthIds();
    }

    /**
     * 批量用户有权限的门店
     *
     * @param userIds 用户ids
     * @param status  状态 1：禁用 0：启用 -1-所有
     * @param moduleId 模块id
     * @param tenantId 租户id
     * @return
     */
    @Override
    public Map<String, List<String>> batchAuthOrganizesAllForUserIdsAndTenantId(List<String> userIds, Integer status, String moduleId, String tenantId) {
        return authPermissionUtils.batchAuthOrganizesAll(userIds, status, moduleId, tenantId);
    }

    @Override
    public List<StoreBaseListInfo> authStoreBaseListInfo() {
        TargetAuthIdsVO authIdsVO = authPermissionUtils.processAuthIds();
        AuthUserNodeDTO dto1 = new AuthUserNodeDTO(authIdsVO, UserProvider.getUser().getTenantId());
        dto1.setHavaAuth(authIdsVO != null);
        dto1.setOrganizeCategoryEnums(List.of(OrganizeCategoryEnums.STORE));
        List<OrganizeGeneralDetailVO> organizeGeneralDetailVOS = organizeApi.authOrganizesByUserBound(dto1).getData();
        if (CollUtil.isEmpty(organizeGeneralDetailVOS)) {
            return new ArrayList<>();
        }
        StoreListInfoDTO dto = new StoreListInfoDTO();
        dto.setStoreIds(organizeGeneralDetailVOS.stream().map(OrganizeGeneralDetailVO::getId).collect(Collectors.toList()));
        dto.setStoreDisabledEnum(StoreDisabledEnum.ENABLED);
        return storeApi.storeBaseInfoList(dto).getData();
    }
}
