package com.red.circle.other.app.command.activity;

import com.red.circle.other.app.dto.clientobject.activity.LotteryRankCO;
import com.red.circle.other.app.dto.cmd.activity.LotteryRankQryCmd;
import com.red.circle.other.infra.database.rds.entity.activity.LotteryUserProgress;
import com.red.circle.other.infra.database.rds.service.activity.LotteryUserProgressService;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.text.StringUtils;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 查询抽奖排行榜.
 *
 * @author system
 * @since 2025-10-21
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class LotteryRankQryExe {

  private final LotteryUserProgressService lotteryUserProgressService;
  private final UserProfileClient userProfileClient;

  public List<LotteryRankCO> execute(LotteryRankQryCmd cmd) {
    Long currentUserId = cmd.getReqUserId();
    
    // 1. 确定周标识
    String weekKey = StringUtils.isNotBlank(cmd.getWeekKey()) 
        ? cmd.getWeekKey() 
        : getCurrentWeekKey();

    // 2. 查询排行榜数据
    List<LotteryUserProgress> progressList = queryRankData(cmd.getActivityId(), weekKey, cmd.getRankType(), cmd.getLimit());

    if (progressList.isEmpty()) {
      return new ArrayList<>();
    }

    // 3. 获取用户信息
    List<Long> userIds = progressList.stream()
        .map(LotteryUserProgress::getUserId)
        .collect(Collectors.toList());
    
    Map<Long, UserProfileDTO> userMap = getUserProfiles(userIds);

    // 4. 组装排行榜数据
    List<LotteryRankCO> rankList = new ArrayList<>();
    int rank = 1;
    
    for (LotteryUserProgress progress : progressList) {
      UserProfileDTO user = userMap.get(progress.getUserId());
      if (user == null) {
        continue;
      }

      LotteryRankCO rankCO = new LotteryRankCO();
      rankCO.setRank(rank++);
      rankCO.setUserId(progress.getUserId());
      rankCO.setAccount(user.getAccount());
      rankCO.setNickname(user.getUserNickname());
      rankCO.setAvatar(user.getUserAvatar());
      rankCO.setTotalAmount(progress.getTotalAmount());
      rankCO.setTotalDrawCount(progress.getTotalDrawCount());
      rankCO.setBigPrizeCount(progress.getBigPrizeCount());
      rankCO.setWeekKey(weekKey);
      rankCO.setIsMe(currentUserId != null && currentUserId.equals(progress.getUserId()));
      
      rankList.add(rankCO);
    }

    return rankList;
  }

  /**
   * 查询排行榜数据.
   */
  private List<LotteryUserProgress> queryRankData(Long activityId, String weekKey, String rankType, Integer limit) {
    var query = lotteryUserProgressService.query()
        .eq(LotteryUserProgress::getWeekKey, weekKey);

    // 如果指定了活动ID
    if (activityId != null) {
      query.eq(LotteryUserProgress::getActivityId, activityId);
    }

    // 根据排行榜类型排序
    if ("DRAW_COUNT".equals(rankType)) {
      query.orderByDesc(LotteryUserProgress::getTotalDrawCount);
    } else {
      // 默认按金额排序
      query.orderByDesc(LotteryUserProgress::getTotalAmount);
    }

    // 限制数量
    query.last("LIMIT " + limit);

    return query.list();
  }

  /**
   * 获取用户信息.
   */
  private Map<Long, UserProfileDTO> getUserProfiles(List<Long> userIds) {
    try {
      List<UserProfileDTO> users = userProfileClient.listByUserId(new HashSet<>(userIds)).getBody();
      if (users != null) {
        return users.stream()
            .collect(Collectors.toMap(UserProfileDTO::getId, user -> user, (a, b) -> a));
      }
    } catch (Exception e) {
      log.error("Failed to get user profiles", e);
    }
    return Map.of();
  }

  /**
   * 获取当前周标识.
   */
  private String getCurrentWeekKey() {
    LocalDate now = LocalDate.now();
    int year = now.getYear();
    int weekOfYear = now.get(WeekFields.of(Locale.getDefault()).weekOfYear());
    return String.format("%dW%02d", year, weekOfYear);
  }

}
