package com.red.circle.other.app.manager.activity.refresh;

import com.alibaba.nacos.common.utils.JacksonUtils;
import com.google.common.collect.Maps;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.other.app.dto.clientobject.activity.ExclusiveGiftTopCO;
import com.red.circle.other.infra.database.cache.service.other.GiftCacheService;
import com.red.circle.other.infra.database.mongo.dto.CountExclusiveGift;
import com.red.circle.other.infra.database.mongo.service.gift.GiftGiveRunningWaterService;
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.utils.DateFormatEnum;
import com.red.circle.other.infra.utils.ZonedDateTimeUtils;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.num.NumUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.ZonedDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 刷新每周专属礼物榜单, 缓存数据加载.
 *
 * @author lixiaofei on 2024/06/25
 */
@Slf4j
@Component
@AllArgsConstructor
public class ResetWeekExclusiveGiftManager {

  private final GiftCacheService giftCacheService;
  private final GiftConfigService giftConfigService;
  private final GiftGiveRunningWaterService giftGiveRunningWaterService;

  /**
   * 每周一执行
   */
  public void weekly() {
    //缓存上周专属礼物榜单
    cacheLastWeekExclusive();
  }


  /**
   * 每15分钟执行一次
   *
   * @author pengshigang
   */
  public void everyFifteenMinutes() {

    //缓存本周专属礼物榜单
    cacheThisWeekExclusive();
  }


  /**
   * 缓存本周专属礼物消耗榜单
   */
  private void cacheThisWeekExclusive() {

    ZonedDateTime now = ZonedDateTimeUtils.nowAsiaRiyadh();

    Integer weekMonday = ZonedDateTimeUtils.getWeekMonday(now);
    Integer weekSunday = ZonedDateTimeUtils.getWeekSunday(now);

    countExclusive(giftGiveRunningWaterService.countExclusiveGift(weekMonday, weekSunday))
        .forEach((key, val) -> giftCacheService.pushListThisWeekExclusive(key,
            JacksonUtils.toJson(val)));
  }

  /**
   * 缓存上周专属礼物消耗榜单
   */
  private void cacheLastWeekExclusive() {

    Integer lastWeekMonday = Integer.parseInt(ZonedDateTimeUtils.format(
        ZonedDateTimeUtils.getAsiaRiyadhLastWeekMonday(), DateFormatEnum.yyyyMMdd));

    Integer lastWeekSunday = Integer.parseInt(ZonedDateTimeUtils.format(
        ZonedDateTimeUtils.getAsiaRiyadhLastWeekSunday(), DateFormatEnum.yyyyMMdd));

    log.warn("上周专属礼物消耗列表last: startTime:{} startTime:{}", lastWeekMonday, lastWeekSunday);

    //根据上周专属礼物消耗，修改专属礼物顺序，上周没有送过一次的专属礼物将被下架
    List<CountExclusiveGift> countExclusiveGifts = giftGiveRunningWaterService.countExclusiveGift(
        lastWeekMonday, lastWeekSunday);

    if (CollectionUtils.isNotEmpty(countExclusiveGifts)) {

      giftConfigService.updateExclusiveNotInDown(
          countExclusiveGifts.stream().map(CountExclusiveGift::getGiftId)
              .distinct().collect(Collectors.toList()));

      giftConfigService.updateBatchById(
          countExclusiveGifts.stream().map(exclusiveGift -> {
            GiftConfig giftConfig = new GiftConfig();
            giftConfig.setUpdateTime(TimestampUtils.now());
            giftConfig.setSort(exclusiveGift.getQuantity().intValue());
            giftConfig.setId(exclusiveGift.getGiftId());
            return giftConfig;
          }).collect(Collectors.toList()));

      countExclusive(countExclusiveGifts)
          .forEach((key, val) -> giftCacheService.pushListLastWeekExclusive(key,
              JacksonUtils.toJson(val)));
    }

    //修改完成后，清空缓存
    giftCacheService.remove();

  }

  private Map<SysOriginPlatformEnum, List<ExclusiveGiftTopCO>> countExclusive(
      List<CountExclusiveGift> countExclusiveGifts) {
    if (CollectionUtils.isEmpty(countExclusiveGifts)) {
      return Maps.newHashMap();
    }
    Map<Long, GiftConfig> giftConfigMap = giftConfigService.mapByIds(
        countExclusiveGifts.stream().map(CountExclusiveGift::getGiftId)
            .collect(Collectors.toSet()));

    return countExclusiveGifts.stream().map(countExclusiveGift -> {
      GiftConfig giftConfig = giftConfigMap.get(countExclusiveGift.getGiftId());
      if (Objects.isNull(giftConfig)) {
        return null;
      }
      return ExclusiveGiftTopCO.builder()
          .giftCandy(NumUtils.formatBigDecimal(countExclusiveGift.getQuantity()))
          .giftName(giftConfig.getGiftName())
          .giftPhoto(giftConfig.getGiftPhoto())
          .sysOrigin(SysOriginPlatformEnum.valueOf(countExclusiveGift.getSysOrigin()))
          .build();
    }).filter(Objects::nonNull).collect(Collectors.groupingBy(ExclusiveGiftTopCO::getSysOrigin));

  }
}
