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

import com.red.circle.other.app.dto.clientobject.activity.UserRankInfoCO;
import com.red.circle.other.app.dto.cmd.UserRankQueryCmd;
import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivityRecord;
import com.red.circle.other.infra.gateway.RankingActivityGateway;
import com.red.circle.other.domain.ranking.RankingActivityType;
import com.red.circle.other.domain.ranking.RankingCycleType;
import com.red.circle.tool.core.num.NumUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Optional;

/**
 * 查询用户排名命令执行器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class UserRankQryExe {

    private final RankingActivityGateway rankingActivityGateway;

    public UserRankInfoCO execute(UserRankQueryCmd cmd) {
        // 获取枚举
        RankingActivityType activityType = RankingActivityType.getByCode(cmd.getActivityType());
        RankingCycleType cycleType = RankingCycleType.getByCode(cmd.getCycleType());

        Long queryUserId = cmd.getUserId() != null ? cmd.getUserId() : cmd.getReqUserId();

        // 查询用户记录
        Optional<RankingActivityRecord> userRecord = rankingActivityGateway.getUserRecord(
            cmd.getReqSysOrigin().getOrigin(),
                queryUserId,
                activityType,
                cmd.getCycleKey()
        );

        UserRankInfoCO rankInfo = new UserRankInfoCO();
        rankInfo.setUserId(queryUserId);

        if (userRecord.isEmpty()) {
            // 用户未参与
            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()
        );

        rankInfo.setRank(rank);
        rankInfo.setQuantity(NumUtils.formatLong(record.getQuantity()));
        rankInfo.setIsRanked(rank > 0);

        return rankInfo;
    }
}