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

import com.google.common.collect.Lists;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.game.fruit.application.convertor.GameFruitTaskAppConvertor;
import com.red.circle.game.fruit.application.dto.clientobject.GameFruitBountyConfigCO;
import com.red.circle.game.fruit.application.dto.clientobject.GameFruitTaskAwardConfigCO;
import com.red.circle.game.fruit.application.dto.enums.MessageTypeTopic;
import com.red.circle.game.fruit.infrastructure.database.cache.service.GameFruitTaskCacheService;
import com.red.circle.game.fruit.infrastructure.database.entity.GameFruitBountyConfig;
import com.red.circle.game.fruit.infrastructure.database.repository.GameFruitBountyConfigService;
import com.red.circle.game.fruit.infrastructure.database.repository.GameFruitTaskAwardConfigService;
import com.red.circle.game.fruit.infrastructure.websocket.message.MessageSender;
import com.red.circle.game.fruit.infrastructure.websocket.message.TopicMessage;
import com.red.circle.game.fruit.inner.enums.GameFruitTaskEnum;
import com.red.circle.game.fruit.inner.error.GameFruitErrorCode;
import com.red.circle.tool.core.collection.CollectionUtils;
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.Comparator;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 游戏任务宝箱奖励
 *
 * @author zongpubin on 2023/12/12
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class GameFruitTaskQryExe {

  private final MessageSender messageSender;
  private final UserProfileClient userProfileClient;
  private final GameFruitTaskAppConvertor gameFruitTaskAppConvertor;
  private final GameFruitTaskCacheService gameFruitTaskCacheService;
  private final GameFruitBountyConfigService gameFruitBountyConfigService;
  private final GameFruitTaskAwardConfigService gameFruitTaskAwardConfigService;

  public void execute(Long userId) {
    List<GameFruitBountyConfigCO> result = Lists.newArrayList();
    // 用户数据
    UserProfileDTO userProfileDTO = ResponseAssert.requiredSuccess(
        userProfileClient.getByUserId(userId));

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

    List<GameFruitBountyConfig> bountyConfigs = gameFruitBountyConfigService.getBySysOrigin(
        userProfileDTO.getOriginSys());

    if (CollectionUtils.isEmpty(bountyConfigs)) {
      messageSender.sendTopic(
          TopicMessage.of(
              MessageTypeTopic.GAME_FRUIT_TASK_INFO_MSG.getTopicId(userId),
              ResultResponse.failure(
                  GameFruitErrorCode.GAME_FRUIT_BOUNTY_INFO_NOT_FOUND)));
      return;
    }

    Map<Long, List<GameFruitTaskAwardConfigCO>> mapTaskAwardConfigs = gameFruitTaskAwardConfigService.mapTaskAwardConfigs(
        userProfileDTO.getOriginSys(), userProfileDTO.getId());

    List<GameFruitBountyConfigCO> bountyConfigCOs = gameFruitTaskAppConvertor.toGameFruitBountyConfigCO(
        bountyConfigs);

    Integer dayCount = gameFruitTaskCacheService.getGameFruitTaskAward(
        userProfileDTO.getId(),
        GameFruitTaskEnum.TASK_COMPLETE_DAY.name());

    Integer weekCount = gameFruitTaskCacheService.getGameFruitTaskAward(
        userProfileDTO.getId(),
        GameFruitTaskEnum.TASK_COMPLETE_WEEK.name());

    for (GameFruitBountyConfigCO bountyConfigCO : bountyConfigCOs) {
      List<GameFruitTaskAwardConfigCO> configArray = Optional.ofNullable(
              mapTaskAwardConfigs.get(bountyConfigCO.getId()))
          .map(configs -> configs.stream().sorted(
              Comparator.comparing(GameFruitTaskAwardConfigCO::getSort)).collect(
              Collectors.toList())
          ).orElseGet(CollectionUtils::newArrayList);

      bountyConfigCO.setAwardConfigs(configArray);

      Set<Boolean> collect = configArray.stream().map(GameFruitTaskAwardConfigCO::getCompleted)
          .filter(Objects::nonNull).collect(Collectors.toSet());

      bountyConfigCO.setAllCompleted(
          collect.stream().allMatch(item -> Objects.equals(Boolean.TRUE, item)));

      if (Objects.equals(bountyConfigCO.getBountyType(), "DAILY")
          && bountyConfigCO.getAllCompleted()) {

        if (dayCount < 1) {
          gameFruitTaskCacheService.recordGameFruitTaskAward(userProfileDTO.getId(),
              GameFruitTaskEnum.TASK_COMPLETE_DAY.name());
        }

      } else if (Objects.equals(bountyConfigCO.getBountyType(), "WEEKLY")
          && bountyConfigCO.getAllCompleted()) {
        if (weekCount < 1) {
          gameFruitTaskCacheService.recordGameFruitTaskAward(userProfileDTO.getId(),
              GameFruitTaskEnum.TASK_COMPLETE_WEEK.name());
        }

      }
      result.add(bountyConfigCO);

    }
    messageSender.sendTopic(
        TopicMessage.of(
            MessageTypeTopic.GAME_FRUIT_TASK_INFO_MSG.getTopicId(userId),
            ResultResponse.success(result)
        ));

  }
}
