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

import com.red.circle.component.redis.service.RedisService;
import com.red.circle.other.infra.database.cache.key.CheckInKeys;
import com.red.circle.other.infra.database.cache.service.other.CheckInCacheService;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * 7日打卡.
 *
 * @author pengliang on 2020/10/9
 */
@Service
@RequiredArgsConstructor
public class CheckInCacheServiceImpl implements CheckInCacheService {

  private final RedisService redisService;

  @Override
  public Long incrCheckInDays(Long userId, long timeoutMilliseconds) {
    return incrCheckInDays(CheckInKeys.SEVEN_CHECK_IN.getKey(userId),
        timeoutMilliseconds);
  }

  private Long incrCheckInDays(String key, long timeoutMilliseconds) {
    Long size = Optional.ofNullable(redisService.increment(key)).orElse(0L);
    redisService.expire(key, timeoutMilliseconds, TimeUnit.MILLISECONDS);
    return size;
  }

  @Override
  public Integer getCheckInDays(Long userId) {
    return getCheckInDays(CheckInKeys.SEVEN_CHECK_IN.getKey(userId));
  }

  private Integer getCheckInDays(String key) {
    return Optional.ofNullable(redisService.getStringToInteger(key)).orElse(null);
  }

  @Override
  public Boolean markDaySevenCheckIn(Long userId, long timeoutMilliseconds) {
    return markDaySevenCheckIn(CheckInKeys.DAY_SEVEN_CHECK_IN.getKey(userId),
        timeoutMilliseconds);
  }

  private Boolean markDaySevenCheckIn(String key, long timeoutMilliseconds) {
    return redisService
        .setIfAbsent(key, 1,
            timeoutMilliseconds, TimeUnit.MILLISECONDS);
  }

  @Override
  public Boolean getMarkDaySevenCheckIn(Long userId) {
    return getMarkDaySevenCheckIn(CheckInKeys.DAY_SEVEN_CHECK_IN.getKey(userId));
  }

  private Boolean getMarkDaySevenCheckIn(String key) {
    return Objects.equals(redisService.getStringToInteger(key), 1);
  }

  @Override
  public Boolean markDailyCheckIn(Long userId) {
    return redisService.setIfAbsent(CheckInKeys.DAILY_CHECK_IN
            .getKey("DAILY_CHECK_IN_" + userId + ZonedDateTimeAsiaRiyadhUtils.nowDateToInt()),
        1, 2, TimeUnit.DAYS);

  }

  @Override
  public Boolean checkDailyCheckIn(Long userId) {

    return StringUtils.isNotBlank(redisService
        .getString(CheckInKeys.DAILY_CHECK_IN.getKey(
            "DAILY_CHECK_IN_" + userId + ZonedDateTimeAsiaRiyadhUtils.nowDateToInt())));
  }
}
