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

import com.google.common.collect.Lists;
import com.red.circle.common.business.enums.ReportTypeEnum;
import com.red.circle.common.business.enums.ReportedApprovalStatusEnum;
import com.red.circle.console.app.convertor.sys.ReportedUserAppConvertor;
import com.red.circle.console.app.dto.clienobject.sys.SysReportedUserCO;
import com.red.circle.console.infra.database.rds.entity.admin.User;
import com.red.circle.console.infra.database.rds.service.admin.UserService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.inner.endpoint.sys.ReportedUserClient;
import com.red.circle.other.inner.model.cmd.sys.SysReportedQryCmd;
import com.red.circle.other.inner.model.dto.sys.SysReportedUserDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 被举报用户 服务实现类
 * </p>
 *
 * @author pengliang
 * @since 2019-11-08
 */
@Service
@RequiredArgsConstructor
public class SysReportedUserServiceImpl implements SysReportedUserService {

  private final UserService userService;
  private final ReportedUserClient reportedUserClient;
  private final UserProfileClient userProfileBackRepository;
  private final ReportedUserAppConvertor reportedUserAppConvertor;

  @Override
  public PageResult<SysReportedUserCO> pageSysReportedUserVO(SysReportedQryCmd sysReportedQuery) {
    PageResult<SysReportedUserDTO> sysReportedUserPage = ResponseAssert.requiredSuccess(
        reportedUserClient.pageSysReportedUser(sysReportedQuery));

    if (CollectionUtils.isEmpty(sysReportedUserPage.getRecords())) {
      return sysReportedUserPage
          .convert(reportedUserAppConvertor::toSysReportedUserCO);
    }

    Map<Long, UserProfileDTO> userMap = ResponseAssert.requiredSuccess(userProfileBackRepository
        .mapByUserIds(getUserIds(sysReportedUserPage)));

    Map<Long, User> backUserMap = userService.mapBackUser(
        sysReportedUserPage.getRecords().stream().map(SysReportedUserDTO::getUpdateUser)
            .filter(Objects::nonNull).collect(Collectors.toSet())
    );

    return sysReportedUserPage.convert(sysReportedUser -> {
      SysReportedUserCO co = reportedUserAppConvertor.toSysReportedUserCO(sysReportedUser);

      co.setReportTypeName(ReportTypeEnum.getName(sysReportedUser.getReportType()))
          .setReportedUser(userMap.get(sysReportedUser.getReportedUserId()))
          .setReportUser(userMap.get(sysReportedUser.getReportUserId()))
          .setApprovalStatusName(
              ReportedApprovalStatusEnum.getDescByValue(sysReportedUser.getApprovalStatus()))
          .setUpdateNickname(Optional.ofNullable(backUserMap.get(sysReportedUser.getUpdateUser()))
              .map(User::getNickname)
              .orElse(null));
      return co;

    });
  }

  private Set<Long> getUserIds(PageResult<SysReportedUserDTO> sysReportedUserPage) {
    Set<Long> reportUserId = sysReportedUserPage.getRecords().stream()
        .map(SysReportedUserDTO::getReportUserId).collect(Collectors.toSet());

    Set<Long> reportedUserId = sysReportedUserPage.getRecords().stream()
        .map(SysReportedUserDTO::getReportedUserId).collect(Collectors.toSet());

    List<Long> userIds = Lists.newArrayList();
    userIds.addAll(reportUserId);
    userIds.addAll(reportedUserId);
    return new HashSet<>(userIds);
  }

}
