package com.red.circle.other.infra.common.props;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.red.circle.other.infra.convertor.material.BadgeInfraConvertor;
import com.red.circle.other.infra.convertor.material.PropsMaterialInfraConvertor;
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.other.inner.enums.material.BadgeBackpackExpireType;
import com.red.circle.other.inner.model.dto.material.BadgeBackpackDTO;
import com.red.circle.other.inner.model.dto.material.UseBadgeDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;

import java.util.*;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 用户徽章
 *
 * @author pengliang on 2024/2/28
 */
@Component
@RequiredArgsConstructor
public class UserBadgeCommon {

  private final BadgeConfigService badgeConfigService;
  private final BadgeInfraConvertor badgeInfraConvertor;
  private final BadgeBackpackService badgeBackpackService;
  private final BadgePictureConfigService badgePictureConfigService;
  private final PropsMaterialInfraConvertor propsMaterialInfraConvertor;

  /**
   * 用户背包列表.
   */
  public List<UseBadgeDTO> listUseBadge(Long userId, String sysOrigin, Collection<Long> wearBadgeId) {
      List<BadgeBackpack> badgeBackpacks = badgeBackpackService.listUserNotExpireTimeByBadgeIds(
              userId, wearBadgeId);

      if (CollectionUtils.isEmpty(badgeBackpacks)) {
          return Lists.newArrayList();
      }

      Set<Long> badgeIds = badgeBackpacks.stream().map(BadgeBackpack::getBadgeId)
              .collect(Collectors.toSet());

      Map<Long, BadgeConfig> badgeConfigMap = badgeConfigService.mapByIds(badgeIds);

      Map<Long, BadgePictureConfig> badgePictureConfigMap = badgePictureConfigService
              .mapBadge(sysOrigin, badgeConfigMap.values().stream().map(BadgeConfig::getId)
                      .collect(Collectors.toSet()));

      List<UseBadgeDTO> useBadgeList = badgeBackpacks.stream().map(badgeBackpack -> {
                  BadgeConfig badgeConfig = badgeConfigMap.get(badgeBackpack.getBadgeId());
                  if (Objects.isNull(badgeConfig)) {
                      return null;
                  }
                  BadgePictureConfig badgePictureConfig = badgePictureConfigMap.get(badgeBackpack.getBadgeId());
                  if (Objects.isNull(badgePictureConfig)) {
                      return null;
                  }
                  UseBadgeDTO entity = propsMaterialInfraConvertor.toUseBadgeDTO(badgeConfig);
                  entity.setUserId(badgeBackpack.getUserId());
                  entity.setSelectUrl(badgePictureConfig.getSelectUrl());
                  entity.setNotSelectUrl(badgePictureConfig.getNotSelectUrl());
                  entity.setAnimationUrl(badgePictureConfig.getAnimationUrl());
                  entity.setUse(badgeBackpack.getUseProps());
                  entity.setExpireTime(
                          Objects.equals(badgeBackpack.getExpireType(), BadgeBackpackExpireType.PERMANENT.name())
                                  ? TimestampUtils.nowPlusYear(10).getTime()
                                  : badgeBackpack.getExpireTime().getTime());
                  return entity;
              })
              .filter(Objects::nonNull)
              .collect(Collectors.toList());
      List<Long> wearBadgeIdList = new ArrayList<>(wearBadgeId);
      Map<Long, Integer> indexMap = Maps.newHashMap();
      for (int i = 0; i < wearBadgeIdList.size(); i++) {
          indexMap.put(wearBadgeIdList.get(i), i);
      }
      useBadgeList.sort(Comparator.comparingInt(o -> indexMap.get(o.getId())));
      return useBadgeList;
  }


  /**
   * 卸下用户全部徽章.
   */
  public void useOffByUserId(Long userId) {
    badgeBackpackService.updateUseOffByUserId(userId);
  }


  /**
   * 修改使用的徽章.
   *
   * @param userId   用户id
   * @param badgeIds 徽章id
   */
  public void updateUseBadge(Long userId,  Collection<Long> badgeIds) {
    badgeBackpackService.updateUseBadge(userId, badgeIds);
  }

  /**
   * 将一组用户徽章到期时间减少指定天数，并且将其卸下.
   *
   * @param userId     用户.
   * @param badgeIds   徽章ids
   * @param reduceDays 将有效时间减少*天.
   */
  public void reduceDaysAndUnUse(Long userId, Set<Long> badgeIds, Integer reduceDays) {
    badgeBackpackService.reduceDaysAndUnUse(userId, badgeIds, reduceDays);
  }

  /**
   * 获取一组用户正在使用徽章.
   */
  public List<BadgeBackpackDTO> listUseNotExpireTimeByUserIds(Set<Long> userIds) {
    return badgeInfraConvertor.toListBadgeBackpackDTO(
        badgeBackpackService.listNotExpireTimeByUserIds(userIds));
  }
}
