package com.red.circle.other.app.inner.service.sys.impl;

import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.inner.service.sys.SysGameListConfigClientService;
import com.red.circle.other.infra.convertor.sys.SysGameListConfigInnerConvertor;
import com.red.circle.other.infra.database.cache.service.other.GameListCacheService;
import com.red.circle.other.infra.database.mongo.service.sys.GameMatchModelConfigService;
import com.red.circle.other.infra.database.rds.entity.sys.GameListConfig;
import com.red.circle.other.infra.database.rds.entity.user.user.BaseInfo;
import com.red.circle.other.infra.database.rds.service.game.GameUserLotteryDetailsRecordService;
import com.red.circle.other.infra.database.rds.service.game.GameUserLotteryRecordService;
import com.red.circle.other.infra.database.rds.service.game.GameUserShardsExchangeRecordService;
import com.red.circle.other.infra.database.rds.service.sys.GameListConfigService;
import com.red.circle.other.infra.database.rds.service.user.user.BaseInfoService;
import com.red.circle.other.inner.model.cmd.game.GameEggQryCmd;
import com.red.circle.other.inner.model.cmd.sys.SysGameListConfigParamCmd;
import com.red.circle.other.inner.model.cmd.sys.SysGameListQryCmd;
import com.red.circle.other.inner.model.cmd.sys.SysGameMatchModelConfigBackQryCmd;
import com.red.circle.other.inner.model.dto.game.GameUserLotteryDetailsRecordDTO;
import com.red.circle.other.inner.model.dto.game.GameUserLotteryRecordDTO;
import com.red.circle.other.inner.model.dto.game.GameUserShardsExchangeRecordDTO;
import com.red.circle.other.inner.model.dto.sys.GameMatchModelConfigDTO;
import com.red.circle.other.inner.model.dto.sys.GameModelDTO;
import com.red.circle.other.inner.model.dto.sys.SysGameListConfigDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.num.NumUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 游戏列表配置
 *
 * @author zongpubin on 2023/10/31
 */
@Service
@RequiredArgsConstructor
public class SysGameListConfigClientServiceImpl implements SysGameListConfigClientService {

  private final BaseInfoService baseInfoService;
  private final GameListCacheService gameListCacheService;
  private final GameListConfigService gameListConfigService;
  private final GameMatchModelConfigService gameMatchModelConfigService;
  private final SysGameListConfigInnerConvertor gameListConfigAppConvertor;
  private final GameUserLotteryRecordService gameUserLotteryRecordService;
  private final GameUserShardsExchangeRecordService gameUserShardsExchangeRecordService;
  private final GameUserLotteryDetailsRecordService gameUserLotteryDetailsRecordService;

  @Override
  public PageResult<SysGameListConfigDTO> pageQuery(SysGameListQryCmd query) {
    PageResult<GameListConfig> pageResult = gameListConfigService.pageQuery(query);
    return pageResult.convert(
        gameListConfigAppConvertor::toSysGameListConfigDTO);
  }

  @Override
  public void saveOrUpdate(SysGameListConfigParamCmd param) {
    GameListConfig gameListConfig = gameListConfigAppConvertor.toSysGameListConfig(param);
    gameListConfig.setRegions(StringUtils.join(param.getRegionList(), ","));

    gameListCacheService.remove(param.getSysOrigin());
    if (Objects.isNull(param.getId())) {
      gameListConfig.setId(IdWorkerUtils.getId());
      gameListConfigService.save(gameListConfig);
      return;
    }
    gameListConfigService.updateSelectiveById(gameListConfig);

  }

  @Override
  public void delete(Long id, String sysOrigin) {
    gameListConfigService.delete().eq(GameListConfig::getId, id).execute();
    gameListCacheService.remove(sysOrigin);
  }

  @Override
  public List<GameMatchModelConfigDTO> lisMatchConfig(SysGameMatchModelConfigBackQryCmd query) {
    return gameListConfigAppConvertor.toGameMatchModelConfigDTO(gameMatchModelConfigService.list(
        gameListConfigAppConvertor.toGameMatchModelConfigQuery(query)));
  }

  @Override
  public void addOrUpdateMatchConfig(GameMatchModelConfigDTO param) {
    if (Objects.isNull(param.getId())) {
      param.setId(IdWorkerUtils.getId());

      param.setModels(param.getModels().stream()
          .peek(model -> model.setOnlinePlayers(NumUtils.randomBetween(10, 999)))
          .collect(Collectors.toList()));

      List<BaseInfo> userBaseInfos = baseInfoService.listVest(4);
      if (CollectionUtils.isNotEmpty(userBaseInfos)) {
        param.setOnlinePlayersUsers(
            userBaseInfos.stream()
                .map(gameListConfigAppConvertor::toGamePlayersUserDTO)
                .collect(Collectors.toList())
        );
      }
      param.setModels(
          param.getModels().stream().sorted(Comparator.comparing(GameModelDTO::getPlayers)).collect(
              Collectors.toList()));
    }
    param.setUpdateTime(TimestampUtils.now());
    gameMatchModelConfigService.add(gameListConfigAppConvertor.toGameMatchModelConfig(param));
  }

  @Override
  public void removeMatchConfig(Long id) {
    gameMatchModelConfigService.removeById(id);
  }

  @Override
  public PageResult<GameUserLotteryRecordDTO> pageGameUserLotteryRecord(GameEggQryCmd query) {
    return gameUserLotteryRecordService.pageRecord(query)
        .convert(gameListConfigAppConvertor::toGameUserLotteryRecordDTO);
  }

  @Override
  public Map<Long, List<GameUserLotteryDetailsRecordDTO>> mapByLotteryIds(Set<Long> lotteryIds) {
    return gameUserLotteryDetailsRecordService.mapByLotteryIds(lotteryIds);
  }


  @Override
  public PageResult<GameUserShardsExchangeRecordDTO> pageUserShardsExchange(GameEggQryCmd query) {
    return gameUserShardsExchangeRecordService.pageRecord(
        query).convert(gameListConfigAppConvertor::toGameUserShardsExchangeRecordDTO);
  }


  @Override
  public SysGameListConfigDTO getByGameCode(String gameCode, String sysOrigin) {
    return gameListConfigAppConvertor.toSysGameListConfigDTO(
        gameListConfigService.getByGameCode(gameCode, sysOrigin));
  }

  @Override
  public Boolean checkGameUnshelve(Set<Long> gameIds) {
    return gameListConfigService.checkGameUnshelve(gameIds);
  }
}
