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

import com.google.common.collect.Lists;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.dto.cmd.app.AppIdLongCmd;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.team.TeamMemberCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMember;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberService;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberTargetService;
import com.red.circle.other.infra.database.rds.entity.team.BillDiamondBalance;
import com.red.circle.other.infra.database.rds.service.team.BillDiamondBalanceService;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.num.NumUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import com.red.circle.wallet.inner.endpoint.diamond.SalaryDiamondRunningWaterClient;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 团队成员列表.
 *
 * @author pengliang on 2022/12/6
 */
@Component
@RequiredArgsConstructor
public class TeamMemberListQryExe {

  private final TeamMemberService teamMemberService;
  private final UserProfileGateway userProfileGateway;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final TeamMemberTargetService teamMemberTargetService;
  private final BillDiamondBalanceService billDiamondBalanceService;
  private final SalaryDiamondRunningWaterClient salaryDiamondRunningWaterClient;

  public List<TeamMemberCO> execute(AppIdLongCmd cmd) {

    List<TeamMember> teamMembers = teamMemberService.listTeamMember(cmd.getId(),
        3000);
    if (CollectionUtils.isEmpty(teamMembers)) {
      return Lists.newArrayList();
    }

    Set<Long> memberUserIds = teamMembers.stream().map(TeamMember::getMemberId)
        .collect(Collectors.toSet());
    Map<Long, UserProfileDTO> userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
        userProfileGateway.mapByUserIds(memberUserIds));

    Map<Long, TeamMemberTarget> teamMemberTargetMap = teamMemberTargetService.mapMemberBillTarget(
        cmd.getId(), memberUserIds, ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt());

    Map<Long, Long> diamondMap = CollectionUtils.isNotEmpty(memberUserIds) ?
            salaryDiamondRunningWaterClient.getDiamondByUserIds(memberUserIds.stream().toList()).getBody() : new HashMap<>();

    List<TeamMemberCO> teamMemberCOs = teamMembers.stream().map(teamMember -> new TeamMemberCO()
            .setId(teamMember.getMemberId())
            .setUserProfile(userProfileMap.get(teamMember.getMemberId()))
            .setTargetFormat(Optional.ofNullable(teamMemberTargetMap.get(teamMember.getMemberId()))
                    .map(target -> NumUtils.formatLong(target.sumAcceptGiftValue()))
                    .orElse("0"))
            .setDiamondFormat(NumUtils.formatLong(diamondMap.get(teamMember.getMemberId())))
            .setTimeHours(Optional.ofNullable(teamMemberTargetMap.get(teamMember.getMemberId()))
                    .map(target -> BigDecimal.valueOf(target.sumAllTargetTime())
                            .divide(BigDecimal.valueOf(60), 2, RoundingMode.DOWN)
                            .stripTrailingZeros().toPlainString())
                    .orElse("0"))
            .setEffectiveDay(Optional.ofNullable(teamMemberTargetMap.get(teamMember.getMemberId()))
                            .map(TeamMemberTarget::sumEffectiveDay)
                            .orElse(0))
            .setUseDiamonds("0")
            .setSurplusDiamonds("0")
            .setRole(Objects.toString(teamMember.getRole()))
            .setWalletWithdrawal(Objects.isNull(teamMember.getWalletWithdrawal()) || Objects.equals(
                    teamMember.getWalletWithdrawal(), Boolean.TRUE))
            .setCreateTime(teamMember.getCreateTime())
    ).collect(Collectors.toList());

    teamMemberCOs.forEach(item -> {
      TeamMemberTarget target = teamMemberTargetMap.get(item.getId());
      if (Objects.nonNull(target)) {
        // 查询钻石账单表信息
        BillDiamondBalance billDiamondBalance = billDiamondBalanceService.getEntityByBillBelongAndUserId(SysOriginPlatformEnum.TARAB.name(), target.getBillBelong(), item.getId());
        if (Objects.nonNull(billDiamondBalance)) {
          item.setUseDiamonds(billDiamondBalance.getConsumptionPoints().setScale(0, RoundingMode.DOWN) + "");
          item.setSurplusDiamonds(billDiamondBalance.getBalance().setScale(0, RoundingMode.DOWN) + "");
        } else {
          item.setUseDiamonds("0");
          item.setSurplusDiamonds("0");
        }
      }
    });
    return teamMemberCOs;
  }

  public Integer executeCount(AppIdLongCmd cmd) {
    List<TeamMember> teamMembers = teamMemberService.listTeamMember(cmd.getId(),
            3000);
    return teamMembers.size();
  }

}
