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

import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.game.fruit.infrastructure.database.dao.GameFruitRoundRecordDAO;
import com.red.circle.game.fruit.infrastructure.database.entity.GameFruitRoundRecord;
import com.red.circle.game.fruit.infrastructure.database.repository.GameFruitRoundRecordService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateUtils;
import com.red.circle.tool.core.date.LocalDateUtils;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 游戏每轮记录 服务实现类.
 * </p>
 *
 * @author lisizhe on 2023-11-30 19:18
 */
@Service
public class GameFruitRoundRecordServiceImpl extends
    BaseServiceImpl<GameFruitRoundRecordDAO, GameFruitRoundRecord> implements
    GameFruitRoundRecordService {

  @Override
  public GameFruitRoundRecord getGameRound() {
    return query().orderByDesc(GameFruitRoundRecord::getId).getOne();
  }

  @Override
  public List<GameFruitRoundRecord> limitRound(Set<Long> gameIds, Integer limit) {
    return query()
        .in(CollectionUtils.isNotEmpty(gameIds), GameFruitRoundRecord::getId, gameIds)
        .orderByDesc(GameFruitRoundRecord::getId)
        .last(PageConstant.formatLimit(limit)).list();
  }

  @Override
  public Map<Long, Integer> mapGameRound(Set<Long> gameIds) {
    if (CollectionUtils.isEmpty(gameIds)) {
      return CollectionUtils.newHashMap();
    }
    return Optional.ofNullable(query()
            .in(GameFruitRoundRecord::getId, gameIds)
            .orderByDesc(GameFruitRoundRecord::getId).list())
        .map(list -> list.stream()
            .collect(Collectors.toMap(GameFruitRoundRecord::getId, GameFruitRoundRecord::getRound)))
        .orElse(CollectionUtils.newHashMap());
  }

  @Override
  public void addUserExpend(GameFruitRoundRecord gameFruitRoundRecord) {
    GameFruitRoundRecord gameFruitRound = baseDAO.getByIdForUpdate(gameFruitRoundRecord.getId());
//    GameFruitRoundRecord gameFruitRound = query().eq(GameFruitRoundRecord::getId,
//        gameFruitRoundRecord.getId()).getOne();
    ResponseAssert.notNull(CommonErrorCode.NOT_FOUND_RECORD_INFO, gameFruitRound);

    update().set(GameFruitRoundRecord::getUserExpend,
            gameFruitRound.getUserExpend().add(gameFruitRoundRecord.getUserExpend()))
        .eq(GameFruitRoundRecord::getId, gameFruitRoundRecord.getId()).execute();
  }

  @Override
  public void addPlatformExpend(Long gameId, Integer expendSum) {
    update().set(GameFruitRoundRecord::getPlatformExpend,
            expendSum)
        .eq(GameFruitRoundRecord::getId, gameId).execute();
  }

  @Override
  public void finish() {
    GameFruitRoundRecord gameFruitRoundRecord = getGameRound();
    ResponseAssert.notNull(CommonErrorCode.NOT_FOUND_RECORD_INFO, gameFruitRoundRecord);
    update()
        .set(GameFruitRoundRecord::getEndTime, DateUtils.now())
        .eq(GameFruitRoundRecord::getId, gameFruitRoundRecord.getId())
        .execute()
    ;

  }

  @Override
  public Long countTodayPlayTimes(Long userId) {
    return baseDAO.countTodayPlayTimes(userId, LocalDateUtils.nowToInteger());
  }

  @Override
  public void start(GameFruitRoundRecord gameFruitRoundRecord) {
    save(gameFruitRoundRecord);
  }
}
