package com.red.circle.game.fruit.infrastructure.database.repository.impl;

import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.game.fruit.application.dto.clientobject.GameFruitAwardRecordCO;
import com.red.circle.game.fruit.application.dto.cmd.UserBetCmd;
import com.red.circle.game.fruit.application.dto.enums.MessageTypeTopic;
import com.red.circle.game.fruit.infrastructure.database.dao.GameFruitUserDAO;
import com.red.circle.game.fruit.infrastructure.database.entity.GameFruitUser;
import com.red.circle.game.fruit.infrastructure.database.repository.GameFruitUserService;
import com.red.circle.game.fruit.infrastructure.websocket.message.MessageSender;
import com.red.circle.game.fruit.infrastructure.websocket.message.TopicMessage;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateUtils;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 服务实现类.
 * </p>
 *
 * @author lisizhe on 2023-11-30 19:17
 */
@Service
@RequiredArgsConstructor
public class GameFruitUserServiceImpl extends
    BaseServiceImpl<GameFruitUserDAO, GameFruitUser> implements GameFruitUserService {

  private final MessageSender messageSender;

  @Override
  public void updateBetAmount(UserBetCmd cmd) {
    GameFruitUser gameFruitUser = query().eq(GameFruitUser::getUserId, cmd.getUid()).getOne();
    if (Objects.isNull(gameFruitUser)) {
      messageSender.sendTopic(
          TopicMessage.of(
              MessageTypeTopic.USER_BET_MSG.getTopicId(cmd.getUid()), ResultResponse.failure(
                  UserErrorCode.USER_INFO_NOT_FOUND)));
      return;
    }

    update().set(GameFruitUser::getBetAmount, cmd.getSumAmount().add(gameFruitUser.getBetAmount()))
        .set(GameFruitUser::getBetSize, gameFruitUser.getBetSize() + 1)
        .eq(GameFruitUser::getUserId, cmd.getUid()).execute();
  }

  @Override
  public GameFruitUser getGameUser(Long userId) {
    return query().eq(GameFruitUser::getUserId, userId).last(PageConstant.LIMIT_ONE).getOne();
  }

  @Override
  public void addGameUser(Long userId, String origin) {
    // 不存在则新增游戏用户数据并且新增参与人数
      GameFruitUser gameUser = new GameFruitUser()
          .setUserId(userId)
          .setSysOrigin(origin)
          .setLastActiveTime(DateUtils.now());
      save(gameUser);
  }

  @Override
  public void updateUserActiveTime(Long userId) {
    update().set(GameFruitUser::getLastActiveTime, DateUtils.now())
        .eq(GameFruitUser::getUserId, userId).execute();
  }

  @Override
  public void plusProfit(List<GameFruitAwardRecordCO> gameFruitAwardRecords) {
    baseDAO.plusProfit(gameFruitAwardRecords);
  }

  @Override
  public Map<Long, GameFruitUser> mapGameFruitUser(Set<Long> userIds) {
    return Optional.ofNullable(
        query().in(GameFruitUser::getUserId, userIds)
            .last(PageConstant.formatLimit(userIds.size()))
            .list()
    ).map(
        list -> list.stream().collect(Collectors.toMap(
            GameFruitUser::getUserId, v -> v
        ))
    ).orElse(CollectionUtils.newHashMap());
  }
}
