package com.red.circle.other.infra.database.rds.service.game.impl;

import com.google.common.collect.Lists;
import com.red.circle.common.business.core.enums.GameStateEnum;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.other.infra.database.rds.dao.game.GameRoomPkRecordDAO;
import com.red.circle.other.infra.database.rds.entity.game.GameRoomPkRecord;
import com.red.circle.other.infra.database.rds.service.game.GameRoomPkRecordService;
import java.sql.Timestamp;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 房间PK记录 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2021-09-24
 */
@Service
@RequiredArgsConstructor
public class GameRoomPkRecordServiceImpl extends
    BaseServiceImpl<GameRoomPkRecordDAO, GameRoomPkRecord> implements GameRoomPkRecordService {

  private final GameRoomPkRecordDAO gameRoomPkRecordDAO;

  @Override
  public GameRoomPkRecord getByRoomIdByStatus(Long roomId, GameStateEnum gameStateEnum) {
    return gameRoomPkRecordDAO.getByRoomIdByStatus(roomId, gameStateEnum.name());
  }

  @Override
  public GameRoomPkRecord getByIdByStatus(Long id, GameStateEnum gameStateEnum) {
    return query()
        .eq(GameRoomPkRecord::getId, id)
        .eq(GameRoomPkRecord::getGameStatus, gameStateEnum)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

  @Override
  public GameRoomPkRecord getByUserIdByStatus(Long userId, GameStateEnum gameStateEnum) {
    return gameRoomPkRecordDAO.getByUserIdByStatus(userId, gameStateEnum.name());
  }

  @Override
  public GameRoomPkRecord getEfficientPkByRoomId(Long roomId) {
    return gameRoomPkRecordDAO.getEfficientPkByRoomId(roomId);
  }

  @Override
  public Boolean isCanJoinOrCreateGame(Long userId) {
    return Objects.isNull(gameRoomPkRecordDAO.isCanJoinOrCreateGameByUserId(userId));
  }

  @Override
  public void updateGameOverById(Long id) {
    update()
        .set(GameRoomPkRecord::getGameStatus, GameStateEnum.VOLUNTARILY_END.name())
        .eq(GameRoomPkRecord::getId, id).execute();
  }

  @Override
  public List<GameRoomPkRecord> listByLastIdByStatus(Long lastId, SysOriginPlatformEnum sysOrigin,
      GameStateEnum gameState, Long notRoomId, Long notUserId) {

    return Optional.ofNullable(query()
            .ne(Objects.isNull(notRoomId), GameRoomPkRecord::getSponsorUserId, notUserId)
            .ne(isUse(gameState) && Objects.isNull(notRoomId),
                GameRoomPkRecord::getRecipientUserId, notUserId)
            .ne(Objects.nonNull(notRoomId), GameRoomPkRecord::getSponsorRoomId, notRoomId)
            .ne(isUse(gameState) && Objects.nonNull(notRoomId),
                GameRoomPkRecord::getRecipientRoomId, notRoomId)
            .eq(GameRoomPkRecord::getSysOrigin, sysOrigin.name())
            .eq(GameRoomPkRecord::getGameStatus, gameState.name())
            .lt(Objects.nonNull(lastId), GameRoomPkRecord::getId, lastId)
            .last(PageConstant.DEFAULT_LIMIT)
            .orderByDesc(GameRoomPkRecord::getId)
            .list())
        .orElse(Lists.newArrayList());
  }

  private boolean isUse(GameStateEnum gameStateEnum) {
    return Objects.equals(gameStateEnum, GameStateEnum.STARTED) ||
        Objects.equals(gameStateEnum, GameStateEnum.END);
  }

  @Override
  public List<GameRoomPkRecord> listExpiredStartedRecordByNow(Timestamp nowTime) {
    return gameRoomPkRecordDAO.listExpiredStartedRecordByNow(nowTime);
  }

  @Override
  public List<GameRoomPkRecord> listExpiredWaitingRecordByNow(Timestamp nowTime) {
    return gameRoomPkRecordDAO.listExpiredWaitingRecordByNow(nowTime);
  }

  @Override
  public Boolean isCanGame(Long userId, Long roomId) {

    if (Objects.isNull(userId) || Objects.isNull(roomId)) {
      return Boolean.FALSE;
    }

    return Objects.isNull(gameRoomPkRecordDAO.isCanGame(userId, roomId));
  }


}



