package com.yd.csf.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.common.enums.CommonEnum;
import com.yd.common.enums.ProjectEnum;
import com.yd.common.enums.TenantEnum;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.common.utils.TreeUtils;
import com.yd.csf.api.service.*;
import com.yd.csf.feign.dto.agentmanagerelation.ApiAgentManageUserDTO;
import com.yd.csf.feign.dto.clientrole.ApiClientRoleDTO;
import com.yd.csf.feign.dto.csfclientuser.ApiCsfClientUserDTO;
import com.yd.csf.feign.dto.firstlevel.ApiFirstLevelDTO;
import com.yd.csf.feign.dto.org.ApiCsfClientUserOrgDTO;
import com.yd.csf.feign.dto.referrer.ApiReferrerDTO;
import com.yd.csf.feign.dto.rule.ApiRuleDTO;
import com.yd.csf.feign.dto.second.ApiSecondLevelDTO;
import com.yd.csf.feign.dto.tutor.ApiTutorDTO;
import com.yd.csf.feign.dto.userbank.ApiCsfClientUserBankDTO;
import com.yd.csf.feign.enums.ClientRoleEnum;
import com.yd.csf.feign.request.csfclientuser.ApiCsfClientUserAddRequest;
import com.yd.csf.feign.request.csfclientuser.ApiCsfClientUserEditRequest;
import com.yd.csf.feign.request.csfclientuser.ApiCsfClientUserPageRequest;
import com.yd.csf.feign.request.csfclientuser.ApiCsfClientUserTreeListRequest;
import com.yd.csf.feign.request.fyc.ApiInitAgentAccumulatedFycRequest;
import com.yd.csf.feign.request.rulebind.ApiCommissionRuleBindingRequest;
import com.yd.csf.feign.response.csfclientuser.ApiCsfClientUserDetailResponse;
import com.yd.csf.feign.response.csfclientuser.ApiCsfClientUserPageResponse;
import com.yd.csf.feign.response.csfclientuser.ApiCsfClientUserTreeListResponse;
import com.yd.csf.feign.response.csfclientuser.ApiManageTreeResponse;
import com.yd.csf.service.dto.query.QueryCsfClientUserDTO;
import com.yd.csf.service.model.*;
import com.yd.csf.service.service.*;
import com.yd.insurance.base.feign.client.usersaleexpand.ApiUserSaleExpandFeignClient;
import com.yd.insurance.base.feign.client.usersignexpand.ApiUserSignExpandFeignClient;
import com.yd.insurance.base.feign.request.usersaleexpand.ApiUserSaleExpandSaveRequest;
import com.yd.insurance.base.feign.request.usersignexpand.ApiUserSignExpandSaveRequest;
import com.yd.user.feign.client.clientuser.ApiClientUserFeignClient;
import com.yd.user.feign.request.clientuser.ApiClientUserConditionListRequest;
import com.yd.user.feign.request.clientuser.ApiClientUserSaveRequest;
import com.yd.user.feign.response.clientuser.ApiClientUserDetailResponse;
import com.yd.user.feign.response.clientuser.ApiClientUserSaveResponse;
import com.yd.user.feign.response.sysmenu.ApiSysMenuTreeListResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Slf4j
@Service
public class ApiCsfClientUserServiceImpl implements ApiCsfClientUserService {

    @Resource
    private ICsfClientUserService csfClientUserService;

    @Resource
    private ApiAgentAccumulatedFycService apiAgentAccumulatedFycService;

    @Resource
    private ApiCommissionRuleBindingService apiCommissionRuleBindingService;

    @Resource
    private ApiUserBankService apiUserBankService;

    @Resource
    private ApiAgentTutoringRelationService apiAgentTutoringRelationService;

    @Resource
    private ApiAgentReferralRelationService apiAgentReferralRelationService;

    @Resource
    private ApiAgentManageRelationService apiAgentManageRelationService;

    @Resource
    private IClientRoleService iClientRoleService;

    @Resource
    private IUserBankService iUserBankService;

    @Resource
    private ICommissionRuleConfigService iCommissionRuleConfigService;

    @Resource
    private IAgentTutoringRelationService iAgentTutoringRelationService;

    @Resource
    private IAgentReferralRelationService iAgentReferralRelationService;

    @Resource
    private IAgentManageRelationService iAgentManageRelationService;

    @Resource
    private IAgentAccumulatedFycService iAgentAccumulatedFycService;

    @Resource
    private ITeamService iTeamService;

    @Resource
    private ApiClientUserFeignClient apiClientUserFeignClient;

    @Resource
    private ApiUserSaleExpandFeignClient apiUserSaleExpandFeignClient;

    @Resource
    private ApiUserSignExpandFeignClient apiUserSignExpandFeignClient;

    /**
     * 查询-左边人员信息树列表（组织架构管理树形列表）
     * @param request
     * @return
     */
    @Override
    public Result<ApiCsfClientUserTreeListResponse> treeList(ApiCsfClientUserTreeListRequest request) {
        //姓名模糊搜索管理和人员关系数据列表
        List<ApiAgentManageUserDTO> userDTOList = apiAgentManageRelationService.queryApiAgentManageUserDTO(request.getName());
        if (CollectionUtils.isEmpty(userDTOList)) {
            return Result.success();
        }
        //userDTOList转化成List<ApiManageTreeResponse> apiManageTreeResponseList
        List<ApiManageTreeResponse> apiManageTreeResponseList = userDTOList
                .stream()
                .map(dto -> {
                    ApiManageTreeResponse response = new ApiManageTreeResponse();
                    BeanUtils.copyProperties(dto,response);
                    return response;
                }).collect(Collectors.toList());
        //构建树列表
        List<ApiManageTreeResponse> treeList = TreeUtils.buildTree(
                apiManageTreeResponseList,
                ApiManageTreeResponse::getAgentId,         // 获取节点ID
                ApiManageTreeResponse::getPid,   // 获取父节点ID
                (parent, children) -> parent.setChildren(children), // 设置子节点
                null                   // 根节点的父ID值
        );

        // 填充每个节点的 childrenAgentIdList（所有后代ID）
        fillChildrenAgentIds(treeList);

        ApiCsfClientUserTreeListResponse response = new ApiCsfClientUserTreeListResponse();
        response.setApiManageTreeResponseList(treeList);
        return Result.success(response);
    }

