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

import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.convertor.material.GiftAppConvertor;
import com.red.circle.other.app.dto.clientobject.gift.UserGiftBackpackCO;
import com.red.circle.other.infra.database.rds.entity.gift.GiftBackpack;
import com.red.circle.other.infra.database.rds.entity.gift.GiftBackpackLimit;
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
import com.red.circle.other.infra.database.rds.service.gift.GiftBackpackLimitService;
import com.red.circle.other.infra.database.rds.service.gift.GiftBackpackService;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 用户礼物背包.
 *
 * @author pengliang on 2021/3/11
 */
@Component
@RequiredArgsConstructor
public class UserGiftBackpackQryExe {

  private final GiftAppConvertor giftAppConvertor;
  private final GiftConfigService giftConfigService;
  private final GiftBackpackService giftBackpackService;
  private final GiftBackpackLimitService giftBackpackLimitService;

  public List<UserGiftBackpackCO> execute(AppExtCommand cmd) {
    List<GiftBackpack> giftBackpacks = giftBackpackService
        .listUserGiftBackPack(cmd.requiredReqUserId());

    if (CollectionUtils.isEmpty(giftBackpacks)) {
      return CollectionUtils.newArrayList();
    }
    Map<Long, GiftConfig> giftConfigInfoMap = giftConfigService.mapByIds(giftBackpacks.stream()
        .map(GiftBackpack::getGiftId)
        .collect(Collectors.toSet()));

    Map<Long, GiftBackpackLimit> giftBackpackLimitMap = giftBackpackLimitService
        .mapByBackIds(cmd.requiredReqUserId(), giftBackpacks.stream()
            .map(GiftBackpack::getId)
            .collect(Collectors.toSet()));

    return giftBackpacks.stream().map(assembly(giftConfigInfoMap, giftBackpackLimitMap))
        .filter(giftBackpack -> Objects.nonNull(giftBackpack.getGiftConfig()))
        .collect(Collectors.toList());
  }

  private Function<GiftBackpack, UserGiftBackpackCO> assembly(
      Map<Long, GiftConfig> giftConfigInfoMap, Map<Long, GiftBackpackLimit> giftBackpackLimitMap) {
    return giftBackpack -> new UserGiftBackpackCO()
        .setId(giftBackpack.getId())
        .setQuantity(giftBackpack.calculationQuantity())
        .setGiftLimit(giftAppConvertor
            .toGiftBackpackLimitCO(giftBackpackLimitMap.get(giftBackpack.getId())))
        .setGiftConfig(
            giftAppConvertor.toGiftConfigCO(giftConfigInfoMap.get(giftBackpack.getGiftId())));
  }

}
