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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.other.app.dto.clientobject.activity.ValidInviteUserCO;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.rds.dao.user.user.InviteUserRechargeCommissionDAO;
import com.red.circle.other.infra.database.rds.dao.user.user.UserInviteUserDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.InviteUserRechargeCommission;
import com.red.circle.other.infra.database.rds.entity.user.user.UserInviteUser;
import com.red.circle.other.infra.enums.user.InviteTypeEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 获取有效邀请用户列表执行器
 * 
 * 表结构说明：
 * user_invite_user: userId(邀请人), inviteUserId(被邀请人)
 * user_invite_user_recharge_commission: userId(被邀请人-充值人), inviteUserId(邀请人-获得佣金人)
 *
 * @author system
 * @date 2025-01-22
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class GetValidInviteUsersExe {

    private final UserInviteUserDAO userInviteUserDAO;
    private final InviteUserRechargeCommissionDAO inviteUserRechargeCommissionDAO;
    private final UserProfileGateway userProfileGateway;

    // 邀请关系有效期（天数）
    private static final int VALID_DAYS = 30;

    /**
     * 执行获取有效邀请用户列表
     *
     * @param cmd 命令
     * @return 有效邀请用户列表
     */
    public List<ValidInviteUserCO> execute(AppExtCommand cmd) {
        Long inviterUserId = cmd.getReqUserId(); // 邀请人ID

        // 查询当前用户邀请的所有用户（userId=邀请人）
        List<UserInviteUser> allInvites = userInviteUserDAO.selectList(
                new LambdaQueryWrapper<UserInviteUser>()
                        .eq(UserInviteUser::getUserId, inviterUserId) // userId是邀请人
                        .orderByDesc(UserInviteUser::getCreateTime)
        );

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

        // 筛选有效邀请
        List<UserInviteUser> validInvites = allInvites.stream()
//                .filter(this::isValidInvite)
                .collect(Collectors.toList());

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

        // 获取被邀请用户ID列表（inviteUserId）
        List<Long> invitedUserIds = validInvites.stream()
                .map(UserInviteUser::getInviteUserId) // inviteUserId是被邀请人
                .collect(Collectors.toList());

        // 批量查询用户信息
        Map<Long, UserProfile> userProfileMap = userProfileGateway.mapByUserIds(new HashSet<>(invitedUserIds));

        // 批量查询佣金信息（inviteUserId=邀请人，userId=被邀请人）
        List<InviteUserRechargeCommission> commissions = inviteUserRechargeCommissionDAO.selectList(
                new LambdaQueryWrapper<InviteUserRechargeCommission>()
                        .eq(InviteUserRechargeCommission::getUserId, inviterUserId) // 邀请人
                        .in(InviteUserRechargeCommission::getInviteUserId, invitedUserIds) // 被邀请人
        );

        Map<Long, BigDecimal> commissionMap = commissions.stream()
                .collect(Collectors.groupingBy(
                        InviteUserRechargeCommission::getInviteUserId, // 被邀请人ID
                        Collectors.reducing(BigDecimal.ZERO, 
                                InviteUserRechargeCommission::getCommission, 
                                BigDecimal::add)
                ));

        // 组装返回数据
        List<ValidInviteUserCO> result = new ArrayList<>();
        for (UserInviteUser invite : validInvites) {
            ValidInviteUserCO userCO = buildValidInviteUserCO(invite, userProfileMap, commissionMap);
            result.add(userCO);
        }

        log.info("有效邀请用户列表, inviterUserId={}, validCount={}", inviterUserId, result.size());
        return result;
    }

    /**
     * 判断是否为有效邀请
     */
    private boolean isValidInvite(UserInviteUser invite) {
        String inviteType = invite.getInviteType();
        
        // LOTTERY类型直接算有效
        if (InviteTypeEnum.LOTTERY.getCode().equals(inviteType)) {
            return true;
        }
        
        // REGISTER类型需要检查充值记录
        if (InviteTypeEnum.REGISTER.getCode().equals(inviteType)) {
            // userId=邀请人, inviteUserId=被邀请人
            return hasValidRecharge(invite.getInviteUserId(), invite.getUserId());
        }
        
        return false;
    }

    /**
     * 检查是否有有效充值记录（commission > 0）
     * @param invitedUserId 被邀请人ID（充值的人）
     * @param inviterUserId 邀请人ID（获得佣金的人）
     */
    private boolean hasValidRecharge(Long invitedUserId, Long inviterUserId) {
        long count = inviteUserRechargeCommissionDAO.selectCount(
                new LambdaQueryWrapper<InviteUserRechargeCommission>()
                        .eq(InviteUserRechargeCommission::getUserId, invitedUserId) // 被邀请人
                        .eq(InviteUserRechargeCommission::getInviteUserId, inviterUserId) // 邀请人
                        .gt(InviteUserRechargeCommission::getCommission, BigDecimal.ZERO)
        );
        return count > 0;
    }

    /**
     * 构建有效邀请用户CO
     */
    private ValidInviteUserCO buildValidInviteUserCO(
            UserInviteUser invite, 
            Map<Long, UserProfile> userProfileMap,
            Map<Long, BigDecimal> commissionMap) {
        
        Long invitedUserId = invite.getInviteUserId(); // 被邀请人ID
        
        ValidInviteUserCO userCO = new ValidInviteUserCO();
        userCO.setInvitedUserId(invitedUserId);
        userCO.setInviteType(invite.getInviteType());
        userCO.setInviteTime(invite.getCreateTime());

        // 设置用户账号
        UserProfile userProfile = userProfileMap.get(invitedUserId);
        if (userProfile != null) {
            userCO.setInvitedUserAccount(userProfile.getAccount());
        }

        // 计算剩余天数
        LocalDateTime inviteTime = invite.getCreateTime().toLocalDateTime();
        LocalDateTime expireTime = inviteTime.plusDays(VALID_DAYS);
        long remainingDays = ChronoUnit.DAYS.between(LocalDateTime.now(), expireTime);
        userCO.setRemainingDays(Math.max(0, (int) remainingDays));

        // 设置提供的收益
        BigDecimal income = commissionMap.getOrDefault(invitedUserId, BigDecimal.ZERO);
        userCO.setProvideIncome(income);

        return userCO;
    }
}
