package com.red.circle.other.app.command.team.query;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.dto.clientobject.team.BdPageCO;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamProfile;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamProfileService;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentBaseInfo;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentTeam;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorService;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentBaseInfoService;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentTeamService;
import com.red.circle.other.inner.endpoint.team.target.TeamProfileClient;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.cmd.team.bd.BdTeamPageQryCmd;
import com.red.circle.other.inner.model.dto.agency.bd.BdTeamInfoDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.sql.Wrapper;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
@RequiredArgsConstructor
public class BdListQryExe {

    private final BusinessDevelopmentBaseInfoService businessDevelopmentBaseInfoService;
    private final BusinessDevelopmentTeamService  businessDevelopmentTeamService;
    private final UserProfileClient userProfileClient;
    private final AdministratorService administratorService;
    private final TeamProfileService teamProfileService;

    public PageResult<BdPageCO> pageResult(BdTeamPageQryCmd qryCmd) {
        boolean b = administratorService.existsAdmin(qryCmd.getUserId());
        if(!b) {
            ResponseAssert.failure(CommonErrorCode.OPERATING_FAILURE);
        }

        PageResult<BusinessDevelopmentBaseInfo> pageResult = businessDevelopmentBaseInfoService.query()
                .eq(StringUtils.isNotBlank(qryCmd.getRegion()), BusinessDevelopmentBaseInfo::getRegion,
                        qryCmd.getRegion())
                .eq(StringUtils.isNotBlank(qryCmd.getSysOrigin()),
                        BusinessDevelopmentBaseInfo::getSysOrigin,
                        qryCmd.getSysOrigin())
                .eq(BusinessDevelopmentBaseInfo::getBdLeadUserId, qryCmd.getUserId())
                .orderByDesc(BusinessDevelopmentBaseInfo::getCreateTime)
                .page(qryCmd.getPageQuery());

        if ( pageResult == null || pageResult.getRecords().isEmpty() ) {
            return null;
        }

        Set<Long> userIds = getUserIds(pageResult.getRecords());
        Map<Long, UserProfileDTO> userMap = userProfileClient.mapByUserIds(userIds).getBody();

        //主播数量
        LambdaQueryWrapper<BusinessDevelopmentTeam> in = Wrappers.lambdaQuery(BusinessDevelopmentTeam.class)
                .select(BusinessDevelopmentTeam::getId, BusinessDevelopmentTeam::getTeamId, BusinessDevelopmentTeam::getUserId)
                .in(BusinessDevelopmentTeam::getUserId, userIds);
        List<BusinessDevelopmentTeam> teamIdList = businessDevelopmentTeamService.list(in);
        Map<Long, Long> teamUserIdMap = teamIdList.stream().collect(Collectors.toMap(BusinessDevelopmentTeam::getTeamId, BusinessDevelopmentTeam::getUserId, (v1, v2) -> v1));
        Set<Long> teamIdSet = teamIdList.stream().map(BusinessDevelopmentTeam::getTeamId).collect(Collectors.toSet());
        Map<Long, Long> teamMemberQuantityMap = teamProfileService.getByIds(teamIdSet).stream()
                .collect(Collectors.toMap(key -> teamUserIdMap.get(key.getId()),
                        e -> e.getCounter().getMemberQuantity(),
                        Long::sum));

        return pageResult.convert(info -> new BdPageCO()
                .setId(info.getId())
                .setSysOrigin(info.getSysOrigin())
                .setUserId(info.getUserId())
                .setUserProfile(userMap.get(info.getUserId()))
                .setAgentCount(info.getMemberQuantity())
                .setBdLeadUserId(info.getBdLeadUserId())
                .setAllAnchorCount(teamMemberQuantityMap.get(info.getUserId()))
                .setContact(info.getContact())
                .setRegion(info.getRegion())
                .setCreateTime(info.getCreateTime())
                .setUpdateTime(info.getUpdateTime()));
    }

    private Set<Long> getUserIds(Collection<BusinessDevelopmentBaseInfo> bdList) {
        return Stream.of(
                        bdList.stream()
                                .map(BusinessDevelopmentBaseInfo::getUserId)
                                .collect(Collectors.toSet()),
                        bdList.stream()
                                .map(BusinessDevelopmentBaseInfo::getBdLeadUserId)
                                .collect(Collectors.toSet()))
                .flatMap(Collection::stream)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
    }

}
