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

import com.fasterxml.jackson.core.type.TypeReference;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.other.infra.database.cache.entity.sys.BannerCache;
import com.red.circle.other.infra.database.cache.key.BannerKeys;
import com.red.circle.other.infra.database.cache.service.other.BannerCacheService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.func.VoidCallable;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 实现平台banner 缓存.
 *
 * @author pengliang on 2021/9/15
 */
@Service
@RequiredArgsConstructor
public class BannerCacheServiceImpl implements BannerCacheService {

  private final RedisService redisService;


  private String getBannerKey(String sysOrigin, String reqClient, String countryCode, List<String> types) {
    String typesKey = (types == null || types.isEmpty()) ? "ALL" : types.toString();
    return String.join("_", BannerKeys.BANNER.name(), sysOrigin, reqClient, countryCode, typesKey);
  }

  @Override
  public List<BannerCache> listBannerCacheBySysOrigin(String sysOrigin, String reqClient, String countryCode, List<String> types, VoidCallable<List<BannerCache>> orElsePut) {

    return Optional
            .ofNullable(redisService.hashGet(BannerKeys.BANNER.getKey(), getBannerKey(sysOrigin, reqClient, countryCode, types),
            new TypeReference<List<BannerCache>>() {
            }))
        .map(bannerCaches -> bannerCaches.stream()
            .filter(Objects::nonNull)
            .filter(bannerCache ->
                Objects.nonNull(bannerCache.getStartTime())
                    && bannerCache.getStartTime().before(TimestampUtils.now()) &&
                    Objects.nonNull(bannerCache.getExpiredTime())
                    && bannerCache.getExpiredTime().after(TimestampUtils.now()))
            .collect(Collectors.toList()))
        .orElseGet(() -> {
          List<BannerCache> bannerCaches = orElsePut.apply();
          if (CollectionUtils.isNotEmpty(bannerCaches)) {
            redisService.hashPut(BannerKeys.BANNER.getKey(), getBannerKey(sysOrigin, reqClient, countryCode, types),
                bannerCaches);
          }
          return bannerCaches;
        });
  }

  @Override
  public void remove(String sysOrigin) {
      redisService.delete(BannerKeys.BANNER.getKey());
      redisService.hashDelete(BannerKeys.BANNER.getKey());
      // 兼容新服务
      redisService.delete("BANNER:BANNER");
  }

}
