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

import com.red.circle.other.app.convertor.user.RankingActivityConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.activity.RankingActivityRecordCO;
import com.red.circle.other.app.dto.clientobject.activity.RankingListCO;
import com.red.circle.other.app.dto.clientobject.activity.UserRankInfoCO;
import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.domain.ranking.RankingActivityType;
import com.red.circle.other.domain.ranking.RankingCycleType;
import com.red.circle.other.domain.ranking.RankingDimension;
import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivityRecord;
import com.red.circle.other.infra.database.mongo.entity.activity.WeekKingQueenCount;
import com.red.circle.other.infra.gateway.RankingActivityGateway;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.num.NumUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 查询排行榜命令执行器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RankingListQryExe {

    private final RankingActivityGateway rankingActivityGateway;
    private final RankingActivityConvertor convertor;
    private final UserProfileGateway userProfileGateway;
    private final UserProfileAppConvertor userProfileAppConvertor;

    public RankingListCO execute(RankingListQueryCmd cmd) {
        // 获取枚举
        RankingActivityType activityType = RankingActivityType.getByCode(cmd.getActivityType());
        RankingCycleType cycleType = cmd.getCycleType() != null ? RankingCycleType.getByCode(cmd.getCycleType()) : RankingCycleType.WEEKLY;

      // 查询排行榜列表
        List<RankingActivityRecord> records = rankingActivityGateway.getRankingList(
            cmd.getReqSysOrigin().getOrigin(),
            activityType,
            cycleType,
            cmd.getCycleKey(),
                null,
                cmd.getTopN()
        );

      Map<Long, UserProfileDTO> userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
          userProfileGateway
              .mapByUserIds(getUserIds(records)));

      // 转换为CO并设置排名
        List<RankingActivityRecordCO> rankingList = IntStream.range(0, records.size())
                .mapToObj(i -> {
                    RankingActivityRecord record = records.get(i);
                    RankingActivityRecordCO co = convertor.toRecordCO(record);
                    co.setRank(i + 1);  // 排名从1开始

                  UserProfileDTO userProfileDTO = userProfileMap.get(record.getUserId());
                  if (userProfileDTO != null) {
                    co.setAccount(userProfileDTO.getAccount());
                    co.setNickname(userProfileDTO.getUserNickname());
                    co.setAvatar(userProfileDTO.getUserAvatar());
                  }
                    return co;
                })
                .collect(Collectors.toList());

        // 查询当前用户排名（如果需要）
        UserRankInfoCO currentUserRank = null;
        if (cmd.getIncludeCurrentUser() && cmd.getReqUserId() != null) {
            currentUserRank = queryCurrentUserRank(cmd, rankingList);
            UserProfile userProfile = userProfileGateway.getByUserId(cmd.getReqUserId());
            if (userProfile != null) {
              currentUserRank.setAccount(userProfile.getAccount());
              currentUserRank.setNickname(userProfile.getUserNickname());
              currentUserRank.setAvatar(userProfile.getUserAvatar());
            }

        }

        // 构建返回结果
        RankingListCO result = new RankingListCO();
        result.setActivityType(activityType.getCode());
        result.setActivityTypeName(activityType.getName());
        result.setCycleType(cycleType.getCode());
        result.setCycleTypeName(cycleType.getName());
        result.setCycleKey(cmd.getCycleKey());
        result.setCycleDisplay(formatCycleDisplay(cycleType, cmd.getCycleKey()));
        
        // 设置维度信息（从第一条记录获取）
        if (!records.isEmpty()) {
            RankingDimension dimension = records.get(0).getDimension();
            if (dimension != null) {
                result.setDimension(dimension.getCode());
                result.setDimensionName(dimension.getName());
                result.setDimensionUnit(dimension.getUnit());
            }
        }
        
        result.setRankingList(rankingList);
        result.setCurrentUserRank(currentUserRank);
        result.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        return result;
    }

  /**
   * 从排行榜列表中查询当前用户排名
   */
  private UserRankInfoCO queryCurrentUserRank(
      RankingListQueryCmd cmd,
      List<RankingActivityRecordCO> rankingList) {

    UserRankInfoCO rankInfo = new UserRankInfoCO();
    rankInfo.setUserId(cmd.getReqUserId());

    // 从排行榜列表中查找当前用户
    Optional<RankingActivityRecordCO> userInList = rankingList.stream()
        .filter(record -> record.getUserId().equals(cmd.getReqUserId()))
        .findFirst();

    if (userInList.isPresent()) {
      // 用户在榜单中
      RankingActivityRecordCO userRecord = userInList.get();
      rankInfo.setRank(userRecord.getRank());
      rankInfo.setQuantity(userRecord.getQuantity());
      rankInfo.setIsRanked(true);
    } else {
      // 用户不在榜单中，显示为0
      rankInfo.setRank(0);
      rankInfo.setQuantity("0");
      rankInfo.setIsRanked(false);
    }

    Optional<RankingActivityRecord> userRecord = rankingActivityGateway.getUserRecord(
        cmd.getReqSysOrigin().getOrigin(),
        cmd.getReqUserId(),
        RankingActivityType.getByCode(cmd.getActivityType()),
        cmd.getCycleKey()
    );

    userRecord.ifPresent(rankingActivityRecord -> rankInfo.setQuantity(NumUtils.formatLong(rankingActivityRecord.getQuantity())));


    return rankInfo;
  }

  private Set<Long> getUserIds(List<RankingActivityRecord> weekStarGiftCounts) {

    return weekStarGiftCounts.stream().map(RankingActivityRecord::getUserId)
        .collect(Collectors.toSet());
  }

    /**
     * 查询当前用户排名
     */
    private UserRankInfoCO queryCurrentUserRank(
            RankingListQueryCmd cmd,
            RankingActivityType activityType,
            RankingCycleType cycleType) {
        
        Optional<RankingActivityRecord> userRecord = rankingActivityGateway.getUserRecord(
                cmd.getReqSysOrigin().getOrigin(),
                cmd.getReqUserId(),
                activityType,
                cmd.getCycleKey()
        );

        if (userRecord.isEmpty()) {
            // 用户未参与
            UserRankInfoCO rankInfo = new UserRankInfoCO();
            rankInfo.setUserId(cmd.getReqUserId());
            rankInfo.setRank(0);
            rankInfo.setQuantity("0");
            rankInfo.setIsRanked(false);
            return rankInfo;
        }

        RankingActivityRecord record = userRecord.get();
        
        // 计算排名
        Integer rank = rankingActivityGateway.calculateUserRank(
              cmd.getReqSysOrigin().getOrigin(),
                activityType,
                cycleType,
                cmd.getCycleKey(),
                null,
                record.getQuantity()
        );

        UserRankInfoCO rankInfo = new UserRankInfoCO();
        rankInfo.setUserId(record.getUserId());
        rankInfo.setRank(rank);
        rankInfo.setQuantity(NumUtils.formatLong(record.getQuantity()));
        rankInfo.setIsRanked(rank <= cmd.getTopN());
        
        return rankInfo;
    }

    /**
     * 格式化周期显示文本
     */
    private String formatCycleDisplay(RankingCycleType cycleType, String cycleKey) {
        if (cycleKey == null) {
            return "";
        }
        
        switch (cycleType) {
            case DAILY:
                // 20250101 -> 2025-01-01
                return cycleKey.substring(0, 4) + "-" + cycleKey.substring(4, 6) + "-" + cycleKey.substring(6, 8);
            case WEEKLY:
                // 20250101 -> 2025年第1周
                return cycleKey.substring(0, 4) + "年第" + getWeekOfYear(cycleKey) + "周";
            case MONTHLY:
                // 202501 -> 2025年1月
                return cycleKey.substring(0, 4) + "年" + Integer.parseInt(cycleKey.substring(4, 6)) + "月";
            default:
                return cycleKey;
        }
    }

    /**
     * 计算是一年中的第几周（简化实现）
     */
    private int getWeekOfYear(String cycleKey) {
        // TODO: 实现准确的周数计算
        return 1;
    }
}