package com.red.circle.other.app.inner.service.material.props.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.red.circle.common.business.enums.PropsActivityRewardEnum;
import com.red.circle.other.app.inner.service.material.props.PropsActivityRewardConfigClientService;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRewardConfig;
import com.red.circle.other.infra.database.rds.entity.badge.BadgeConfig;
import com.red.circle.other.infra.database.rds.entity.emoji.EmojiGroup;
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.service.activity.PropsActivityRewardConfigService;
import com.red.circle.other.infra.database.rds.service.badge.BadgeConfigService;
import com.red.circle.other.infra.database.rds.service.emoji.EmojiGroupService;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.props.PropsSourceRecordService;
import com.red.circle.other.inner.model.dto.material.PropsActivityRewardConfigInfoDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.parse.DataTypeUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
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.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 活动道具奖励配置
 *
 * @author zongpubin on 2023/10/11
 */

@Service
@RequiredArgsConstructor
public class PropsActivityRewardConfigClientServiceImpl implements
    PropsActivityRewardConfigClientService {


  private final EmojiGroupService sysEmojiGroupService;
  private final GiftConfigService sysGiftConfigService;
  private final BadgeConfigService sysBadgeConfigService;
  private final PropsSourceRecordService propsSourceRecordService;
  private final PropsActivityRewardConfigService propsActivityRewardConfigService;


  @Override
  public Map<Long, List<PropsActivityRewardConfigInfoDTO>> mapByGroupIds(Set<Long> sourceGroupIds) {
    if (CollectionUtils.isEmpty(sourceGroupIds)) {
      return Maps.newHashMap();
    }

    return Optional.ofNullable(listByGroupIds(new ArrayList<>(sourceGroupIds)))
        .map(config -> config.stream()
            .collect(Collectors.groupingBy(PropsActivityRewardConfigInfoDTO::getGroupId)))
        .orElseGet(Maps::newHashMap);
  }

  public List<PropsActivityRewardConfigInfoDTO> listByGroupIds(List<Long> groupIds) {

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

    List<PropsActivityRewardConfig> propsActivityRewardConfigs = propsActivityRewardConfigService.listByGroupIds(
        groupIds);

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

    Set<Long> sourceIds = propsActivityRewardConfigs.stream().filter(config ->
            Objects.equals(config.getType(), PropsActivityRewardEnum.PROPS.name()) || Objects.equals(config.getType(), PropsActivityRewardEnum.PROP_COUPON.name()))
        .map(config -> Long.valueOf(config.getContent()))
        .collect(Collectors.toSet());

    Set<Long> fragmentsIds = propsActivityRewardConfigs.stream().filter(config ->
            Objects.equals(config.getType(), PropsActivityRewardEnum.FRAGMENTS.name()))
        .map(config -> Long.valueOf(config.getContent()))
        .collect(Collectors.toSet());

    Set<Long> customizeSourceIds = propsActivityRewardConfigs.stream().filter(config ->
            Objects.equals(config.getType(), PropsActivityRewardEnum.CUSTOMIZE.name()))
        .map(config -> Long.valueOf(config.getContent()))
        .collect(Collectors.toSet());

    Set<Long> gifts = propsActivityRewardConfigs.stream().filter(config ->
            Objects.equals(config.getType(), PropsActivityRewardEnum.GIFT.name()))
        .map(config -> Long.valueOf(config.getContent()))
        .collect(Collectors.toSet());

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

    Map<Long, PropsSourceRecord> customizeSourceMap = propsSourceRecordService
        .mapByIds(customizeSourceIds);

    Map<Long, PropsSourceRecord> fragmentsSourceMap = propsSourceRecordService
        .mapByIds(fragmentsIds);

    Map<Long, GiftConfig> giftMap = sysGiftConfigService.mapByIds(gifts);

    Map<Long, BadgeConfig> sysBadgeConfigMap = sysBadgeConfigService
        .mapByIds(propsActivityRewardConfigs.stream().filter(config ->
                Objects.equals(config.getType(), PropsActivityRewardEnum.BADGE.name()) ||
                        Objects.equals(config.getType(), PropsActivityRewardEnum.PROP_COUPON.name()))
            .map(config -> Long.valueOf(config.getContent()))
            .collect(Collectors.toSet()));

    Map<Long, EmojiGroup> emojiGroupMap = sysEmojiGroupService
        .mapByIds(propsActivityRewardConfigs.stream().filter(config ->
                Objects.equals(config.getType(), PropsActivityRewardEnum.EMOJI.name()))
            .map(config -> Long.valueOf(config.getContent()))
            .collect(Collectors.toSet()));

    return propsActivityRewardConfigs.stream().map(config -> {
          PropsActivityRewardConfigInfoDTO propsActivity = new PropsActivityRewardConfigInfoDTO()
              .setId(config.getId())
              .setGroupId(config.getGroupId())
              .setType(config.getType())
              .setContent(config.getContent())
              .setSort(config.getSort())
              .setCreateTime(config.getCreateTime())
              .setDetailType(config.getDetailType())
              .setQuantity(config.getQuantity())
              .setRemark(config.getRemark())
              .setUpdateTime(config.getUpdateTime());

          propsActivity.setSort(Objects.isNull(propsActivity.getSort()) ? 0 : propsActivity.getSort());
          if (Objects.equals(config.getType(), PropsActivityRewardEnum.PROPS.name()) || Objects.equals(config.getType(), PropsActivityRewardEnum.PROP_COUPON.name())) {
            PropsSourceRecord sourceRecord = sourceRecordMap
                .get(Long.valueOf(config.getContent()));
            if (sourceRecord != null) {
                propsActivity.setCover(sourceRecord.getCover());
                propsActivity.setName(sourceRecord.getName());
                propsActivity.setSourceUrl(sourceRecord.getSourceUrl());
                propsActivity.setAmount(sourceRecord.getAmount());
            }
          }

          if (Objects.equals(config.getType(), PropsActivityRewardEnum.FRAGMENTS.name())) {
            PropsSourceRecord sourceRecord = fragmentsSourceMap
                .get(Long.valueOf(config.getContent()));
            if (sourceRecord != null) {
                propsActivity.setCover(sourceRecord.getCover());
                propsActivity.setSourceUrl(sourceRecord.getSourceUrl());
                propsActivity.setAmount(sourceRecord.getAmount());
            }
          }

          if (Objects.equals(config.getType(), PropsActivityRewardEnum.CUSTOMIZE.name())) {
            PropsSourceRecord sourceRecord = customizeSourceMap
                .get(Long.valueOf(config.getContent()));
            if (sourceRecord != null) {
                propsActivity.setCover(sourceRecord.getCover());
                propsActivity.setSourceUrl(sourceRecord.getSourceUrl());
                propsActivity.setRemark(config.getRemark());
            }
          }

          if (Objects.equals(config.getType(), PropsActivityRewardEnum.EMOJI.name())) {
            EmojiGroup sysEmojiGroupVO = emojiGroupMap.get(Long.valueOf(config.getContent()));
            propsActivity.setCover(sysEmojiGroupVO.getCover());
          }

          if (Objects.equals(config.getType(), PropsActivityRewardEnum.GIFT.name())) {
            GiftConfig giftConfig = giftMap.get(Long.valueOf(config.getContent()));
            setGift(config, propsActivity, giftConfig);
          }

          if (Objects.equals(config.getType(), PropsActivityRewardEnum.BADGE.name()) || Objects.equals(config.getType(), PropsActivityRewardEnum.PROP_COUPON.name())) {
            BadgeConfig sysBadgeConfig = sysBadgeConfigMap
                .get(DataTypeUtils.toLong(config.getContent()));
            if (sysBadgeConfig != null) {
                propsActivity.setBadgeName(sysBadgeConfig.getBadgeName());
            }
          }

          if (!Objects.equals(config.getType(), PropsActivityRewardEnum.SPECIAL_ID.name())) {
            propsActivity.setAmount(new BigDecimal(config.getContent()));
          }
          return propsActivity;
        }).sorted(Comparator.comparing(PropsActivityRewardConfigInfoDTO::getSort))
        .collect(Collectors.toList());
  }

  private void setGift(PropsActivityRewardConfig config,
      PropsActivityRewardConfigInfoDTO propsActivity, GiftConfig giftConfig) {
    if (Objects.nonNull(giftConfig)) {
      propsActivity.setCover(giftConfig.getGiftPhoto());
      propsActivity.setSourceUrl(giftConfig.getGiftSourceUrl());
      propsActivity.setAmount(giftConfig.getGiftCandy());
      propsActivity.setName(giftConfig.getGiftName());
    }
  }
}
