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

import com.red.circle.console.app.convertor.UserConfessionRecordAppConvertor;
import com.red.circle.console.app.dto.clienobject.user.UserConfessionRecordCO;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.other.inner.endpoint.user.user.UserConfessionRecordClient;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.cmd.user.UserConfessionRecordQryCmd;
import com.red.circle.other.inner.model.dto.user.UserConfessionDTO;
import com.red.circle.other.inner.model.dto.user.UserConfessionRecordDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * @author zongpubin on 2024/1/30
 */
@Service
@RequiredArgsConstructor
public class ConfessionRecordServiceImpl implements ConfessionRecordService {

  private final UserProfileClient userProfileClient;
  private final UserConfessionRecordClient userConfessionRecordClient;
  private final UserConfessionRecordAppConvertor userConfessionRecordAppConvertor;

  @Override
  public PageResult<UserConfessionRecordCO> pageListQuery(UserConfessionRecordQryCmd query) {
    PageResult<UserConfessionRecordDTO> pageResult = ResponseAssert.requiredSuccess(
        userConfessionRecordClient.pageListQuery(
            query));
    if (CollectionUtils.isEmpty(pageResult.getRecords())) {
      return pageResult.convert(userConfessionRecordAppConvertor::toUserConfessionRecordCO);
    }
    Map<Long, UserProfileDTO> userProfileMap = getUserProfileMap(pageResult);

    return pageResult.convert(userConfessionRecord -> {
      UserConfessionRecordCO recordVO = userConfessionRecordAppConvertor.toUserConfessionRecordCO(
          userConfessionRecord);

      UserProfileDTO userProfile = userProfileMap.get(userConfessionRecord.getUserId());
      UserProfileDTO confessionUserProfile = userProfileMap.get(
          userConfessionRecord.getConfessionUserId());

      if (Objects.nonNull(userProfile) && Objects.nonNull(confessionUserProfile)) {
        recordVO.setUserProfile(userProfile);
        recordVO.setConfessionUserProfile(confessionUserProfile);
      }
      return recordVO;
    });
  }

  @Override
  public void auditUserConfession(UserConfessionDTO dto) {
    userConfessionRecordClient.auditUserConfession(dto);
  }

  private Map<Long, UserProfileDTO> getUserProfileMap(
      PageResult<UserConfessionRecordDTO> userConfessions) {
    return ResponseAssert.requiredSuccess(userProfileClient.mapByUserIds(
        userConfessions.getRecords().stream()
            .map(confessionRecord -> Arrays.asList(confessionRecord.getUserId(),
                confessionRecord.getConfessionUserId()))
            .flatMap(Collection::stream)
            .collect(Collectors.toSet())));
  }
}
