package com.red.circle.game.fruit.application.command.query;

import com.google.common.collect.Lists;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.game.fruit.application.convertor.GameFruitAppConvertor;
import com.red.circle.game.fruit.application.dto.clientobject.GameFruitBoxRewardsCO;
import com.red.circle.game.fruit.application.dto.enums.MessageTypeTopic;
import com.red.circle.game.fruit.infrastructure.database.entity.GameFruitUserOpenedAward;
import com.red.circle.game.fruit.infrastructure.database.repository.GameFruitUserOpenedAwardService;
import com.red.circle.game.fruit.infrastructure.websocket.message.MessageSender;
import com.red.circle.game.fruit.infrastructure.websocket.message.TopicMessage;
import com.red.circle.other.inner.asserts.PropsErrorCode;
import com.red.circle.other.inner.endpoint.activity.PropsActivityClient;
import com.red.circle.other.inner.enums.activity.PropsActivityTypeEnum;
import com.red.circle.other.inner.model.dto.activity.props.ActivityResource;
import com.red.circle.other.inner.model.dto.activity.rule.GameFruitTaskContent;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.LocalDateUtils;
import com.red.circle.other.inner.asserts.user.UserErrorCode;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 游戏任务宝箱奖励
 *
 * @author zongpubin on 2023/12/12
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class GameFruitTaskBoxQryExe {
  private final RedisService redisService;
  private final MessageSender messageSender;
  private final UserProfileClient userProfileClient;
  private final GameFruitAppConvertor gameFruitAppConvertor;
  private final PropsActivityClient propsActivityCnfClient;
  private final GameFruitUserOpenedAwardService gameFruitUserOpenedAwardService;

  public void execute(Long userId) {
    List<ActivityResource> resources = Lists.newArrayList();
    String boxType;
    //开宝箱循环轮数
    Long boxRounds;
    // 用户数据
    UserProfileDTO userProfileDTO = ResponseAssert.requiredSuccess(
        userProfileClient.getByUserId(userId));

    if (Objects.isNull(userProfileDTO)) {
      messageSender.sendTopic(
          TopicMessage.of(
              MessageTypeTopic.GAME_FRUIT_BOX_REWARD_MSG.getTopicId(userId), ResultResponse.failure(
                  UserErrorCode.USER_INFO_NOT_FOUND)));
      return;
    }

    List<ActivityResource> winResources = ResponseAssert.requiredSuccess(propsActivityCnfClient
        .listActivityResource(SysOriginPlatformEnum.valueOf(userProfileDTO.getOriginSys()),
            PropsActivityTypeEnum.GAME_FRUIT_BOX_REWARD_WIN));

    List<ActivityResource> timesResources = ResponseAssert.requiredSuccess(propsActivityCnfClient
        .listActivityResource(SysOriginPlatformEnum.valueOf(userProfileDTO.getOriginSys()),
            PropsActivityTypeEnum.GAME_FRUIT_BOX_REWARD_TIMES));

    if (CollectionUtils.isEmpty(winResources) && CollectionUtils.isEmpty(timesResources)) {
      messageSender.sendTopic(
          TopicMessage.of(
              MessageTypeTopic.GAME_FRUIT_BOX_REWARD_MSG.getTopicId(userId), ResultResponse.failure(
                  PropsErrorCode.PROPS_RESOURCE_IS_EMPTY)));
      return;
    }

    GameFruitTaskContent winTask = GameFruitTaskContent.serializable(
        winResources.get(0).getJsonData());

    if (Objects.equals(winTask.getStatus(), Boolean.TRUE)) {
      resources.addAll(winResources);
      boxType = PropsActivityTypeEnum.GAME_FRUIT_BOX_REWARD_WIN.name();
      boxRounds = Optional.ofNullable(
          redisService.getStringToLong(getCommentRoundsKey(userId,boxType))).orElse(0L);
    } else {
      resources.addAll(timesResources);
      boxType = PropsActivityTypeEnum.GAME_FRUIT_BOX_REWARD_TIMES.name();
      boxRounds = Optional.ofNullable(
          redisService.getStringToLong(getCommentRoundsKey(userId,boxType))).orElse(0L);
    }

    Map<Long, GameFruitUserOpenedAward> openedAwardMap = gameFruitUserOpenedAwardService.getByUserIdAndDate(
        userId,
        LocalDateUtils.nowToInteger());

    List<GameFruitBoxRewardsCO> collect = resources.stream().map(resource -> {
      GameFruitBoxRewardsCO boxRewards = gameFruitAppConvertor.toGameFruitBoxRewardsCO(resource);
      boxRewards.setIsOpened(Objects.nonNull(openedAwardMap.get(boxRewards.getRule().getId())));
      boxRewards.setBoxType(boxType);
      boxRewards.setBoxRounds(boxRounds);
      return boxRewards;
    }).collect(Collectors.toList());

    messageSender.sendTopic(
        TopicMessage.of(
            MessageTypeTopic.GAME_FRUIT_BOX_REWARD_MSG.getTopicId(userId),
            ResultResponse.success(collect)
        ));

  }

  private String getCommentRoundsKey(Long userId, String activityType) {
    return "GAME_FRUIT_OPEN_BOX_ROUNDS:" + activityType + "_" + LocalDateUtils.nowToInteger() + "_"
        + userId;
  }
}
