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

import com.google.common.collect.Maps;
import com.red.circle.common.business.dto.cmd.LastIdCmd;
import com.red.circle.other.app.convertor.user.UserConfessionConvertor;
import com.red.circle.other.app.dto.clientobject.user.user.ConfessionChanceCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
import com.red.circle.other.infra.database.rds.entity.user.user.ConfessionChance;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.user.user.ConfessionChanceService;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.Arrays;
import java.util.Collection;
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.AllArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 告白机会列表
 *
 * @author zongpubin on 2023/11/15
 */
@Component
@AllArgsConstructor
public class UserConfessionChanceQryExe {

  private final GiftConfigService giftConfigService;
  private final UserProfileGateway userProfileGateway;
  private final UserConfessionConvertor userConfessionConvertor;
  private final ConfessionChanceService confessionChanceService;

  public List<ConfessionChanceCO> execute(LastIdCmd cmd) {

    List<ConfessionChance> confessionChances = confessionChanceService.getUserConfessionChance(
        cmd.requiredReqUserId(), cmd.getLastId());

    if (CollectionUtils.isEmpty(confessionChances)) {
      return null;
    }

    Map<Long, UserProfile> userProfileMap = userProfileGateway
        .mapByUserIds(getAllUserIds(confessionChances));

    Map<Long, GiftConfig> giftConfigMap = Optional.ofNullable(giftConfigService
        .mapByIds(confessionChances.stream().map(ConfessionChance::getGiftId)
            .collect(Collectors.toSet()))).orElse(Maps.newHashMap());

    return userConfessionConvertor.toConfessionChanceCO(
        confessionChances).stream().map(chance -> {
      UserProfile userProfile = userProfileMap.get(chance.getUserId());
      UserProfile confessionUserProfile = userProfileMap.get(chance.getConfessionUserId());
      if (Objects.isNull(userProfile) || Objects.isNull(confessionUserProfile)) {
        return null;
      }
      chance.setUserAvatar(userProfile.getUserAvatar());
      chance.setUserNickname(userProfile.getUserNickname());
      chance.setConfessionUserAvatar(confessionUserProfile.getUserAvatar());
      chance.setConfessionUserNickname(confessionUserProfile.getUserNickname());
      GiftConfig giftConfig = giftConfigMap.get(chance.getGiftId());
      if (Objects.isNull(giftConfig)) {
        return null;
      }
      chance.setCover(giftConfig.getGiftPhoto());
      return chance;
    }).filter(Objects::nonNull).collect(Collectors.toList());
  }

  private Set<Long> getAllUserIds(List<ConfessionChance> results) {
    return results.stream()
        .map(confessionChance -> Arrays.asList(confessionChance.getUserId(),
            confessionChance.getConfessionUserId()))
        .flatMap(Collection::stream)
        .collect(Collectors.toSet());
  }
}