    /**
     * 递归收集子级人员ID
     * @param treeList
     */
    private void fillChildrenAgentIds(List<ApiManageTreeResponse> treeList) {
        for (ApiManageTreeResponse node : treeList) {
            List<String> allChildIds = new ArrayList<>();
            collectAllChildrenIds(node, allChildIds);
            node.setChildrenAgentIdList(allChildIds);
            // 递归处理子节点
            if (node.getChildren() != null && !node.getChildren().isEmpty()) {
                fillChildrenAgentIds(node.getChildren());
            }
        }
    }

    private void collectAllChildrenIds(ApiManageTreeResponse node, List<String> ids) {
        if (node.getChildren() != null) {
            for (ApiManageTreeResponse child : node.getChildren()) {
                ids.add(child.getAgentId());
                collectAllChildrenIds(child, ids); // 继续收集孙节点
            }
        }
    }

    /**
     * 分页查询-人员信息
     * @param request
     * @return
     */
    @Override
    public Result<IPage<ApiCsfClientUserPageResponse>> page(ApiCsfClientUserPageRequest request) {
        Page<ApiCsfClientUserPageResponse> page = new Page<>(request.getPageNo(), request.getPageSize());
        IPage<ApiCsfClientUserPageResponse> iPage = csfClientUserService.iPage(page, request);
        return Result.success(iPage);
    }

    /**
     * 详情-人员信息
     * @param csfClientUserBizId
     * @return
     */
    @Override
    public Result<ApiCsfClientUserDetailResponse> detail(String csfClientUserBizId) {
        CsfClientUser csfClientUser = csfClientUserService.queryOne(csfClientUserBizId);
        if (csfClientUser == null) {
            throw new BusinessException("人员信息不存在");
        }
        ApiCsfClientUserDetailResponse response = new ApiCsfClientUserDetailResponse();
        //人员信息
        ApiCsfClientUserDTO userDTO = new ApiCsfClientUserDTO();
        BeanUtils.copyProperties(csfClientUser,userDTO);
        //设置绑定的角色列表
        List<ApiClientRoleDTO> roleDTOList = getRoleDTOList(csfClientUser.getRoleBizIds());
        userDTO.setRoleDTOList(roleDTOList);
        //设置绑定的基本法列表
        List<ApiRuleDTO> ruleDTOList = getRuleDTOList(csfClientUser.getRuleBizIds());
        userDTO.setRuleDTOList(ruleDTOList);
        response.setUserDTO(userDTO);

        //人员银行信息列表
        List<ApiCsfClientUserBankDTO> bankDTOList = getBankDTOList(csfClientUser.getCsfClientUserBizId());
        response.setBankDTOList(bankDTOList);

        //组织信息
        //辅导列表
        ApiCsfClientUserOrgDTO orgDTO = new ApiCsfClientUserOrgDTO();
        List<ApiTutorDTO> tutorDTOList = getTutorDTOList(csfClientUser.getClientUserBizId());
        orgDTO.setTutorDTOList(tutorDTOList);
        //推荐列表
        List<ApiReferrerDTO> referrerDTOList = getReferrerDTOList(csfClientUser.getClientUserBizId());
        orgDTO.setReferrerDTOList(referrerDTOList);
        //一级和二级列表
        //一级管理列表
        List<ApiFirstLevelDTO> firstLevelDTOList = getFirstLevelDTOList(csfClientUser.getClientUserBizId());
        orgDTO.setFirstLevelDTOList(firstLevelDTOList);
        //二级管理列表
        List<ApiSecondLevelDTO> secondLevelDTOList = getSecondLevelDTOList(csfClientUser.getClientUserBizId());
        orgDTO.setSecondLevelDTOList(secondLevelDTOList);
        response.setOrgDTO(orgDTO);
        return Result.success(response);
    }

