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

import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Lists;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.func.VoidCallable;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.infra.database.cache.entity.user.InviteUserRedPacketCarouselAwardsCache;
import com.red.circle.other.infra.database.cache.entity.user.InviteUserRedPacketConfigCache;
import com.red.circle.other.infra.database.cache.key.user.UserInviteKey;
import com.red.circle.other.infra.database.cache.service.user.RedPacketInviteUserCacheService;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 红包邀新缓存.
 *
 * @author pengshigang on 2023/5/11
 */
@Service
@AllArgsConstructor
public class RedPacketInviteUserCacheServiceImpl implements RedPacketInviteUserCacheService {

  private final RedisService redisService;

  private String getCarouselAwardsKey(String sysOrigin) {
    return UserInviteKey.RED_PACKET_INVITE_USER_CAROUSEL_AWARDS.getKey(sysOrigin);
  }

  private String getConfigKey(String sysOrigin) {
    return UserInviteKey.RED_PACKET_INVITE_USER_CONFIG.getKey(sysOrigin);
  }

  @Override
  public List<InviteUserRedPacketCarouselAwardsCache> listCarouselAwardsCache(String sysOrigin,
      VoidCallable<List<InviteUserRedPacketCarouselAwardsCache>> orElsePut) {

    return Optional
        .ofNullable(redisService.getString(getCarouselAwardsKey(sysOrigin)))
        .map(str -> JacksonUtils.readValue(str,
            new TypeReference<List<InviteUserRedPacketCarouselAwardsCache>>() {
            }))
        .orElseGet(() -> {
          List<InviteUserRedPacketCarouselAwardsCache> caches = orElsePut.apply();
          caches.forEach(cache -> {
            if (Objects.equals(cache.getType(), "USD")) {
              cache.setImgUrl("/back/red-packet-invite-new-user-jd-mj.png");
            }
            if (Objects.equals(cache.getType(), "WITHDRAWAL")) {
              cache.setImgUrl("/back/red-packet-invite-new-user-jd-ljtx.png");
            }
            if (Objects.equals(cache.getType(), "TARGET")) {
              cache.setImgUrl("/back/red-packet-invite-new-user-jd-mb.png");
            }
            if (Objects.equals(cache.getType(), "DIAMOND")&&Objects.equals("ASWAT",sysOrigin)) {
              cache.setImgUrl("/back/red-packet-invite-new-user-jd-zs.png");
            }
            if (Objects.equals(cache.getType(), "DIAMOND")&&Objects.equals("TWO_FUN",sysOrigin)) {
              cache.setImgUrl("/back/diamond-purple.png");
            }
          });
          if (CollectionUtils.isNotEmpty(caches)) {
            redisService
                .setString(getCarouselAwardsKey(sysOrigin), JacksonUtils.toJson(caches));
          }
          return caches;
        });
  }

  @Override
  public void removeCarouselAwardsCache(String sysOrigin) {
    redisService.delete(getCarouselAwardsKey(sysOrigin));
  }

  @Override
  public InviteUserRedPacketConfigCache getConfigCache(String sysOrigin,
      VoidCallable<InviteUserRedPacketConfigCache> orElsePut) {

    return Optional
        .ofNullable(redisService.getString(getConfigKey(sysOrigin)))
        .map(str -> JacksonUtils.readValue(str, InviteUserRedPacketConfigCache.class))
        .orElseGet(() -> {
          InviteUserRedPacketConfigCache cache = orElsePut.apply();
          if (Objects.nonNull(cache)) {
            redisService
                .setString(getConfigKey(sysOrigin), JacksonUtils.toJson(cache));
          }
          return cache;
        });
  }

  @Override
  public void removeConfigCache(String sysOrigin) {
    redisService.delete(getConfigKey(sysOrigin));
  }

  private String getRedPacketAwardsKey(Long redPacketId) {
    return UserInviteKey.RED_PACKET_INVITE_AWARDS.getKey(redPacketId);
  }

  @Override
  public List<InviteUserRedPacketCarouselAwardsCache> getRedPacketAwards(Long redPacketId) {

    String str = redisService.getString(getRedPacketAwardsKey(redPacketId));
    if (StringUtils.isBlank(str)) {
      return Lists.newArrayList();
    }

    return Optional.ofNullable(JacksonUtils.readValue(str,
        new TypeReference<List<InviteUserRedPacketCarouselAwardsCache>>() {
        })).orElse(Lists.newArrayList());
  }

  @Override
  public void cacheRedPacketAwards(Long redPacketId,
      List<InviteUserRedPacketCarouselAwardsCache> otherList) {

    redisService.setString(getRedPacketAwardsKey(redPacketId),
        JacksonUtils.toJson(otherList), 3, TimeUnit.DAYS);
  }

  private String getRedPacketLotteryCountKey(Long redPacketId) {
    return UserInviteKey.RED_PACKET_LOTTERY_COUNT.getKey(redPacketId);
  }

  @Override
  public Long getRedPacketLotteryCount(Long redPacketId) {
    return redisService.getStringToLong(getRedPacketLotteryCountKey(redPacketId));
  }

  @Override
  public void incrRedPacketLotteryCount(Long redPacketId) {
    redisService.increment(getRedPacketLotteryCountKey(redPacketId), 1, 3,
        TimeUnit.DAYS);
  }

