package com.red.circle.other.app.inner.service.user.user.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.collect.Maps;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.inner.service.user.user.UserInviteUserClientService;
import com.red.circle.other.infra.database.rds.entity.user.user.InviteUserRechargeCommission;
import com.red.circle.other.infra.database.rds.entity.user.user.UserInviteUser;
import com.red.circle.other.infra.database.rds.service.user.user.InviteUserRechargeCommissionService;
import com.red.circle.other.infra.database.rds.service.user.user.UserInviteUserService;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.cmd.team.bd.BdTeamWorkStatisticsQryCmd;
import com.red.circle.other.inner.model.cmd.user.InviteStatisticsQryCmd;
import com.red.circle.other.inner.model.cmd.user.InviteUserQryCmd;
import com.red.circle.other.inner.model.dto.user.PageInviteUserRegisterDTO;
import com.red.circle.other.inner.model.dto.user.UserInviteUserCountDTO;

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

import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

/**
 * 用户邀请服务
 *
 * @author xiongcheng on 2024/3/8
 */
@Service
@RequiredArgsConstructor
public class UserInviteUserClientServiceImpl implements UserInviteUserClientService {

  private final UserInviteUserService userInviteUserService;
  private final UserProfileClient userProfileClient;
  private final InviteUserRechargeCommissionService inviteUserRechargeCommissionService;

  @Override
  public Map<Long, UserInviteUserCountDTO> mapInviteStatisticsByUserIds(
      InviteStatisticsQryCmd qryCmd) {
    if (CollectionUtils.isEmpty(qryCmd.getUserIds())) {
      return Maps.newHashMap();
    }
    //获取bd邀请人数信息
    List<UserInviteUserCountDTO> dbUserInviteList = userInviteUserService.listInviteStatisticsByUserIds(
        qryCmd.getQryCmd(), qryCmd.getUserIds());
    if (CollectionUtils.isEmpty(dbUserInviteList)) {
      return Maps.newHashMap();
    }
    return dbUserInviteList.stream()
        .collect(Collectors.toMap(UserInviteUserCountDTO::getUserId, v -> v));
  }

  @Override
  public PageResult<PageInviteUserRegisterDTO> pageQuery(InviteUserQryCmd query) {
    // 1. 分页查询 user_invite_user 表
    PageResult<UserInviteUser> pageResult = userInviteUserService.query()
        .eq(StringUtils.isNotBlank(query.getSysOrigin()),
            UserInviteUser::getSysOrigin, query.getSysOrigin())
        .eq(Objects.nonNull(query.getUserId()),
            UserInviteUser::getUserId, query.getUserId())
        .eq(Objects.nonNull(query.getInviteUserId()),
            UserInviteUser::getInviteUserId, query.getInviteUserId())
        .ge(Objects.nonNull(query.startTimeToLocalDateTime()),
            UserInviteUser::getCreateTime, query.startTimeToLocalDateTime())
        .le(Objects.nonNull(query.endTimeToLocalDateTime()),
            UserInviteUser::getCreateTime, query.endTimeToLocalDateTime())
        .orderByDesc(UserInviteUser::getCreateTime)
        .page(query.getPageQuery());

    // 2. 如果没有数据，直接返回
    if (CollectionUtils.isEmpty(pageResult.getRecords())) {
      return PageResult.newPageResult(0);
    }

    // 3. 收集所有用户ID
    Set<Long> userIds = Stream.of(
            pageResult.getRecords().stream()
                .map(UserInviteUser::getUserId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()),
            pageResult.getRecords().stream()
                .map(UserInviteUser::getInviteUserId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()))
        .flatMap(Collection::stream)
        .collect(Collectors.toSet());

    // 4. 批量查询用户信息
    Map<Long, UserProfileDTO> userProfileMap = ResponseAssert.requiredSuccess(
        userProfileClient.mapByUserIds(userIds));

    Map<Long, BigDecimal> commissionMap = inviteUserRechargeCommissionService.query()
        .in(InviteUserRechargeCommission::getUserId, userIds)
        .list()
        .stream().collect(Collectors.toMap(InviteUserRechargeCommission::getUserId, InviteUserRechargeCommission::getCommission, BigDecimal::add));

    // 5. 转换为 DTO 并返回
    return pageResult.convert(inviteUser -> new PageInviteUserRegisterDTO()
        .setId(inviteUser.getId())
        .setUserId(inviteUser.getUserId())
        .setInviteUserId(inviteUser.getInviteUserId())
        .setUserProfile(userProfileMap.get(inviteUser.getUserId()))
        .setBeUserProfile(userProfileMap.get(inviteUser.getInviteUserId()))
        .setCommission(commissionMap.get(inviteUser.getUserId()))
        .setCreateTime(inviteUser.getCreateTime())
    );
  }

}
