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.RoomManagerKeys;
import com.red.circle.other.infra.database.cache.service.other.RoomManagerCacheService;
import com.red.circle.other.infra.database.rds.service.live.RoomMemberService;
import com.red.circle.other.inner.enums.live.RoomUserRolesEnum;
import com.red.circle.tool.core.text.StringUtils;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 房间管理缓存 实现.
 *
 * @author pengliang on 2021/7/28
 */
@Service
@RequiredArgsConstructor
public class RoomManagerCacheServiceImpl implements RoomManagerCacheService {

  private final RedisService redisService;
  private final RoomMemberService roomMemberService;

  @Override
  public Long getNumberPeople(Long roomAccount) {
    return redisService.getStringToLong(RoomManagerKeys.MEMBER_NUM.getKey(roomAccount));
  }

  @Override
  public Long setNumberPeople(String roomAccount, Long numberPeople) {
    redisService.delete(RoomManagerKeys.MEMBER_NUM.getKey(roomAccount));
    redisService.increment(RoomManagerKeys.MEMBER_NUM.getKey(roomAccount),
        numberPeople,
        10,
        TimeUnit.MINUTES);
    return numberPeople;
  }

  @Override
  public Long incrementNumberPeople(String roomAccount) {
    return redisService.increment(RoomManagerKeys.MEMBER_NUM.getKey(roomAccount),
        10,
        TimeUnit.MINUTES);
  }

  @Override
  public Long decrementNumberPeople(String roomAccount) {
    return redisService.decrement(RoomManagerKeys.MEMBER_NUM.getKey(roomAccount),
        10,
        TimeUnit.MINUTES);
  }

  @Override
  public void removeNumberPeople(String roomAccount) {
    redisService.delete(RoomManagerKeys.MEMBER_NUM.getKey(roomAccount));
  }

  @Override
  public RoomUserRolesEnum getRoomUserRoles(Long userId, Long roomId) {
    return getRoomUserRoles(userId, roomId, roomMemberService::getRoomUserRoles);
  }

  @Override
  public void removeRoomUserRoles(Long userId, Long roomId) {
    redisService.delete(RoomManagerKeys.ROOM_ROLES.getKey(userId, roomId));
  }

  private RoomUserRolesEnum getRoomUserRoles(Long userId, Long roomId,
      BiFunction<Long, Long, RoomUserRolesEnum> orElseGetAndPut) {

    String key = RoomManagerKeys.ROOM_ROLES.getKey(userId, roomId);

    String roles = redisService.getString(key);
    if (StringUtils.isNotBlank(roles)) {
      return RoomUserRolesEnum.valueOf(roles);
    }
    RoomUserRolesEnum newRoles = orElseGetAndPut.apply(userId, roomId);
    if (Objects.nonNull(newRoles)) {
      redisService.setString(key, newRoles, 1, TimeUnit.DAYS);
      return newRoles;
    }

    redisService.setString(key, RoomUserRolesEnum.TOURIST, 1, TimeUnit.DAYS);
    return RoomUserRolesEnum.TOURIST;
  }

}
