package com.red.circle.console.app.service.app.team;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.red.circle.console.app.convertor.team.TeamAppConvertor;
import com.red.circle.console.app.dto.clienobject.team.TeamSalaryCO;
import com.red.circle.console.app.dto.clienobject.team.TeamSalaryDetailsCO;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.inner.endpoint.team.target.TeamProfileClient;
import com.red.circle.other.inner.model.cmd.team.TeamSalaryBackQryCmd;
import com.red.circle.other.inner.model.dto.agency.agency.TeamSalaryPaymentDTO;
import com.red.circle.other.inner.model.dto.agency.agency.TeamSalaryPaymentDetailsDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.endpoint.user.region.RegionConfigClient;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import java.util.Comparator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 团队申请审核日志.
 *
 * @author pengshigang on 2022/12/19
 */
@Service
@RequiredArgsConstructor
public class TeamSalaryBackServiceImpl implements TeamSalaryBackService {

  private final TeamAppConvertor teamAppConvertor;
  private final TeamProfileClient teamProfileClient;
  private final UserProfileClient userProfileClient;
  private final RegionConfigClient regionConfigClient;

  @Override
  public PageResult<TeamSalaryCO> listByCondition(TeamSalaryBackQryCmd query) {

    PageResult<TeamSalaryPaymentDTO> pageResult = ResponseAssert.requiredSuccess(teamProfileClient
        .listByCondition(query));

    pageResult.setTotal(pageResult.getTotal());
    PageResult<TeamSalaryCO> page = pageResult.convert(teamAppConvertor::toTeamSalaryCO);
    if (pageResult.getTotal() <= 0) {
      return page;
    }

    Map<String, String> mapRegionName = getMapRegionName(query);

    Map<Long, UserProfileDTO> userProfileMap = getUserProfileMap(pageResult);

    page.setRecords(pageResult.getRecords().stream().map(salary -> {

      TeamSalaryCO salaryVO = teamAppConvertor.toTeamSalaryCO(salary);
      if (Objects.isNull(salaryVO)) {
        return null;
      }

      UserProfileDTO userProfile = userProfileMap.get(salary.getUserId());
      if (Objects.isNull(userProfile)) {
        return null;
      }
      salaryVO.setUserProfile(userProfile);

      if (CollectionUtils.isEmpty(salary.getSalarySendDetails())) {
        return salaryVO;
      }

      if (CollectionUtils.isNotEmpty(salary.getSalarySendDetails())) {

        salaryVO.setSalaryDetails(salary.getSalarySendDetails().stream().map(details -> {

              TeamSalaryDetailsCO detailsVO = teamAppConvertor.toTeamSalaryDetailsCO(details);
              if (Objects.isNull(detailsVO)) {
                return null;
              }

              UserProfileDTO teamMember = userProfileMap.get(detailsVO.getTeamMemberId());
              if (Objects.nonNull(teamMember)) {
                detailsVO.setTeamMemberProfile(teamMember);
              }

              UserProfileDTO teamOwn = userProfileMap.get(detailsVO.getTeamOwnId());
              if (Objects.nonNull(teamOwn)) {
                detailsVO.setTeamOwnProfile(teamOwn);
              }

              String regionName = mapRegionName.get(detailsVO.getTeamRegionId());
              if (StringUtils.isNotBlank(regionName)) {
                detailsVO.setTeamRegionName(regionName);
              }

              if (Objects.nonNull(detailsVO.getRefundUserId())) {
                UserProfileDTO refundUser = userProfileMap.get(detailsVO.getRefundUserId());
                detailsVO.setRefundUser(refundUser);
              }

              return detailsVO;

            }).filter(Objects::nonNull)
            .sorted(Comparator.comparing(TeamSalaryDetailsCO::getCreateTime).reversed())
            .collect(Collectors.toList()));
      }

      return salaryVO;

    }).filter(Objects::nonNull).collect(Collectors.toList()));
    return page;
  }

  private Map<String, String> getMapRegionName(TeamSalaryBackQryCmd query) {
    return ResponseAssert.requiredSuccess(
        regionConfigClient.mapRegionNameBySysOrigin(query.getSysOrigin()));
  }

  private Map<Long, UserProfileDTO> getUserProfileMap(PageResult<TeamSalaryPaymentDTO> pageResult) {

    Set<Long> userIds = Sets.newHashSet();

    pageResult.getRecords().forEach(v -> {

      userIds.add(v.getUserId());

      if (CollectionUtils.isEmpty(v.getSalarySendDetails())) {
        return;
      }

      userIds.addAll(
          v.getSalarySendDetails().stream().map(TeamSalaryPaymentDetailsDTO::getTeamOwnId).collect(
              Collectors.toSet()));

      userIds.addAll(
          v.getSalarySendDetails().stream().map(TeamSalaryPaymentDetailsDTO::getRefundUserId)
              .collect(
                  Collectors.toSet()));
    });

    if (CollectionUtils.isEmpty(userIds)) {
      return Maps.newHashMap();
    }

    return ResponseAssert.requiredSuccess(userProfileClient.mapByUserIds(userIds));
  }

}
