package com.red.circle.other.infra.database.cache.service.other.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.other.infra.convertor.game.GiftInfraConvertor;
import com.red.circle.other.infra.database.cache.key.GiftKeys;
import com.red.circle.other.infra.database.cache.service.other.GiftCacheService;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.inner.model.dto.material.GiftConfigDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * @author pengliang
 * @since 2020/10/3 9:47
 */
@Service
@RequiredArgsConstructor
public class GiftCacheServiceImpl implements GiftCacheService {

  private final RedisService redisService;
  private final GiftConfigService giftConfigService;
  private final GiftInfraConvertor giftInfraConvertor;

  /**
   * 获取指定礼物.
   */
  @Override
  public GiftConfigDTO getById(Long id) {
    return getGiftConfig(id,
        giftId -> giftInfraConvertor.toGiftConfigDTO(giftConfigService.getById(giftId)));
  }

  @Override
  public List<GiftConfigDTO> listBySysOrigin(SysOriginPlatformEnum sysOrigin) {
    return listGiftConfigCache(sysOrigin, this::toListGiftConfigDTO);
  }

  private List<GiftConfigDTO> toListGiftConfigDTO(SysOriginPlatformEnum origin) {
    return giftInfraConvertor.toListGiftConfigDTO(giftConfigService.listEffectiveSysOriginGift(origin));
  }

  /**
   * 获得组成cp时赠送的礼物.
   */
  @Override
  public GiftConfigDTO getPairCpGive(SysOriginPlatformEnum sysOrigin) {
    return getById(getPairCpGiveGiftId(sysOrigin));
  }

  private List<GiftConfigDTO> listGiftConfigCache(SysOriginPlatformEnum sysOrigin, Function<SysOriginPlatformEnum, List<GiftConfigDTO>> orElseGet) {
    List<GiftConfigDTO> giftConfigCaches = redisService.hashGet(
        GiftKeys.LIST.getKey(),
        sysOrigin.name(),
        new TypeReference<>() {
        }
    );

    if (CollectionUtils.isNotEmpty(giftConfigCaches)) {
      return giftConfigCaches;
    }

    List<GiftConfigDTO> newGiftConfigCaches = orElseGet.apply(sysOrigin);
    if (CollectionUtils.isNotEmpty(newGiftConfigCaches)) {
      redisService.hashPut(GiftKeys.LIST.getKey(), sysOrigin.name(), newGiftConfigCaches);
    }
    return newGiftConfigCaches;
  }

  private GiftConfigDTO getGiftConfig(Long id, Function<Long, GiftConfigDTO> orElseGet) {
    GiftConfigDTO giftConfigCache = redisService
        .hashGet(GiftKeys.LIST.getKey(), Objects.toString(id), GiftConfigDTO.class);

    if (Objects.nonNull(giftConfigCache)) {
      return giftConfigCache;
    }

    GiftConfigDTO newGiftConfigCache = orElseGet.apply(id);
    if (Objects.nonNull(newGiftConfigCache)) {
      redisService.hashPut(GiftKeys.LIST.getKey(),
          Objects.toString(newGiftConfigCache.getId()),
          newGiftConfigCache
      );
    }
    return newGiftConfigCache;
  }

  @Override
  public void remove() {
    redisService.delete(GiftKeys.LIST.getKey());
    redisService.delete("GIFT_INFO");
  }

  @Override
  public void pushListLastWeekExclusive(SysOriginPlatformEnum sysOrigin, String data) {
    redisService
        .setString(getListLastWeekExclusiveKey(sysOrigin), data, 10, TimeUnit.DAYS);
  }

  @Override
  public String getListLastWeekExclusive(SysOriginPlatformEnum sysOrigin) {
    return redisService.getString(getListLastWeekExclusiveKey(sysOrigin));
  }


  @Override
  public void pushListThisWeekExclusive(SysOriginPlatformEnum sysOrigin, String data) {
    redisService
        .setString(getListThisWeekExclusiveKey(sysOrigin), data, 2, TimeUnit.HOURS);
  }

  @Override
  public String getListThisWeekExclusive(SysOriginPlatformEnum sysOrigin) {
    return redisService.getString(getListThisWeekExclusiveKey(sysOrigin));
  }


  @Override
  public Long getPairCpGiveGiftId(SysOriginPlatformEnum sysOrigin) {
    return redisService.getStringToLong(getPairCpGiveGiftIdKey(sysOrigin));
  }

  @Override
  public void pushPairCpGiveGiftId(SysOriginPlatformEnum sysOrigin, Long giftId) {
    redisService.setString(getPairCpGiveGiftIdKey(sysOrigin), giftId);
  }

  /**
   * 老版本key, 无法回溯的缓存.
   */
  private String getListLastWeekExclusiveKey(SysOriginPlatformEnum sysOrigin) {
    return "LAST_WEEK_EXCLUSIVE_LIST:" + sysOrigin.name();
  }

  /**
   * 老版本key, 无法回溯的缓存.
   */
  private String getListThisWeekExclusiveKey(SysOriginPlatformEnum sysOrigin) {
    return "THIS_WEEK_EXCLUSIVE_LIST:" + sysOrigin.name();
  }

  /**
   * 老版本key, 无法回溯的缓存.
   */
  private String getPairCpGiveGiftIdKey(SysOriginPlatformEnum sysOrigin) {
    return "PAIR_CP_GIVE_GIFT_ID:" + sysOrigin.name();
  }
}
