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

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.csf.api.service.*;
import com.yd.csf.feign.dto.clientrole.ApiClientRoleDTO;
import com.yd.csf.feign.dto.csfclientuser.ApiCsfClientUserDTO;
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.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.ApiCsfClientUserPageRequest;
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.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 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.util.ArrayList;
import java.util.Arrays;
import java.util.List;
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 IClientRoleService iClientRoleService;

    @Resource
    private IUserBankService iUserBankService;

    @Resource
    private ICommissionRuleConfigService iCommissionRuleConfigService;

    @Resource
    private IAgentTutoringRelationService iAgentTutoringRelationService;

    @Resource
    private IAgentReferralRelationService iAgentReferralRelationService;

    @Resource
    private ApiClientUserFeignClient apiClientUserFeignClient;

    @Resource
    private ApiUserSaleExpandFeignClient apiUserSaleExpandFeignClient;

    @Resource
    private ApiUserSignExpandFeignClient apiUserSignExpandFeignClient;

    /**
     * 分页查询-人员信息
     * @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);
        //一级和二级列表 TODO
        response.setOrgDTO(orgDTO);
        return Result.success(response);
    }

    /**
     * 获取推荐列表
     * @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()
                .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()
                .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;
    }

    /**
     * 新增-人员信息
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(ApiCsfClientUserAddRequest request) {
        if (request.getUserDTO() == null) {
            throw new BusinessException("人员基本信息不能为空");
        }
        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);
        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());
            //注册来源-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) : "");
        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(roleBizIdList);
        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());
            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
        }

        //处理组织关系
        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);

        //处理一级和二级关系 TODO
        return Result.success();
    }

}
