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

import com.alibaba.fastjson.JSON;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.BdIncomeDetailCO;
import com.red.circle.other.app.dto.clientobject.BdIncomeDetailMemberCO;
import com.red.circle.other.app.dto.clientobject.BdTeamMemberDetailCO;
import com.red.circle.other.app.dto.clientobject.BdTeamOverviewCO;
import com.red.circle.other.app.dto.cmd.BdTeamMemberDetailQueryCmd;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.mongo.dto.team.TeamBillMemberTarget;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamBillCycle;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamPolicyManager;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamProfile;
import com.red.circle.other.infra.database.mongo.service.team.TeamBillCycleUtils;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamBillCycleService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberTargetService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamPolicyManagerService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamProfileService;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentTeam;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentTeamService;
import com.red.circle.other.inner.asserts.team.TeamErrorCode;
import com.red.circle.other.inner.enums.team.TeamBillCycleStatus;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * BD团队成员详情查询执行器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class BdTeamMemberDetailQryExe {

    private final TeamBillCycleService teamBillCycleService;
    private final TeamMemberTargetService teamMemberTargetService;
    private final TeamPolicyManagerService teamPolicyManagerService;
    private final BusinessDevelopmentTeamService businessDevelopmentTeamService;
    private final UserProfileGateway userProfileGateway;
    private final UserProfileAppConvertor userProfileAppConvertor;
    private final TeamProfileService teamProfileService;
    private final RedisService redisService;

    /**
     * 执行查询
     */
    public BdTeamMemberDetailCO execute(BdTeamMemberDetailQueryCmd cmd) {
        String type = cmd.getType();
        Long targetId = cmd.getTargetId();

        // 缓存查询
        String cacheKey = "bdteam:detail:" + type + ":" + targetId;
        BdTeamMemberDetailCO cached = redisService.getStringToObject(cacheKey, BdTeamMemberDetailCO.class);
        if (cached != null) {
            return cached;
        }

        // 查询数据
        BdTeamMemberDetailCO result;
        if ("AGENCY".equals(type)) {
            // Agency视角：查询单个team的数据
            result = queryAgencyDetail(targetId);
        } else if ("BD".equals(type)) {
            // BD视角：查询该BD下所有team的汇总数据
            result = queryBdDetail(targetId);
        } else {
            result = new BdTeamMemberDetailCO();
        }

        // 缓存结果（1分钟）
        redisService.setString(cacheKey, JSON.toJSONString(result), 1, TimeUnit.MINUTES);

        return result;
    }

    /**
     * 查询Agency详情（单个team）
     */
    private BdTeamMemberDetailCO queryAgencyDetail(Long userId) {
        BdTeamMemberDetailCO detail = new BdTeamMemberDetailCO();
        TeamProfile teamProfile = teamProfileService.getByOwnUserId(userId);
        ResponseAssert.notNull(TeamErrorCode.NOT_TEAM_MEMBER, teamProfile);

        // 查询最近2个账单周期
        List<TeamBillCycle> teamBillCycles = teamBillCycleService.listLatestBill(teamProfile.getId(), 2);
        
        if (CollectionUtils.isEmpty(teamBillCycles)) {
            detail.setTotalIncome(BigDecimal.ZERO);
            detail.setPreviousPeriodIncome(BigDecimal.ZERO);
            detail.setIncomeDetails(Collections.emptyList());
            return detail;
        }

        // 获取所有区域的政策配置
        Map<String, TeamPolicyManager> regionPolicyMap = teamPolicyManagerService.mapRegionReleaseWithCountry(
                teamBillCycles.stream().map(TeamBillCycle::getRegion).collect(Collectors.toSet()));

        List<BdIncomeDetailCO> incomeDetails = new ArrayList<>();
        
        for (TeamBillCycle teamBillCycle : teamBillCycles) {
            if (Objects.isNull(teamBillCycle)) {
                continue;
            }

            // 查询该账单周期下的所有成员目标数据
            List<TeamMemberTarget> teamMemberTargets = teamMemberTargetService.listByBillBelong(
                    teamBillCycle.getTeamId(), teamBillCycle.getBillBelong());

            BdIncomeDetailCO incomeDetail = buildIncomeDetail(
                    teamBillCycle, teamMemberTargets, regionPolicyMap);
            
            incomeDetails.add(incomeDetail);
        }

        // 计算总收入和上期收入
        detail.setIncomeDetails(incomeDetails);
        if (incomeDetails.size() >= 1) {
            detail.setTotalIncome(incomeDetails.get(0).getTeamTotalIncome());
        } else {
            detail.setTotalIncome(BigDecimal.ZERO);
        }
        
        if (incomeDetails.size() >= 2) {
            detail.setPreviousPeriodIncome(incomeDetails.get(1).getTeamTotalIncome());
        } else {
            detail.setPreviousPeriodIncome(BigDecimal.ZERO);
        }

        return detail;
    }

    /**
     * 查询BD详情（多个team汇总）
     */
    private BdTeamMemberDetailCO queryBdDetail(Long bdUserId) {
        BdTeamMemberDetailCO detail = new BdTeamMemberDetailCO();

        // 查询该BD的所有团队
        List<BusinessDevelopmentTeam> bdTeamList = businessDevelopmentTeamService.listByUserId(bdUserId);
        
        if (CollectionUtils.isEmpty(bdTeamList)) {
            detail.setTotalIncome(BigDecimal.ZERO);
            detail.setPreviousPeriodIncome(BigDecimal.ZERO);
            detail.setIncomeDetails(Collections.emptyList());
            return detail;
        }

        Set<Long> teamIdSet = bdTeamList.stream()
                .map(BusinessDevelopmentTeam::getTeamId)
                .collect(Collectors.toSet());

        // 为每个team查询最近2个账单周期
        Map<Long, List<TeamBillCycle>> teamBillMap = new HashMap<>();
        for (Long teamId : teamIdSet) {
            List<TeamBillCycle> bills = teamBillCycleService.listLatestBill(teamId, 2);
            if (CollectionUtils.isNotEmpty(bills)) {
                teamBillMap.put(teamId, bills);
            }
        }

        // 按周期分组汇总
        Map<Integer, List<TeamBillCycle>> billBelongMap = new HashMap<>();
        for (List<TeamBillCycle> bills : teamBillMap.values()) {
            for (TeamBillCycle bill : bills) {
                billBelongMap.computeIfAbsent(bill.getBillBelong(), k -> new ArrayList<>()).add(bill);
            }
        }

        // 获取所有区域的政策配置
        Set<String> allRegions = teamBillMap.values().stream()
                .flatMap(List::stream)
                .map(TeamBillCycle::getRegion)
                .collect(Collectors.toSet());
        Map<String, TeamPolicyManager> regionPolicyMap = teamPolicyManagerService.mapRegionReleaseWithCountry(allRegions);

        // 按周期构建收入明细
        List<BdIncomeDetailCO> incomeDetails = new ArrayList<>();
        List<Integer> sortedBillBelongs = billBelongMap.keySet().stream()
                .sorted(Comparator.reverseOrder())
                .toList();

        for (Integer billBelong : sortedBillBelongs) {
            List<TeamBillCycle> billsInPeriod = billBelongMap.get(billBelong);
            BdIncomeDetailCO incomeDetail = buildBdIncomeDetailForPeriod(
                    billBelong, billsInPeriod, regionPolicyMap, bdTeamList);
            incomeDetails.add(incomeDetail);
        }

        // 计算总收入和上期收入
        detail.setIncomeDetails(incomeDetails);
        if (incomeDetails.size() >= 1) {
            detail.setTotalIncome(incomeDetails.get(0).getTeamTotalIncome());
        } else {
            detail.setTotalIncome(BigDecimal.ZERO);
        }
        
        if (incomeDetails.size() >= 2) {
            detail.setPreviousPeriodIncome(incomeDetails.get(1).getTeamTotalIncome());
        } else {
            detail.setPreviousPeriodIncome(BigDecimal.ZERO);
        }

        return detail;
    }

    /**
     * 构建单个周期的收入明细（Agency视角）
     */
    private BdIncomeDetailCO buildIncomeDetail(
            TeamBillCycle teamBillCycle,
            List<TeamMemberTarget> teamMemberTargets,
            Map<String, TeamPolicyManager> policyManagerMap) {

        BdIncomeDetailCO incomeDetail = new BdIncomeDetailCO();

        // 设置周期信息
        String[] dates = TeamBillCycleUtils.parseBillBelongToDateRange(teamBillCycle.getBillBelong());
        incomeDetail.setSettlementPeriod(dates[0] + "-" + dates[1]);
        
        // 判断状态
        incomeDetail.setStatus(TeamBillCycleStatus.UNPAID == teamBillCycle.getStatus() ? "In Progress" : "Completed");

        if (CollectionUtils.isEmpty(teamMemberTargets)) {
            incomeDetail.setMemberCount(0);
            incomeDetail.setTeamTotalIncome(BigDecimal.ZERO);
            incomeDetail.setMembers(Collections.emptyList());
            return incomeDetail;
        }

        // 计算每个成员的政策目标数据
        List<TeamBillMemberTarget> memberTargetList = new ArrayList<>();
        for (TeamMemberTarget target : teamMemberTargets) {
            TeamPolicyManager policy = TeamBillCycleUtils.getPolicyFromMap(
                    policyManagerMap,
                    target.getRegion(),
                    target.getCountryCode());
            TeamBillMemberTarget teamBillMemberTarget = TeamBillCycleUtils.calculatorPolicyTarget(target, policy);
            memberTargetList.add(teamBillMemberTarget);
        }

        // 设置成员数量和总收入
        incomeDetail.setMemberCount(memberTargetList.size());
        BigDecimal totalIncome = memberTargetList.stream()
                .map(TeamBillMemberTarget::getTotalSalary)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        incomeDetail.setTeamTotalIncome(totalIncome);

        // 构建成员详细列表
        Set<Long> memberIds = memberTargetList.stream()
                .map(TeamBillMemberTarget::getUserId)
                .collect(Collectors.toSet());
        Map<Long, UserProfileDTO> userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
                userProfileGateway.mapByUserIds(memberIds));

        List<BdIncomeDetailMemberCO> members = new ArrayList<>();
        for (TeamBillMemberTarget memberTarget : memberTargetList) {
            BdIncomeDetailMemberCO member = new BdIncomeDetailMemberCO();
            
            UserProfileDTO userProfile = userProfileMap.get(memberTarget.getUserId());
            if (userProfile != null) {
                member.setUserId(userProfile.getId().toString());
                member.setUserName(userProfile.getUserNickname());
                member.setAvatar(userProfile.getUserAvatar());
                member.setAccount(userProfile.getAccount());
            }
            
            member.setIncome(memberTarget.getTotalSalary());
            members.add(member);
        }

        incomeDetail.setMembers(members);

        return incomeDetail;
    }

    /**
     * 构建BD某个周期的收入明细（汇总多个team）
     */
    private BdIncomeDetailCO buildBdIncomeDetailForPeriod(
            Integer billBelong,
            List<TeamBillCycle> billsInPeriod,
            Map<String, TeamPolicyManager> regionPolicyMap,
            List<BusinessDevelopmentTeam> bdTeamList) {

        BdIncomeDetailCO incomeDetail = new BdIncomeDetailCO();

        // 设置周期信息
        String[] dates = TeamBillCycleUtils.parseBillBelongToDateRange(billBelong);
        incomeDetail.setSettlementPeriod(dates[0] + "-" + dates[1]);
        
        // 判断状态
        if (!billsInPeriod.isEmpty()) {
            incomeDetail.setStatus(TeamBillCycleStatus.UNPAID == billsInPeriod.get(0).getStatus() ? "In Progress" : "Completed");
        }

        // 汇总所有team的收入
        BigDecimal totalIncome = BigDecimal.ZERO;
        List<BdIncomeDetailMemberCO> members = new ArrayList<>();

        // 获取所有Agency的用户信息
        Map<Long, Long> teamIdToAgentIdMap = bdTeamList.stream()
                .collect(Collectors.toMap(
                        BusinessDevelopmentTeam::getTeamId,
                        BusinessDevelopmentTeam::getAgentId,
                        (existing, replacement) -> existing
                ));

        Set<Long> agentIds = new HashSet<>(teamIdToAgentIdMap.values());
        Map<Long, UserProfileDTO> userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
                userProfileGateway.mapByUserIds(agentIds));

        for (TeamBillCycle bill : billsInPeriod) {
            // 查询该team的成员目标
            List<TeamMemberTarget> teamMemberTargets = teamMemberTargetService.listByBillBelong(
                    bill.getTeamId(), bill.getBillBelong());

            if (CollectionUtils.isEmpty(teamMemberTargets)) {
                continue;
            }

            // 计算team收入
            List<TeamBillMemberTarget> memberTargetList = new ArrayList<>();
            for (TeamMemberTarget target : teamMemberTargets) {
                TeamPolicyManager policy = TeamBillCycleUtils.getPolicyFromMap(
                        regionPolicyMap,
                        target.getRegion(),
                        target.getCountryCode());
                TeamBillMemberTarget teamBillMemberTarget = TeamBillCycleUtils.calculatorPolicyTarget(target, policy);
                memberTargetList.add(teamBillMemberTarget);
            }

            BigDecimal teamIncome = memberTargetList.stream()
                    .map(TeamBillMemberTarget::getTotalSalary)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            totalIncome = totalIncome.add(teamIncome);

            // 构建Agency成员信息
            Long agentId = teamIdToAgentIdMap.get(bill.getTeamId());
            if (agentId != null) {
                BdIncomeDetailMemberCO member = new BdIncomeDetailMemberCO();
                
                UserProfileDTO userProfile = userProfileMap.get(agentId);
                if (userProfile != null) {
                    member.setUserId(userProfile.getId().toString());
                    member.setUserName(userProfile.getUserNickname());
                    member.setAvatar(userProfile.getUserAvatar());
                    member.setAccount(userProfile.getAccount());
                }
                
                member.setIncome(teamIncome);
                members.add(member);
            }
        }

        incomeDetail.setTeamTotalIncome(totalIncome);
        incomeDetail.setMembers(members);
        // 设置Agency数量
        incomeDetail.setMemberCount(members.size());
        return incomeDetail;
    }
}