    /**
     * 获取一级管理列表
     * @param clientUserBizId
     * @return
     */
    public List<ApiFirstLevelDTO> getFirstLevelDTOList(String clientUserBizId) {
        List<ApiFirstLevelDTO> firstLevelDTOList = new ArrayList<>();
        if (StringUtils.isBlank(clientUserBizId)) {
            return firstLevelDTOList;
        }
        log.info("获取一级管理列表=>clientUserBizId:{}", clientUserBizId);
        List<String> manageIdList = iAgentManageRelationService.lambdaQuery()
                .select(AgentManageRelation::getManageId)
                .eq(AgentManageRelation::getAgentId, clientUserBizId)
                .list() // 可能包含 null 元素
                .stream()
                .filter(Objects::nonNull)              // 过滤掉 null 对象
                .map(AgentManageRelation::getManageId)
                .collect(Collectors.toList());
        log.info("获取一级管理列表=>manageIdList:{}", JSON.toJSONString(manageIdList));
        if (CollectionUtils.isEmpty(manageIdList)) {
            return firstLevelDTOList;
        }
        List<CsfClientUser> manageList = csfClientUserService.lambdaQuery()
                .in(CsfClientUser::getClientUserBizId,manageIdList)
                .list();
        if (CollectionUtils.isEmpty(manageList)) {
            return firstLevelDTOList;
        }

        return manageList.stream().map(user -> {
            ApiFirstLevelDTO dto = new ApiFirstLevelDTO();
            BeanUtils.copyProperties(user, dto);
            //TODO 设置等级名称
            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取二级管理列表
     * @param clientUserBizId
     * @return
     */
    public List<ApiSecondLevelDTO> getSecondLevelDTOList(String clientUserBizId) {
        List<ApiSecondLevelDTO> secondLevelDTOList = new ArrayList<>();
        if (StringUtils.isBlank(clientUserBizId)) {
            return secondLevelDTOList;
        }
        List<String> manageIdList = iAgentManageRelationService.lambdaQuery()
                .select(AgentManageRelation::getSManageId)
                .eq(AgentManageRelation::getAgentId, clientUserBizId)
                .list() // 返回 List<AgentTutoringRelation>
                .stream()
                .filter(Objects::nonNull)
                .map(AgentManageRelation::getSManageId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(manageIdList)) {
            return secondLevelDTOList;
        }
        List<CsfClientUser> manageList = csfClientUserService.lambdaQuery()
                .in(CsfClientUser::getClientUserBizId,manageIdList)
                .list();
        if (CollectionUtils.isEmpty(manageList)) {
            return secondLevelDTOList;
        }

        return manageList.stream().map(user -> {
            ApiSecondLevelDTO dto = new ApiSecondLevelDTO();
            BeanUtils.copyProperties(user, dto);
            //TODO 设置等级名称
            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取推荐列表
     * @param clientUserBizId
     * @return
     */
    public List<ApiReferrerDTO> getReferrerDTOList(String clientUserBizId) {
        List<ApiReferrerDTO> referrerDTOList = new ArrayList<>();
        if (StringUtils.isBlank(clientUserBizId)) {
            return referrerDTOList;
        }
        List<String> referrerIdList = iAgentReferralRelationService.lambdaQuery()
                .select(AgentReferralRelation::getReferrerId)
                .eq(AgentReferralRelation::getAgentId, clientUserBizId)
                .list() // 返回 List<AgentTutoringRelation>
                .stream()
                .filter(Objects::nonNull)
                .map(AgentReferralRelation::getReferrerId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(referrerIdList)) {
            return referrerDTOList;
        }
        List<CsfClientUser> referrerList = csfClientUserService.lambdaQuery()
                .in(CsfClientUser::getClientUserBizId,referrerIdList)
                .list();
        if (CollectionUtils.isEmpty(referrerList)) {
            return referrerDTOList;
        }

        return referrerList.stream().map(user -> {
            ApiReferrerDTO dto = new ApiReferrerDTO();
            BeanUtils.copyProperties(user, dto);
            //TODO 设置等级名称
            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取辅导列表
     * @param clientUserBizId
     * @return
     */
    public List<ApiTutorDTO> getTutorDTOList(String clientUserBizId) {
        List<ApiTutorDTO> tutorDTOList = new ArrayList<>();
        if (StringUtils.isBlank(clientUserBizId)) {
            return tutorDTOList;
        }
        List<String> tutorIdList = iAgentTutoringRelationService.lambdaQuery()
                .select(AgentTutoringRelation::getTutorId)
                .eq(AgentTutoringRelation::getAgentId, clientUserBizId)
                .list() // 返回 List<AgentTutoringRelation>
                .stream()
                .filter(Objects::nonNull)
                .map(AgentTutoringRelation::getTutorId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(tutorIdList)) {
            return tutorDTOList;
        }
        List<CsfClientUser> tutorList = csfClientUserService.lambdaQuery()
                .in(CsfClientUser::getClientUserBizId,tutorIdList)
                .list();
        if (CollectionUtils.isEmpty(tutorList)) {
            return tutorDTOList;
        }

        return tutorList.stream().map(user -> {
            ApiTutorDTO dto = new ApiTutorDTO();
            BeanUtils.copyProperties(user, dto);
            //TODO 设置等级名称
            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取绑定的角色列表
     * @param roleBizIds
     * @return
     */
    public List<ApiClientRoleDTO> getRoleDTOList(String roleBizIds) {
        List<ApiClientRoleDTO> roleDTOList = new ArrayList<>();
        if (StringUtils.isBlank(roleBizIds)) {
            return roleDTOList;
        }
        List<String> roleBizIdList = Arrays.asList(roleBizIds.split(";"));
        List<ClientRole> clientRoleList = iClientRoleService.queryList(roleBizIdList);
        if (CollectionUtils.isEmpty(clientRoleList)) {
            return roleDTOList;
        }
        roleDTOList = clientRoleList.stream().map(d -> {
            ApiClientRoleDTO roleDTO = new ApiClientRoleDTO();
            roleDTO.setName(d.getName());
            roleDTO.setRoleBizId(d.getRoleBizId());
            return roleDTO;
        }).collect(Collectors.toList());
        return roleDTOList;
    }

    /**
     * 获取绑定的基本法列表
     * @param ruleBizIds
     * @return
     */
    public List<ApiRuleDTO> getRuleDTOList(String ruleBizIds) {
        List<ApiRuleDTO> ruleDTOList = new ArrayList<>();
        if (StringUtils.isBlank(ruleBizIds)) {
            return ruleDTOList;
        }
        List<String> ruleBizIdList = Arrays.asList(ruleBizIds.split(";"));
        List<CommissionRuleConfig> ruleConfigList = iCommissionRuleConfigService.queryList(ruleBizIdList);
        if (CollectionUtils.isEmpty(ruleConfigList)) {
            return ruleDTOList;
        }
        ruleDTOList = ruleConfigList.stream().map(d -> {
            ApiRuleDTO ruleDTO = new ApiRuleDTO();
            ruleDTO.setRuleName(d.getRuleName());
            ruleDTO.setRuleBizId(d.getRuleBizId());
            return ruleDTO;
        }).collect(Collectors.toList());
        return ruleDTOList;
    }

    /**
     * 获取人员银行信息列表
     * @param csfClientUserBizId
     * @return
     */
    public List<ApiCsfClientUserBankDTO> getBankDTOList(String csfClientUserBizId) {
        List<ApiCsfClientUserBankDTO> userBankDTOList = new ArrayList<>();
        if (StringUtils.isBlank(csfClientUserBizId)) {
            return userBankDTOList;
        }
        List<UserBank> userBankList = iUserBankService.queryList(csfClientUserBizId);
        if (CollectionUtils.isEmpty(userBankList)) {
            return userBankDTOList;
        }
        userBankDTOList = userBankList.stream().map(d -> {
            ApiCsfClientUserBankDTO bankDTO = new ApiCsfClientUserBankDTO();
            BeanUtils.copyProperties(d,bankDTO);
            return bankDTO;
        }).collect(Collectors.toList());
        return userBankDTOList;
    }

    /**
     * 编辑-人员信息
     * 编辑说明：
     * 1、由于老数据的原因，详情返回的人员信息，初始化等级和所属团队，根据返回的数据，来决定是只读还是能修改。返回有数据只读，返回无数据可以修改。其他基础信息字段可以修改。
     * 2、银行信息和组织信息不能修改，只读状态。
     * @param request
     * @return
     */
    @Override
    public Result edit(ApiCsfClientUserEditRequest request) {
        ApiCsfClientUserDTO userDTO = request.getUserDTO();
        if (userDTO == null) {
            throw new BusinessException("人员基本信息入参对象不能为空");
        }
        //查询人员信息是否存在
        CsfClientUser csfClientUser = csfClientUserService.lambdaQuery()
                .eq(CsfClientUser::getCsfClientUserBizId,request.getCsfClientUserBizId())
                .last(" limit 1 ")
                .one();
        if (csfClientUser == null) {
            throw new BusinessException("人员信息不存在");
        }
        String teamBizId = csfClientUser.getTeamBizId();
        BeanUtils.copyProperties(userDTO,csfClientUser);

        //校验入参的所属团队和一级管理人所属团队是否匹配
        checkTeam(request.getOrgDTO(),csfClientUser.getTeamBizId());

        //更新绑定的角色ID列表
        //绑定的客户端角色表表唯一业务ID列表（多个分号分隔）
        List<String> roleBizIdList = userDTO.getRoleDTOList().stream()
                .filter(d -> StringUtils.isNotBlank(d.getRoleBizId()))
                .map(ApiClientRoleDTO::getRoleBizId)
                .collect(Collectors.toList());
        csfClientUser.setRoleBizIds(CollectionUtils.isNotEmpty(roleBizIdList) ? String.join(";",roleBizIdList) : "");
        //更新绑定的基本法ID列表
        //绑定的基本法配置表唯一业务ID列表（多个分号分隔）
        List<String> ruleBizIdList = userDTO.getRuleDTOList().stream()
                .filter(d -> StringUtils.isNotBlank(d.getRuleBizId()))
                .map(ApiRuleDTO::getRuleBizId)
                .collect(Collectors.toList());
        csfClientUser.setRuleBizIds(CollectionUtils.isNotEmpty(ruleBizIdList) ? String.join(";",ruleBizIdList) : "");

        //合同签订日期
        csfClientUser.setContractSigningDate(userDTO.getContractSigningDate() != null ? userDTO.getContractSigningDate().toInstant()
                .atZone(ZoneId.of("GMT+8"))
                .toLocalDateTime() : null);
        //离职日
        csfClientUser.setLastWorkingDay(userDTO.getLastWorkingDay() != null ? userDTO.getLastWorkingDay().toInstant()
                .atZone(ZoneId.of("GMT+8"))
                .toLocalDateTime() : null);

        //校验是否需要初始化等级
        //查询积分总表记录，校验是否初始化了等级，没有就新增，有就无需处理。
        AgentAccumulatedFyc agentAccumulatedFyc = iAgentAccumulatedFycService.lambdaQuery()
                .eq(AgentAccumulatedFyc::getAgentId,csfClientUser.getClientUserBizId())
                .last(" limit 1 ").one();
        if (agentAccumulatedFyc == null) {
            //没有初始化过等级，必须传值初始化
            //根据初始化职级，fyc表（业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息）新增初始化记录
            ApiInitAgentAccumulatedFycRequest fycRequest = new ApiInitAgentAccumulatedFycRequest();
            fycRequest.setAgentId(csfClientUser.getClientUserBizId());
            fycRequest.setAgentName(csfClientUser.getName());
            fycRequest.setInitGrade(userDTO.getInitGradeCode());
            apiAgentAccumulatedFycService.initAgentAccumulatedFyc(fycRequest);
        }else {
            //积分总表的初始等级和当前等级回写更新到人员信息表中
            csfClientUser.setInitGradeCode(agentAccumulatedFyc.getInitGrade());
            csfClientUser.setCurrentGradeCode(agentAccumulatedFyc.getCurrentGradeCode());
        }

        //查询当前人员的管理关系数据
        AgentManageRelation agentManageRelation = iAgentManageRelationService.lambdaQuery()
                .eq(AgentManageRelation::getAgentId,csfClientUser.getClientUserBizId())
                .last(" limit 1 ")
                .one();
        //处理所属团队数据=>如果之前老数据中没有所属团队并且管理关系处于最高节点。那么就生成团队表数据，回写更新。
        if (StringUtils.isBlank(teamBizId) && (agentManageRelation != null && agentManageRelation.getPid() == null)) {
            //新增团队信息
            Team team = new Team();
            team.setTeamName(userDTO.getTeamName());
            team.setPid("0");
            team.setTeamBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_TEAM.getCode()));
            //团队长
            team.setTeamLeaderId(csfClientUser.getClientUserBizId());
            team.setTeamLevel(1);
            iTeamService.saveOrUpdate(team);
            csfClientUser.setTeamBizId(team.getTeamBizId());
        }
        csfClientUserService.saveOrUpdate(csfClientUser);

        //根据绑定的基本法配置，新增基本法绑定表记录
        ApiCommissionRuleBindingRequest bindingRequest = new ApiCommissionRuleBindingRequest();
        bindingRequest.setTargetId(csfClientUser.getClientUserBizId());
        bindingRequest.setTargetName(csfClientUser.getName());
        bindingRequest.setTargetType("AGENT");
        bindingRequest.setStatus(1);
        bindingRequest.setRuleBizIdList(roleBizIdList);
        apiCommissionRuleBindingService.saveCommissionRuleBinding(bindingRequest);

        //根据选择的角色，对应更新相关的表（转介人表、签单员表、合伙人表等）
        if (roleBizIdList != null && roleBizIdList.contains(ClientRoleEnum.ZJR.getItemValue())) {
            // 处理转介人逻辑 => 更新或新增转介人信息 => 远程调用保险基础数据服务保存转介人表信息
            ApiUserSaleExpandSaveRequest saleExpandSaveRequest = new ApiUserSaleExpandSaveRequest();
            BeanUtils.copyProperties(csfClientUser,saleExpandSaveRequest);
            saleExpandSaveRequest.setRealName(csfClientUser.getName());
            saleExpandSaveRequest.setClientUserBizId(csfClientUser.getClientUserBizId());
            try {
                apiUserSaleExpandFeignClient.save(saleExpandSaveRequest);
            }catch (Exception e){
                log.info("处理转介人逻辑 => 更新或新增转介人信息 => 远程调用保险基础数据服务保存转介人表信息失败：{}",e.getMessage());
                throw new BusinessException(e.getMessage());
            }
        }
        if (roleBizIdList != null && roleBizIdList.contains(ClientRoleEnum.QDY.getItemValue())) {
            // 处理签单员逻辑 => 更新或新增签单员信息 => 远程调用保险基础数据服务保存签单员表信息
            ApiUserSignExpandSaveRequest signExpandSaveRequest = new ApiUserSignExpandSaveRequest();
            BeanUtils.copyProperties(csfClientUser,signExpandSaveRequest);
            signExpandSaveRequest.setRealName(csfClientUser.getName());
            signExpandSaveRequest.setClientUserBizId(csfClientUser.getClientUserBizId());
            try {
                apiUserSignExpandFeignClient.save(signExpandSaveRequest);
            }catch (Exception e){
                log.info("处理转介人逻辑 => 更新或新增转介人信息 => 远程调用保险基础数据服务保存签单员表信息失败：{}",e.getMessage());
                throw new BusinessException(e.getMessage());
            }
        }
        if (roleBizIdList != null && roleBizIdList.contains(ClientRoleEnum.HHR.getItemValue())) {
            // 处理合伙人逻辑 TODO
        }

        return Result.success();
    }

    /**
     * 新增-人员信息
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(ApiCsfClientUserAddRequest request) {
        if (request.getUserDTO() == null) {
            throw new BusinessException("人员基本信息不能为空");
        }
        if (request.getOrgDTO() == null) {
            request.setOrgDTO(new ApiCsfClientUserOrgDTO());
        }
        ApiCsfClientUserDTO userDTO = request.getUserDTO();
        //校验手机号的唯一性
        List<CsfClientUser> csfClientUserList = csfClientUserService.queryList(QueryCsfClientUserDTO.builder()
                .phone(userDTO.getPhone())
                .isMy(false)
                .build());
        if (CollectionUtils.isNotEmpty(csfClientUserList)) {
            throw new BusinessException("手机号已经存在");
        }
        //手机号+租户ID+项目ID->查询中心客户端用户表用户记录
        ApiClientUserConditionListRequest conditionListRequest = new ApiClientUserConditionListRequest();
        //租户ID
        conditionListRequest.setTenantBizId(TenantEnum.YD.getTenantBizId());
        //项目ID
        conditionListRequest.setProjectBizId(ProjectEnum.CSF_PC.getProjectBizId());
        //手机号
        conditionListRequest.setPhone(userDTO.getPhone());
        //手机号+租户ID+项目ID->查询中心客户端用户表用户记录
        Result<List<ApiClientUserDetailResponse>> result = apiClientUserFeignClient.conditionList(conditionListRequest);
        ApiClientUserDetailResponse response = null;
        if (result.getCode() == 200 && CollectionUtils.isNotEmpty(result.getData())) {
            response = new ApiClientUserDetailResponse();
            List<ApiClientUserDetailResponse> responses = result.getData();
            response = responses.get(0);
        }
        //新增人员信息入库
        CsfClientUser csfClientUser = new CsfClientUser();
        BeanUtils.copyProperties(userDTO,csfClientUser);

        //校验入参的所属团队和一级管理人所属团队是否匹配
        checkTeam(request.getOrgDTO(),csfClientUser.getTeamBizId());

        if (response != null) {
            //中心用户记录不为空，获取中心用户ID保存
            csfClientUser.setClientUserBizId(response.getClientUserBizId());
        }else {
            //中心用户记录为空，远程调用接口->创建中心用户
            ApiClientUserSaveRequest saveRequest = new ApiClientUserSaveRequest();
            saveRequest.setApprovalStatus(CommonEnum.APPROVAL_STATUS_CG.getCode());
            saveRequest.setName(userDTO.getName());
            saveRequest.setPhone(userDTO.getPhone());
            saveRequest.setEmail(userDTO.getEmail());
            saveRequest.setGender(Integer.parseInt(userDTO.getGender()));
            saveRequest.setIdCardType(userDTO.getCardType());
            saveRequest.setIdCardNumber(userDTO.getCardNo());
            //注册来源-PC
            saveRequest.setRegisterSource(CommonEnum.SOURCE_TYPE_PC.getCode());
            saveRequest.setStatus(1);
            //租户唯一业务ID
            saveRequest.setTenantBizId(TenantEnum.YD.getTenantBizId());
            //项目唯一业务ID
            saveRequest.setProjectBizId(ProjectEnum.CSF_PC.getProjectBizId());
            try {
                //远程调用中心用户微服务-保存中心客户端用户信息
                Result<ApiClientUserSaveResponse> saveResponseResult = apiClientUserFeignClient.save(saveRequest);
                if (saveResponseResult != null && saveResponseResult.getCode() == 200) {
                    ApiClientUserSaveResponse userSaveResponse = saveResponseResult.getData();
                    if (userSaveResponse != null) {
                        csfClientUser.setClientUserBizId(userSaveResponse.getClientUserBizId());
                    }
                }
            }catch (Exception e) {
                log.info("远程调用中心用户微服务-保存中心客户端用户信息失败：{}",e.getMessage());
                throw new BusinessException(e.getMessage());
            }
        }
        csfClientUser.setCsfClientUserBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_CSF_CLIENT_USER.getCode()));
        //绑定的客户端角色表表唯一业务ID列表（多个分号分隔）
        List<String> roleBizIdList = userDTO.getRoleDTOList().stream()
                .filter(d -> StringUtils.isNotBlank(d.getRoleBizId()))
                .map(ApiClientRoleDTO::getRoleBizId)
                .collect(Collectors.toList());
        csfClientUser.setRoleBizIds(CollectionUtils.isNotEmpty(roleBizIdList) ? String.join(";",roleBizIdList) : "");
        //绑定的基本法配置表唯一业务ID列表（多个分号分隔）
        List<String> ruleBizIdList = userDTO.getRuleDTOList().stream()
                .filter(d -> StringUtils.isNotBlank(d.getRuleBizId()))
                .map(ApiRuleDTO::getRuleBizId)
                .collect(Collectors.toList());
        csfClientUser.setRuleBizIds(CollectionUtils.isNotEmpty(ruleBizIdList) ? String.join(";",ruleBizIdList) : "");

        //当一级和二级都没有选择，说明是顶级根节点。那么所属团队不是选择，而是录入的团队名称。此时该人员是团队负责人，团队名称就是录入的名称。并且同步一份数据到团队表中
        List<ApiFirstLevelDTO> firstLevelDTOList = request.getOrgDTO().getFirstLevelDTOList();
        List<ApiSecondLevelDTO> secondLevelDTOList = request.getOrgDTO().getSecondLevelDTOList();
        if (CollectionUtils.isEmpty(firstLevelDTOList) && CollectionUtils.isEmpty(secondLevelDTOList)) {
            //保存团队信息
            Team team = iTeamService.lambdaQuery()
                    .eq(Team::getTeamLeaderId,csfClientUser.getClientUserBizId())
                    .last(" limit 1 ").one();
            if (team != null) {
                //更新团队名称即可
                team.setTeamName(userDTO.getTeamName());
                iTeamService.saveOrUpdate(team);
            }else {
                //新增团队信息
                Team team1 = new Team();
                team1.setTeamName(userDTO.getTeamName());
                team1.setPid("0");
                team1.setTeamBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_TEAM.getCode()));
                //TODO 团队编码
//                team1.setTeamCode();
                //团队长
                team1.setTeamLeaderId(csfClientUser.getClientUserBizId());
                team1.setTeamLevel(1);
                iTeamService.saveOrUpdate(team1);
                csfClientUser.setTeamBizId(team1.getTeamBizId());
            }
        }

        //合同签订日期
        csfClientUser.setContractSigningDate(userDTO.getContractSigningDate() != null ? userDTO.getContractSigningDate().toInstant()
                .atZone(ZoneId.of("GMT+8"))
                .toLocalDateTime() : null);
        //离职日
        csfClientUser.setLastWorkingDay(userDTO.getLastWorkingDay() != null ? userDTO.getLastWorkingDay().toInstant()
                .atZone(ZoneId.of("GMT+8"))
                .toLocalDateTime() : null);
        csfClientUserService.saveOrUpdate(csfClientUser);

        //根据初始化职级，fyc表（业务员累计积分表 - 存储业务员的累计FYC积分和当前等级信息）新增初始化记录
        ApiInitAgentAccumulatedFycRequest fycRequest = new ApiInitAgentAccumulatedFycRequest();
        fycRequest.setAgentId(csfClientUser.getClientUserBizId());
        fycRequest.setAgentName(csfClientUser.getName());
        fycRequest.setInitGrade(userDTO.getInitGradeCode());
        apiAgentAccumulatedFycService.initAgentAccumulatedFyc(fycRequest);

        //根据绑定的基本法配置，新增基本法绑定表记录
        ApiCommissionRuleBindingRequest bindingRequest = new ApiCommissionRuleBindingRequest();
        bindingRequest.setTargetId(csfClientUser.getClientUserBizId());
        bindingRequest.setTargetName(csfClientUser.getName());
        bindingRequest.setTargetType("AGENT");
        bindingRequest.setStatus(1);
        bindingRequest.setRuleBizIdList(ruleBizIdList);
        apiCommissionRuleBindingService.saveCommissionRuleBinding(bindingRequest);

        //保存用户银行列表信息
        apiUserBankService.saveUserBankList(csfClientUser,request.getBankDTOList());

        //根据选择的角色，对应更新相关的表（转介人表、签单员表、合伙人表等）
        if (roleBizIdList != null && roleBizIdList.contains(ClientRoleEnum.ZJR.getItemValue())) {
            // 处理转介人逻辑 => 更新或新增转介人信息 => 远程调用保险基础数据服务保存转介人表信息
            ApiUserSaleExpandSaveRequest saleExpandSaveRequest = new ApiUserSaleExpandSaveRequest();
            BeanUtils.copyProperties(csfClientUser,saleExpandSaveRequest);
            saleExpandSaveRequest.setRealName(csfClientUser.getName());
            saleExpandSaveRequest.setClientUserBizId(csfClientUser.getClientUserBizId());
            saleExpandSaveRequest.setRaNumber(csfClientUser.getRaNumber());
            saleExpandSaveRequest.setContractSigningDate(csfClientUser.getContractSigningDate());
            saleExpandSaveRequest.setLastWorkingDay(csfClientUser.getLastWorkingDay());
            saleExpandSaveRequest.setGender(Integer.parseInt(csfClientUser.getGender()));
            try {
                apiUserSaleExpandFeignClient.save(saleExpandSaveRequest);
            }catch (Exception e){
                log.info("处理转介人逻辑 => 更新或新增转介人信息 => 远程调用保险基础数据服务保存转介人表信息失败：{}",e.getMessage());
                throw new BusinessException(e.getMessage());
            }
        }
        if (roleBizIdList != null && roleBizIdList.contains(ClientRoleEnum.QDY.getItemValue())) {
            // 处理签单员逻辑 => 更新或新增签单员信息 => 远程调用保险基础数据服务保存签单员表信息
            ApiUserSignExpandSaveRequest signExpandSaveRequest = new ApiUserSignExpandSaveRequest();
            BeanUtils.copyProperties(csfClientUser,signExpandSaveRequest);
            signExpandSaveRequest.setRealName(csfClientUser.getName());
            signExpandSaveRequest.setClientUserBizId(csfClientUser.getClientUserBizId());
            signExpandSaveRequest.setRaNumber(csfClientUser.getRaNumber());
            signExpandSaveRequest.setContractSigningDate(csfClientUser.getContractSigningDate());
            signExpandSaveRequest.setLastWorkingDay(csfClientUser.getLastWorkingDay());
            signExpandSaveRequest.setGender(Integer.parseInt(csfClientUser.getGender()));
            try {
                apiUserSignExpandFeignClient.save(signExpandSaveRequest);
            }catch (Exception e){
                log.info("处理转介人逻辑 => 更新或新增转介人信息 => 远程调用保险基础数据服务保存签单员表信息失败：{}",e.getMessage());
                throw new BusinessException(e.getMessage());
            }
        }
        if (roleBizIdList != null && roleBizIdList.contains(ClientRoleEnum.HHR.getItemValue())) {
            // 处理合伙人逻辑 TODO
        }

        //处理组织关系
        handleOrgRel(request.getOrgDTO(),csfClientUser);

        return Result.success();
    }

    /**
     * 处理组织关系
     * @param orgDTO
     * @param csfClientUser
     * @return
     */
    public Result handleOrgRel(ApiCsfClientUserOrgDTO orgDTO,CsfClientUser csfClientUser) {
        //处理辅导关系
        apiAgentTutoringRelationService.saveAgentTutoringRelationList(orgDTO.getTutorDTOList(),csfClientUser.getClientUserBizId());
        //处理推荐关系
        apiAgentReferralRelationService.saveAgentReferralRelationList(orgDTO.getReferrerDTOList(),csfClientUser);

        //处理一级和二级关系
        //判断一级列表和二级列表是否都为空，如果都为空，说明当前人员作为根节点（顶级）。
        if (CollectionUtils.isEmpty(orgDTO.getFirstLevelDTOList())
                && CollectionUtils.isEmpty(orgDTO.getSecondLevelDTOList())) {
            //根节点
            AgentManageRelation agentManageRelation = new AgentManageRelation();
            agentManageRelation.setManageBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_AGENT_MANAGE_RELATION.getCode()));
            agentManageRelation.setAgentId(csfClientUser.getClientUserBizId());
            agentManageRelation.setIsActive(1);
            //一级管理人ID和二级管理人ID、父级人员ID为空
            //新增人员管理关系数据
            iAgentManageRelationService.saveOrUpdate(agentManageRelation);
        }else if (CollectionUtils.isNotEmpty(orgDTO.getFirstLevelDTOList())
                && CollectionUtils.isEmpty(orgDTO.getSecondLevelDTOList())) {
            //一级不为空并且二级为空
            //校验一级管理人是否有上级，如果有，则提示校验：必须传入一级管理人的上级（二级管理人）
            List<ApiFirstLevelDTO> firstLevelDTOList = orgDTO.getFirstLevelDTOList();
            ApiFirstLevelDTO firstLevelDTO = firstLevelDTOList.get(0);
            //查询一级管理关系信息
            AgentManageRelation agentManageRelation = iAgentManageRelationService.lambdaQuery()
                    .eq(AgentManageRelation::getAgentId,firstLevelDTO.getClientUserBizId())
                    .last(" limit 1 ")
                    .one();
            if (agentManageRelation == null) {
                throw new BusinessException("一级管理关系信息不存在");
            }
            if (StringUtils.isNotBlank(agentManageRelation.getPid())) {
                throw new BusinessException("一级管理人存在上级管理人，所以二级管理人必须传值");
            }
            //校验一级人员是否离职
            if (firstLevelDTO.getEmploymentStatus().equals("1")) {
                throw new BusinessException("一级管理人已离职，请重新选择一级管理人");
            }
            //一级管理没有上级=>当前二级管理人就是当前一级管理人
            //新增当前人员关系数据
            AgentManageRelation manageRelation = new AgentManageRelation();
            manageRelation.setManageBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_AGENT_MANAGE_RELATION.getCode()));
            manageRelation.setAgentId(csfClientUser.getClientUserBizId());
            manageRelation.setManageId(agentManageRelation.getAgentId());
            //二级管理人ID => 根据需求，如果一级管理人没有上级，那么二级就是默认是一级管理人作为二级
            manageRelation.setSManageId(agentManageRelation.getAgentId());
            manageRelation.setPid(agentManageRelation.getAgentId());
            manageRelation.setIsActive(1);
            iAgentManageRelationService.saveOrUpdate(manageRelation);
        }else if (CollectionUtils.isNotEmpty(orgDTO.getFirstLevelDTOList())
                && CollectionUtils.isNotEmpty(orgDTO.getSecondLevelDTOList())) {
            //一二级都不为空
            List<ApiFirstLevelDTO> firstLevelDTOList = orgDTO.getFirstLevelDTOList();
            ApiFirstLevelDTO firstLevelDTO = firstLevelDTOList.get(0);
            //查询一级管理关系信息
            AgentManageRelation agentManageRelation = iAgentManageRelationService.lambdaQuery()
                    .eq(AgentManageRelation::getAgentId,firstLevelDTO.getClientUserBizId())
                    .last(" limit 1 ")
                    .one();
            if (agentManageRelation == null) {
                throw new BusinessException("一级管理关系信息不存在");
            }
            List<ApiSecondLevelDTO> secondLevelDTOList = orgDTO.getSecondLevelDTOList();
            ApiSecondLevelDTO secondLevelDTO = secondLevelDTOList.get(0);
            //查询二级管理关系信息
            AgentManageRelation sAgentManageRelation = iAgentManageRelationService.lambdaQuery()
                    .eq(AgentManageRelation::getAgentId,secondLevelDTO.getClientUserBizId())
                    .last(" limit 1 ")
                    .one();
            if (sAgentManageRelation == null) {
                throw new BusinessException("二级管理关系信息不存在");
            }
            //校验入参的二级管理人必须和一级管理人的上级是同一个人
            if (!secondLevelDTO.getClientUserBizId().equals(agentManageRelation.getPid())) {
                //不是同一个人
                throw new BusinessException("入参的二级管理人必须和一级管理人的上级是同一个人");
            }
            //校验一级管理人是否离职
            if (firstLevelDTO.getEmploymentStatus().equals("1")) {
                throw new BusinessException("一级管理人已离职，请重新选择一级管理人");
            }
            //校验二级管理人是否离职
            if (secondLevelDTO.getEmploymentStatus().equals("1")) {
                throw new BusinessException("二级管理人已离职，请重新选择一级管理人或者一级管理人做组织迁移");
            }
            //新增当前人员关系数据
            AgentManageRelation manageRelation = new AgentManageRelation();
            manageRelation.setManageBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_AGENT_MANAGE_RELATION.getCode()));
            manageRelation.setAgentId(csfClientUser.getClientUserBizId());
            //一级管理人ID
            manageRelation.setManageId(firstLevelDTO.getClientUserBizId());
            //二级管理人ID
            manageRelation.setSManageId(secondLevelDTO.getClientUserBizId());
            //父级ID = 一级管理人ID
            manageRelation.setPid(firstLevelDTO.getClientUserBizId());
            manageRelation.setIsActive(1);
            iAgentManageRelationService.saveOrUpdate(manageRelation);
        }

        return Result.success();
    }

    /**
     * 校验入参的所属团队和一级管理人所属团队是否匹配
     * @param orgDTO
     * @param teamBizId
     */
    public void checkTeam(ApiCsfClientUserOrgDTO orgDTO,String teamBizId) {
        //必须是选择了一级管理，才作为校验基础
        List<ApiFirstLevelDTO> firstLevelDTOList = orgDTO.getFirstLevelDTOList();
        if (CollectionUtils.isEmpty(firstLevelDTOList)) {
            return;
        }
        ApiFirstLevelDTO apiFirstLevelDTO = firstLevelDTOList.get(0);
        if (!apiFirstLevelDTO.getTeamBizId().equals(teamBizId)) {
            //入参的所属团队和一级管理人所属团队不匹配，提示。
            throw new BusinessException("所属团队和一级管理人所属团队必须一致，请重新选择");
        }
    }

}
