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.game.ktv.GameKtvSongCache;
import com.red.circle.other.infra.database.cache.key.GameKtvKeys;
import com.red.circle.other.infra.database.cache.service.other.GameKtvCacheService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.func.VoidCallable;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * KTV缓存实现.
 *
 * @author pengshigang on 2023/5/11
 */
@Service
@RequiredArgsConstructor
public class GameKtvCacheServiceImpl implements GameKtvCacheService {

  private final RedisService redisService;

  @Override
  public long getWaitCountDown(Long roomId) {
    return Optional.ofNullable(
        redisService
            .getExpire(GameKtvKeys.NEW_WAIT_COUNT_DOWN.getKey(roomId),TimeUnit.SECONDS)
    ).filter(val -> val >= 0).orElse(0L);
  }

  @Override
  public void cacheWaitCountDown(Long roomId) {
    redisService.setString(GameKtvKeys.NEW_WAIT_COUNT_DOWN.getKey(roomId),
        30, 30, TimeUnit.SECONDS);
  }


  @Override
  public void removeSongCountDown(Long roomId) {

    redisService.delete(GameKtvKeys.GAME_KTV_SONG_COUNT_DOWN.getKey(roomId));
  }

  @Override
  public long getSongCountDown(Long roomId) {
    return Optional.ofNullable(
        redisService
            .getExpire(GameKtvKeys.NEW_SONG_COUNT_DOWN.getKey(roomId),TimeUnit.SECONDS)
    ).filter(val -> val >= 0).orElse(0L);
  }

  @Override
  public void cacheSongCountDown(Long roomId, long countDown) {
    redisService.setString(GameKtvKeys.NEW_SONG_COUNT_DOWN.getKey(roomId),
        countDown, countDown, TimeUnit.SECONDS);
  }

  @Override
  public List<GameKtvSongCache> listKtvSongCache(String sysOrigin,
      VoidCallable<List<GameKtvSongCache>> orElsePut) {

    List<GameKtvSongCache> caches = redisService.hashGet(GameKtvKeys.KTV_SONG_CONFIG.getKey(),
        sysOrigin,
        new TypeReference<>() {
        });

    return Optional
        .ofNullable(caches)
        .map(ktvSongCaches -> ktvSongCaches.stream()
            .filter(Objects::nonNull)
            .collect(Collectors.toList())
        )
        .orElseGet(() -> {
          List<GameKtvSongCache> gameKtvSongCaches = orElsePut.apply();

          redisService.hashPut(GameKtvKeys.KTV_SONG_CONFIG.getKey(),
              sysOrigin,
              CollectionUtils.isNotEmpty(gameKtvSongCaches)
                  ? gameKtvSongCaches
                  : CollectionUtils.newArrayList()
          );

          return gameKtvSongCaches;
        });
  }

  @Override
  public void remove() {
    redisService.delete(GameKtvKeys.KTV_SONG_CONFIG.getKey());
  }


  @Override
  public Boolean isFreeIntegralMax(Long userId) {

    String key = GameKtvKeys.KTV_FREE_INTEGRAL_MAX
        .getKey(ZonedDateTimeAsiaRiyadhUtils.nowDateToInt() + "_" + userId);

    int integral = Optional.ofNullable(redisService.getStringToInteger(key))
        .orElse(0);
    if (integral >= 1000) {
      return Boolean.TRUE;
    }

    redisService.setIfAbsent(key, integral + 100, 2, TimeUnit.DAYS);
    return Boolean.FALSE;
  }

}
