package com.red.circle.game.fruit.application.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.game.fruit.application.command.UserBetExe;
import com.red.circle.game.fruit.application.convertor.GameFruitAppConvertor;
import com.red.circle.game.fruit.application.dto.clientobject.DaysRankingCO;
import com.red.circle.game.fruit.application.dto.cmd.BetPrizeCmd;
import com.red.circle.game.fruit.application.dto.cmd.UserBetCmd;
import com.red.circle.game.fruit.application.dto.enums.GameSysOriginEnum;
import com.red.circle.game.fruit.application.dto.enums.MessageTypeTopic;
import com.red.circle.game.fruit.application.service.UserRankingService;
import com.red.circle.game.fruit.core.domain.gateway.DaysRankingGateway;
import com.red.circle.game.fruit.infrastructure.database.entity.GameFruitPrize;
import com.red.circle.game.fruit.infrastructure.database.entity.GameFruitUser;
import com.red.circle.game.fruit.infrastructure.database.entity.GameFruitUserDaysRanking;
import com.red.circle.game.fruit.infrastructure.database.memory.service.GameFruitMemoryService;
import com.red.circle.game.fruit.infrastructure.database.repository.GameFruitPrizeService;
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.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
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;

/**
 * <p>
 * 用户每日盈利排名 服务实现类.
 * </p>
 *
 * @author lisizhe on 2023-11-30 19:17
 */
@Service
@RequiredArgsConstructor
public class UserRankingServiceImpl implements UserRankingService {

  private final UserBetExe userBetExe;
  private final MessageSender messageSender;
  private final UserProfileClient userProfileClient;
  private final DaysRankingGateway daysRankingGateway;
  private final GameFruitUserService gameFruitUserService;
  private final GameFruitAppConvertor gameFruitAppConvertor;
  private final GameFruitPrizeService gameFruitPrizeService;
  private final GameFruitMemoryService gameFruitMemoryService;

  @Override
  public void listRankingTop(Long userId) {
    GameFruitUser gameFruitUser = gameFruitUserService.getGameUser(userId);
    if (Objects.isNull(gameFruitUser)) {
      messageSender.sendTopic(TopicMessage.of(MessageTypeTopic.USER_RANKING_MSG.getTopicId(userId),
          ResultResponse.failure(UserErrorCode.USER_NOT_REGISTERED)));
    }
    List<GameFruitUserDaysRanking> daysRankings = daysRankingGateway.listRankingTop(10,
        gameFruitUser.getSysOrigin());
    messageSender.sendTopic(TopicMessage.of(MessageTypeTopic.USER_RANKING_MSG.getTopicId(userId),
        ResultResponse.success(listRanking(daysRankings))));
  }

  @Override
  public void listRankingTop3(Long userId) {
    GameFruitUser gameFruitUser = gameFruitUserService.getGameUser(userId);
    if (Objects.isNull(gameFruitUser)) {
      messageSender.sendTopic(TopicMessage.of(MessageTypeTopic.USER_RANKING_MSG.getTopicId(userId),
          ResultResponse.failure(UserErrorCode.USER_NOT_REGISTERED)));
    }
    List<GameFruitUserDaysRanking> daysRankings = daysRankingGateway.listRankingTop(3,
        gameFruitUser.getSysOrigin());

    messageSender.sendTopic(TopicMessage.of(MessageTypeTopic.RANKING_TOP3_MSG.getTopicId(userId),
        ResultResponse.success(listRanking(daysRankings))));
  }

  @Override
  public void testBet() {
    int sec = gameFruitMemoryService.getRoundSec();

    /*Set<Long> addUsers = new HashSet<>();
    addUsers.add(1719923367338016770L);
    addUsers.add(1720018073213001729L);
    addUsers.add(1719638661159133186L);
    addUsers.add(1742004689374326786L);
    addUsers.add(1740693723590230018L);
    addUsers.add(1730509960843681793L);

    for (Long addUser : addUsers) {

      GameFruitUser gameFruitUser = gameFruitUserService.getGameUser(addUser);

      if(Objects.isNull(gameFruitUser)){
        gameFruitUserService.addGameUser(addUser, GameSysOriginEnum.TWO_FUN.getSysOrigin());
      }
    }*/
    if (sec <= 15) {
      return;
    }
    // 查询出二十个用户
    Set<Long> userIds = new HashSet<>();
    /*userIds.add(1730469681665413122L);
    userIds.add(1730469496931487746L);
    userIds.add(1730468906715492354L);
    userIds.add(1730428391307522050L);
    userIds.add(1730168366120775682L);
    userIds.add(1730470142195798018L);
    userIds.add(1731980453114265602L);
    userIds.add(1730470670755868673L);
    userIds.add(1732249512901672961L);
    userIds.add(1732309344576929794L);
    userIds.add(1737720560403742722L);
    userIds.add(1730166828820279297L);
    userIds.add(1730045417734975490L);
    userIds.add(1722071017400897537L);
    userIds.add(1721775241065525249L);
    userIds.add(1721711849923096577L);
    userIds.add(1719913439515287554L);
    userIds.add(1718944645920239617L);
    userIds.add(1718929768405184513L);
    userIds.add(1718926825224318978L);*/

   /* userIds.add(1719923367338016770L);
    userIds.add(1720018073213001729L);
    userIds.add(1719638661159133186L);
    userIds.add(1742004689374326786L);
    userIds.add(1740693723590230018L);
    userIds.add(1730509960843681793L);*/

    userIds.add(1742127073865691138L);
    // 查询出所有奖品，随机出某个奖品下注

    Map<Long, GameFruitPrize> gameFruitPrizeMap = gameFruitPrizeService.mapPrize(
        GameSysOriginEnum.TWO_FUN.getSysOrigin());

    List<GameFruitPrize> gameFruitPrizes = gameFruitPrizeMap.values().stream().toList();

    userIds.forEach(item -> {


      List<BetPrizeCmd> userBetCmds = new ArrayList<>();

      int prizeNum = RandomUtil.randomInt(1, 3);

      GameFruitUser gameFruitUser = gameFruitUserService.getGameUser(item);

      if(Objects.isNull(gameFruitUser)){
        gameFruitUserService.addGameUser(item, GameSysOriginEnum.TWO_FUN.getSysOrigin());
      }

      userBetCmds.add(new BetPrizeCmd().setPrizeId(gameFruitPrizes.get(prizeNum).getId())
          .setBetAmount(BigDecimal.valueOf(10)));
      userBetExe.execute(new UserBetCmd().setUid(item)
          .setBetPrizes(userBetCmds)
          .setAutoStart(0));
      /*try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }*/
    });
  }

  private List<DaysRankingCO> listRanking(
      List<GameFruitUserDaysRanking> gameFruitUserDaysRankings) {

    List<DaysRankingCO> resultList;
    if (CollectionUtils.isEmpty(gameFruitUserDaysRankings)) {
      resultList = CollectionUtils.newArrayList();
    } else {
      Map<Long, UserProfileDTO> userProfileMap = ResponseAssert.requiredSuccess(
          userProfileClient.mapByUserIds(
              gameFruitUserDaysRankings.stream().map(GameFruitUserDaysRanking::getUserId).collect(
                  Collectors.toSet())));
      resultList = gameFruitUserDaysRankings.stream().map(item -> {
        DaysRankingCO co = gameFruitAppConvertor.toDaysRankingCO(item);
        co.setUserInfo(
            gameFruitAppConvertor.toGameUserInfoCO(userProfileMap.get(item.getUserId())));
        return co;
      }).toList();
    }
    return resultList;
  }
}
