package com.red.circle.other.infra.gateway.assembly;

import com.red.circle.other.infra.convertor.material.PropsNobleVipInfraConvertor;
import com.red.circle.other.infra.convertor.material.PropsSourceInfraConvertor;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.service.props.PropsNobleVipAbilityService;
import com.red.circle.other.infra.database.rds.service.props.PropsSourceRecordService;
import com.red.circle.other.inner.model.dto.material.props.NobleVipAbility;
import com.red.circle.other.inner.model.dto.material.props.PropsNobleVipAbilityDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

/**
 * @author pengliang on 2023/11/7
 */
@Component
@RequiredArgsConstructor
public class NobleVipAbilityAssembly {

  private final PropsSourceRecordService propsSourceRecordService;
  private final PropsSourceInfraConvertor propsSourceInfraConvertor;
  private final PropsNobleVipInfraConvertor propsNobleVipInfraConvertor;
  private final PropsNobleVipAbilityService propsNobleVipAbilityService;

  /**
   * 获取贵族vip能力.
   */
  public NobleVipAbility getAbility(Long sourceId) {
    List<NobleVipAbility> abilities = listAbility(Set.of(sourceId));
    return CollectionUtils.isNotEmpty(abilities)
        ? abilities.get(0)
        : null;
  }


  /**
   * 获取贵族vip能力.
   */
  public List<NobleVipAbility> listAbility(Set<Long> sourceIds) {

    if (CollectionUtils.isEmpty(sourceIds)) {
      return CollectionUtils.newArrayList();
    }

    List<PropsNobleVipAbilityDTO> nobleVipAbilities = propsNobleVipInfraConvertor.toListPropsNobleVipAbilityDTO(
        propsNobleVipAbilityService.listByIds(sourceIds)
    );

    if (CollectionUtils.isEmpty(nobleVipAbilities)) {
      return CollectionUtils.newArrayList();
    }

    List<NobleVipAbility> ability = nobleVipAbilities.stream().map(noble -> {
                NobleVipAbility nobleVipAbility = new NobleVipAbility();
                BeanUtils.copyProperties(noble, nobleVipAbility);
                nobleVipAbility.setNobleVipAbility(noble);
                return nobleVipAbility;
            })
        .toList();

    Set<Long> abilitySourceIds = ability.stream().map(NobleVipAbility::noblePropsSourceIds)
        .flatMap(Collection::stream)
        .collect(Collectors.toSet());

    if (CollectionUtils.isEmpty(abilitySourceIds)) {
      return ability;
    }

    Map<Long, PropsSourceRecord> sourceRecordMap = propsSourceRecordService.mapByIds(
        abilitySourceIds);

    if (CollectionUtils.isEmpty(sourceRecordMap)) {
      return ability;
    }

    return ability.stream().peek(noble -> {

      if (Objects.nonNull(noble.avatarFrameId())) {
        noble.setAvatarFrame(propsSourceInfraConvertor
            .toPropsSources(sourceRecordMap.get(noble.avatarFrameId()))
        );
      }

      if (Objects.nonNull(noble.cardId())) {
        noble.setCar(propsSourceInfraConvertor
            .toPropsSources(sourceRecordMap.get(noble.cardId()))
        );
      }

      if (Objects.nonNull(noble.chatBubbleId())) {
        noble.setChatBubble(propsSourceInfraConvertor
            .toPropsSources(sourceRecordMap.get(noble.chatBubbleId()))
        );
      }

      if (Objects.nonNull(noble.dataCardId())) {
        noble.setDataCard(propsSourceInfraConvertor
            .toPropsSources(sourceRecordMap.get(noble.dataCardId())));
      }

    }).toList();
  }

  /**
   * 获取贵族vip能力.
   */
  public Map<Long, NobleVipAbility> mapAbility(Set<Long> sourceIds) {
    if (CollectionUtils.isEmpty(sourceIds)) {
      return CollectionUtils.newHashMap();
    }

    List<NobleVipAbility> abilities = listAbility(sourceIds);
    if (CollectionUtils.isEmpty(abilities)) {
      return CollectionUtils.newHashMap();
    }

    return abilities.stream().collect(Collectors.toMap(NobleVipAbility::id, v -> v));
  }
}
