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

import com.red.circle.other.app.dto.clientobject.TeamBdMonthlyIncomeCO;
import com.red.circle.other.app.dto.cmd.TeamBdMonthlyIncomeCmd;
import com.red.circle.other.infra.database.mongo.dto.team.TeamBillSettleResult;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamBillCycle;
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.rds.entity.team.BusinessDevelopmentTeam;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentTeamService;
import com.red.circle.other.inner.endpoint.team.bd.BdTeamLeaderClient;
import com.red.circle.other.inner.enums.team.TeamBillCycleStatus;
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.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 查询 BD 团队月度收入执行器.
 *
 * @author tf
 * @since 2025-10-28
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class TeamBdMonthlyIncomeQryExe {

    private final BusinessDevelopmentTeamService businessDevelopmentTeamService;
    private final TeamBillCycleService teamBillCycleService;
    private final BdTeamLeaderClient bdTeamLeaderClient;

    /**
     * 执行查询.
     *
     * @param cmd 查询命令
     * @return 月度收入汇总
     */
    public TeamBdMonthlyIncomeCO execute(TeamBdMonthlyIncomeCmd cmd) {
        TeamBdMonthlyIncomeCO co = new TeamBdMonthlyIncomeCO();

        // 1. 查询BD关联的所有代理
        List<BusinessDevelopmentTeam> bdTeamList = new ArrayList<>();
        if ("BD".equals(cmd.getType())) {
          bdTeamList.addAll(businessDevelopmentTeamService.listByUserId(cmd.getReqUserId()));
        } else {
          bdTeamList.add(businessDevelopmentTeamService.getByAgentId(cmd.getReqUserId()));
        }

        if (CollectionUtils.isEmpty(bdTeamList)) {
            co.setTotalIncome(BigDecimal.ZERO);
            co.setPreviousPeriodIncome(BigDecimal.ZERO);
            return co;
        }

        // 2. 获取所有团队ID
        Set<Long> teamIdSet = bdTeamList.stream()
                .map(BusinessDevelopmentTeam::getTeamId)
                .collect(Collectors.toSet());

        // 3. 获取当前账单周期 billBelong
        Integer currentBillBelong = TeamBillCycleUtils.getCalcBillBelong();

        // 4. 获取上一个账单周期 billBelong
        Integer previousBillBelong = calculatePreviousBillBelong(currentBillBelong);

        // 5. 查询当前周期的账单（当月总收入）
        Map<Long, TeamBillCycle> currentBillCycleMap = teamBillCycleService.mapByTeamIds(
                teamIdSet, currentBillBelong, TeamBillCycleStatus.SETTLED);

        // 6. 查询上一个周期的账单（上期收入）
        Map<Long, TeamBillCycle> previousBillCycleMap = teamBillCycleService.mapByTeamIds(
                teamIdSet, previousBillBelong, TeamBillCycleStatus.SETTLED);

        // 8. 计算当月总收入
        BigDecimal totalIncome = calculateTotalIncome(currentBillCycleMap);

        // 9. 计算上期收入
        BigDecimal previousPeriodIncome = calculateTotalIncome(previousBillCycleMap);

        co.setTotalIncome(totalIncome);
        co.setPreviousPeriodIncome(previousPeriodIncome);
        return co;
    }

    /**
     * 计算总收入（薪资收入 + 充值收入）.
     */
    private BigDecimal calculateTotalIncome(Map<Long, TeamBillCycle> billCycleMap) {
        if (CollectionUtils.isEmpty(billCycleMap)) {
            return BigDecimal.ZERO;
        }

        BigDecimal salaryRatio = new BigDecimal("0.03"); // 3%
        BigDecimal rechargeRatio = new BigDecimal("0.05"); // 5%

        BigDecimal totalIncome = BigDecimal.ZERO;

        for (TeamBillCycle billCycle : billCycleMap.values()) {
            TeamBillSettleResult settleResult = billCycle.getSettleResult();
            if (settleResult != null) {
                // BD薪资收益
                BigDecimal salaryIncome = Optional.ofNullable(settleResult.getTotalSalary())
                        .orElse(BigDecimal.ZERO)
                        .multiply(salaryRatio);

                // BD充值收益
                BigDecimal rechargeIncome = Optional.ofNullable(BigDecimal.ZERO)
                        .orElse(BigDecimal.ZERO)
                        .multiply(rechargeRatio);

                totalIncome = totalIncome.add(salaryIncome).add(rechargeIncome);
            }
        }

        return totalIncome;
    }

    /**
     * 计算可提现收入（所有已完成账单的收入总和）.
     */
    private BigDecimal calculateAvailableIncome(List<TeamBillCycle> completedBills) {
        if (CollectionUtils.isEmpty(completedBills)) {
            return BigDecimal.ZERO;
        }

        BigDecimal salaryRatio = new BigDecimal("0.03"); // 3%
        BigDecimal rechargeRatio = new BigDecimal("0.05"); // 5%

        BigDecimal availableIncome = BigDecimal.ZERO;

        for (TeamBillCycle billCycle : completedBills) {
            TeamBillSettleResult settleResult = billCycle.getSettleResult();
            if (settleResult != null) {
                // BD薪资收益
                BigDecimal salaryIncome = Optional.ofNullable(settleResult.getTotalSalary())
                        .orElse(BigDecimal.ZERO)
                        .multiply(salaryRatio);

                // BD充值收益
                BigDecimal rechargeIncome = Optional.ofNullable(BigDecimal.ZERO)
                        .orElse(BigDecimal.ZERO)
                        .multiply(rechargeRatio);

                availableIncome = availableIncome.add(salaryIncome).add(rechargeIncome);
            }
        }

        return availableIncome;
    }

    /**
     * 计算上一个账单周期.
     *
     * @param currentBillBelong 当前账单周期（格式：20251001 或 20251016）
     * @return 上一个账单周期
     */
    private Integer calculatePreviousBillBelong(Integer currentBillBelong) {
        if (currentBillBelong == null) {
            return null;
        }

        String billBelongStr = String.valueOf(currentBillBelong);
        int year = Integer.parseInt(billBelongStr.substring(0, 4));
        int month = Integer.parseInt(billBelongStr.substring(4, 6));
        int day = Integer.parseInt(billBelongStr.substring(6, 8));

        LocalDate currentDate = LocalDate.of(year, month, day);
        LocalDate previousDate;

        if (day == 1) {
            // 当前是1号，上一个周期是上个月的16号
            previousDate = currentDate.minusMonths(1).withDayOfMonth(16);
        } else {
            // 当前是16号，上一个周期是本月的1号
            previousDate = currentDate.withDayOfMonth(1);
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        return Integer.parseInt(previousDate.format(formatter));
    }

}
