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

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.dto.cmd.app.AppIdLongCmd;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.other.app.convertor.team.TeamAppConvertor;
import com.red.circle.other.app.dto.clientobject.team.*;
import com.red.circle.other.domain.model.user.UserProfile;
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.user.region.SysRegionConfig;
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.user.region.SysRegionConfigService;
import com.red.circle.other.infra.database.rds.entity.team.BillDiamondBalance;
import com.red.circle.other.infra.database.rds.entity.team.BillDiamondBalanceDetails;
import com.red.circle.other.infra.database.rds.service.team.BillDiamondBalanceDetailsService;
import com.red.circle.other.infra.database.rds.service.team.BillDiamondBalanceService;
import com.red.circle.other.inner.enums.team.TeamBillCycleStatus;
import com.red.circle.other.inner.enums.team.TeamMemberTargetIndex;
import com.red.circle.other.inner.enums.team.TeamMemberTargetStatus;
import com.red.circle.other.inner.enums.team.TeamPolicyTypeEnum;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.num.NumUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 团队账单.
 *
 * @author pengliang on 2022/12/27
 */
@Component
@RequiredArgsConstructor
public class TeamBillQryExe {

  private static final Logger log = LoggerFactory.getLogger(TeamBillQryExe.class);
  private final TeamAppConvertor teamAppConvertor;
  private final TeamBillCycleService teamBillCycleService;
  private final TeamMemberTargetService teamMemberTargetService;
  private final TeamPolicyManagerService teamPolicyManagerService;
  private final BillDiamondBalanceService billDiamondBalanceService;

  public List<TeamBillCO> execute(AppIdLongCmd cmd) {

    List<TeamBillCycle> teamBillCycles = teamBillCycleService.listLatestBill(cmd.getId(),
        PageConstant.MAX_LIMIT_SIZE);

    if (CollectionUtils.isEmpty(teamBillCycles)) {
      return Lists.newArrayList();
    }
    List<TeamBillCO> teamBill = teamBillCycles.stream().map(teamAppConvertor::toTeamBillCO).collect(Collectors.toList());
    for (TeamBillCO teamBillCO : teamBill) {
      if (!Objects.isNull(teamBillCO.getSettleResult())) {
        BillDiamondBalance billDiamondBalance = billDiamondBalanceService
                .getEntityByBillBelongAndUserId(SysOriginPlatformEnum.TARAB.name(), teamBillCO.getBillBelong(), cmd.getReqUserId());
        if (!Objects.isNull(billDiamondBalance)) {
          teamBillCO.getSettleResult().setRedeemedSalary(Objects.isNull(billDiamondBalance.getConsumptionPoints()) ? BigDecimal.ZERO : billDiamondBalance.getConsumptionPoints());
        } else {
          teamBillCO.getSettleResult().setRedeemedSalary(BigDecimal.ZERO);
        }
        // 用户剩余工资=用户工资-用户已兑换工资
        BigDecimal surplusSalary = teamBillCO.getSettleResult().getOwnSalary().subtract(teamBillCO.getSettleResult().getRedeemedSalary());
        teamBillCO.getSettleResult().setSurplusSalary(surplusSalary);
      }
    }
    return teamBill;
  }

