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

import com.google.common.collect.Lists;
import com.red.circle.common.business.dto.cmd.app.AppUserIdCmd;
import com.red.circle.other.app.convertor.material.BadgeAppConvertor;
import com.red.circle.other.app.dto.clientobject.material.BadgeBackpackCO;
import com.red.circle.other.app.dto.clientobject.material.BadgeConfigCO;
import com.red.circle.other.infra.database.rds.entity.badge.BadgeBackpack;
import com.red.circle.other.infra.database.rds.entity.badge.BadgeConfig;
import com.red.circle.other.infra.database.rds.entity.badge.BadgePictureConfig;
import com.red.circle.other.infra.database.rds.service.badge.BadgeBackpackService;
import com.red.circle.other.infra.database.rds.service.badge.BadgeConfigService;
import com.red.circle.other.infra.database.rds.service.badge.BadgePictureConfigService;
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/12
 */
@Component
@RequiredArgsConstructor
public class UserBadgeBackpackTableQryExe {

  private final BadgeAppConvertor badgeAppConvertor;
  private final BadgeConfigService badgeConfigService;
  private final BadgeBackpackService badgeBackpackService;
  private final BadgePictureConfigService badgePictureConfigService;

  public List<BadgeBackpackCO> execute(AppUserIdCmd cmd) {
    List<BadgeBackpack> badgeBackpacks = badgeBackpackService.listByBadgeBackpack(cmd.getUserId());
    if (CollectionUtils.isEmpty(badgeBackpacks)) {
      return Lists.newArrayList();
    }

    Map<Long, BadgePictureConfig> badgePictureConfigMap = badgePictureConfigService
        .mapBadge(cmd.requireReqSysOrigin(), badgeBackpacks.stream().map(BadgeBackpack::getBadgeId)
            .collect(Collectors.toSet()));

    return assembly(badgeBackpacks, badgePictureConfigMap);
  }

  private List<BadgeBackpackCO> assembly(List<BadgeBackpack> badgeBackpacks,
      Map<Long, BadgePictureConfig> badgePictureConfigMap) {

    List<BadgeConfig> badgeConfigs = badgeConfigService.listByIds(getBadgeId(badgeBackpacks));

    if (CollectionUtils.isEmpty(badgeConfigs) || CollectionUtils.isEmpty(badgePictureConfigMap)) {
      return Lists.newArrayList();
    }

    Map<Long, BadgeBackpack> badgeBackpackMap = badgeBackpackToMap(badgeBackpacks);

    return badgeConfigs.stream().map(badgeConfig -> {
      BadgeConfigCO badgeConfigCo = badgeAppConvertor.toBadgeConfigCO(badgeConfig);
      BadgeBackpack badgeBackpack = badgeBackpackMap.get(badgeConfig.getId());
      BadgePictureConfig badgePictureConfig = badgePictureConfigMap.get(badgeConfig.getId());
      if (Objects.isNull(badgePictureConfig)) {
        return null;
      }
      badgeConfigCo.setAnimationUrl(badgePictureConfig.getAnimationUrl());
      badgeConfigCo.setSelectUrl(badgePictureConfig.getSelectUrl());
      badgeConfigCo.setNotSelectUrl(badgePictureConfig.getNotSelectUrl());
      return new BadgeBackpackCO()
          .setId(badgeBackpack.getId())
          .setBadgeConfig(badgeConfigCo);
    }).filter(Objects::nonNull).collect(Collectors.toList());
  }

  private Map<Long, BadgeBackpack> badgeBackpackToMap(List<BadgeBackpack> badgeBackpacks) {
    return badgeBackpacks.stream()
        .collect(Collectors.toMap(BadgeBackpack::getBadgeId, Function.identity(), (k, v) -> v));
  }

  private List<Long> getBadgeId(List<BadgeBackpack> badgeBackpacks) {
    return badgeBackpacks.stream().map(BadgeBackpack::getBadgeId).distinct()
        .collect(Collectors.toList());
  }

}