  @Override
  public Long decrRedPacketLotteryCount(Long redPacketId) {
    return redisService.decrement(getRedPacketLotteryCountKey(redPacketId), 1, 3,
        TimeUnit.DAYS);
  }

  private String getTodayHelpUsersKey(Long userId, Long day) {
    return UserInviteKey.RED_PACKET_TODAY_HELP_USERS.getKey(userId) + "_" + day;
  }

  @Override
  public List<Long> getTodayHelpUsers(Long userId, Long day) {

    String str = redisService.getString(getTodayHelpUsersKey(userId, day));
    if (StringUtils.isBlank(str)) {
      return Lists.newArrayList();
    }
    List<Long> userIds = JacksonUtils.readValue(str, new TypeReference<>() {
    });
    return Optional.ofNullable(userIds).orElse(Lists.newArrayList());
  }

  @Override
  public void cacheTodayHelpUsers(Long userId, Long day, Long toHelpUserId) {

    String str = redisService.getString(getTodayHelpUsersKey(userId, day));
    List<Long> toHelpUserIds = Lists.newArrayList();
    if (StringUtils.isBlank(str)) {
      toHelpUserIds.add(toHelpUserId);
      redisService.setString(getTodayHelpUsersKey(userId, day),
          JacksonUtils.toJson(toHelpUserIds), 3, TimeUnit.DAYS);
      return;
    }
    toHelpUserIds = JacksonUtils.readValue(str, new TypeReference<>() {
    });
    if (CollectionUtils.isEmpty(toHelpUserIds)) {
      redisService.setString(getTodayHelpUsersKey(userId, day),
          JacksonUtils.toJson(Lists.newArrayList(toHelpUserId)), 3, TimeUnit.DAYS);
      return;
    }
    if (toHelpUserIds.contains(toHelpUserId)) {
      return;
    }
    toHelpUserIds.add(toHelpUserId);
    redisService.setString(getTodayHelpUsersKey(userId, day),
        JacksonUtils.toJson(toHelpUserIds), 3, TimeUnit.DAYS);
  }

  private String getReturnUserHelpKey(Long userId) {
    return UserInviteKey.RED_PACKET_RETURN_USER_HELP.getKey(userId);
  }

  @Override
  public List<Long> getReturnUserHelp(Long userId) {

    String str = redisService.getString(getReturnUserHelpKey(userId));
    if (StringUtils.isBlank(str)) {
      return Lists.newArrayList();
    }
    List<Long> userIds = JacksonUtils.readValue(str, new TypeReference<>() {
    });
    return Optional.ofNullable(userIds).orElse(Lists.newArrayList());
  }

  @Override
  public void cacheReturnUserHelp(Long userId, Long toHelpUserId) {

    String str = redisService.getString(getReturnUserHelpKey(userId));
    List<Long> toHelpUserIds = Lists.newArrayList();
    if (StringUtils.isBlank(str)) {
      toHelpUserIds.add(toHelpUserId);
      redisService.setString(getReturnUserHelpKey(userId),
          JacksonUtils.toJson(toHelpUserIds), 5, TimeUnit.DAYS);
      return;
    }
    toHelpUserIds = JacksonUtils.readValue(str, new TypeReference<>() {
    });
    if (CollectionUtils.isEmpty(toHelpUserIds)) {
      redisService.setString(getReturnUserHelpKey(userId),
          JacksonUtils.toJson(Lists.newArrayList(toHelpUserId)), 5, TimeUnit.DAYS);
      return;
    }
    if (toHelpUserIds.contains(toHelpUserId)) {
      return;
    }
    toHelpUserIds.add(toHelpUserId);
    redisService.setString(getReturnUserHelpKey(userId),
        JacksonUtils.toJson(toHelpUserIds), 5, TimeUnit.DAYS);
  }

  private String getAllIncrLotteryCountKey(String sysOrigin) {
    return UserInviteKey.RED_PACKET_ALL_INCR_LOTTERY_COUNT.getKey(sysOrigin);
  }

  @Override
  public Long incrLotteryCount(String sysOrigin) {

    return redisService.increment(getAllIncrLotteryCountKey(sysOrigin), 180,
        TimeUnit.DAYS);
  }

  @Override
  public void resetLotteryCount(String sysOrigin) {
    redisService.setString(getAllIncrLotteryCountKey(sysOrigin), 0, 180, TimeUnit.DAYS);
  }

  private String getWithdrawPrizesKey(String sysOrigin) {
    return UserInviteKey.RED_PACKET_WITHDRAW_PRIZES.getKey(sysOrigin);
  }

  @Override
  public Boolean existWithdrawPrizes(String sysOrigin) {
    return Optional.ofNullable(redisService.getStringToBool(getWithdrawPrizesKey(sysOrigin)))
        .orElse(Boolean.TRUE);
  }

  @Override
  public void receiveWithdrawPrizes(String sysOrigin) {
    redisService.setString(getWithdrawPrizesKey(sysOrigin), Boolean.FALSE, 180,
        TimeUnit.DAYS);
  }

  @Override
  public void resetWithdrawPrizes(String sysOrigin) {
    redisService.setString(getWithdrawPrizesKey(sysOrigin), Boolean.TRUE, 180,
        TimeUnit.DAYS);
  }

}