  /**
   * 查询代理的团队账单列表（包含每个账单的累计成员数据）.
   *
   * @param cmd 查询命令
   * @return 账单列表
   */
  public List<TeamBillCO> executeAgent(AppIdLongCmd cmd) {

    List<TeamBillCycle> teamBillCycles = teamBillCycleService.listLatestBill(cmd.getId(), 5);
    
    if (CollectionUtils.isEmpty(teamBillCycles)) {
      return Lists.newArrayList();
    }

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

    List<TeamBillCO> result = Lists.newArrayList();
    
    for (TeamBillCycle teamBillCycle : teamBillCycles) {
      if (Objects.isNull(teamBillCycle)) {
        continue;
      }

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

      if (CollectionUtils.isEmpty(teamMemberTargets)) {
        // 如果没有成员数据，仍然返回账单基本信息
        TeamBillCO teamBillCO = teamAppConvertor.toTeamBillCO(teamBillCycle);
        result.add(teamBillCO);
        continue;
      }

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

      // 转换为账单CO对象
      TeamBillCO teamBillCO = teamAppConvertor.toTeamBillCO(teamBillCycle);
      teamBillCO.setBillTitle(TeamBillCycleUtils.parseBillBelongToDateRangeStr(teamBillCO.getBillBelong()));

      // 设置累计的成员结算结果
      if (!CollectionUtils.isEmpty(memberTargetList)) {
        List<TeamMemberTargetSettlementResultCO> settlementResults = memberTargetList.stream()
            .map(teamAppConvertor::toTeamMemberTargetSettlementResultCO)
            .collect(Collectors.toList());
        
        // 汇总所有成员的结算结果
        TeamBillSettleResultCO settleResult = aggregateSettlementResults(settlementResults);
        teamBillCO.setSettleResult(settleResult);
      }
      
      result.add(teamBillCO);
    }

    return result;
  }

  private static List<TeamMemberTargetIndex> filter(List<TeamMemberTargetIndex> stringList, Integer dateNumBer) {
    stringList = stringList.stream().filter(item -> {
      return item.getDateNumber().equals(dateNumBer);
    }).collect(Collectors.toList());
    return stringList;
  }

  private Map<String, String> getMetadata(SysRegionConfig regionConfig) {
    return Optional.ofNullable(regionConfig)
            .map(SysRegionConfig::getMetadata).orElseGet(CollectionUtils::newHashMap);
  }

  /**
   * 是否开启每日自动结算工资.
   */
  private boolean isOpenDailyAutoSalary(Map<String, String> metadata) {
    return Objects.equals(metadata.get("openDailyAutoSalary"), "true");
  }

  /**
   * 汇总所有成员的结算结果.
   *
   * @param settlementResults 成员结算结果列表
   * @return 汇总后的账单结算结果
   */
  private TeamBillSettleResultCO aggregateSettlementResults(List<TeamMemberTargetSettlementResultCO> settlementResults) {
    TeamBillSettleResultCO settleResult = new TeamBillSettleResultCO();
    
    if (CollectionUtils.isEmpty(settlementResults)) {
      return settleResult;
    }
    
    // 统计工作人数（有工资的成员）
    int workMembers = 0;
    // 统计完成人数（工资大于0的成员）
    int finishMembers = 0;
    // 累计成员工资
    BigDecimal totalMemberSalary = BigDecimal.ZERO;
    // 累计拥有者工资
    BigDecimal totalOwnSalary = BigDecimal.ZERO;
    
    for (TeamMemberTargetSettlementResultCO result : settlementResults) {
      if (result == null) {
        continue;
      }
      
      // 统计工作人数：只要有成员记录就算工作
      workMembers++;
      
      // 累计成员工资
      if (result.getMemberSalary() != null) {
        totalMemberSalary = totalMemberSalary.add(result.getMemberSalary());
        // 如果成员工资大于0，算作完成
        if (result.getMemberSalary().compareTo(BigDecimal.ZERO) > 0) {
          finishMembers++;
        }
      }
      
      // 累计拥有者工资
      if (result.getOwnSalary() != null) {
        totalOwnSalary = totalOwnSalary.add(result.getOwnSalary());
      }
    }
    
    // 设置统计结果
    settleResult.setWorkMembers(workMembers);
    settleResult.setFinishMembers(finishMembers);
    settleResult.setMemberSalary(totalMemberSalary);
    settleResult.setOwnSalary(totalOwnSalary);
    
    // 计算总工资
    BigDecimal totalSalary = totalMemberSalary.add(totalOwnSalary);
    settleResult.setTotalSalary(totalSalary);
    
    // 注意：已兑换工资和剩余工资需要从其他地方获取（如原来的 execute 方法中的逻辑）
    // 这里先设置为0，如果需要可以后续补充
    settleResult.setRedeemedSalary(BigDecimal.ZERO);
    settleResult.setSurplusSalary(totalSalary);
    
    return settleResult;
  }
}
