package com.dora.util;

import com.dora.entity.RevenueConfig;
import com.dora.mapper.RevenueConfigMapper;
import com.dora.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 推广等级统一计算工具
 * 统一推广等级的计算逻辑，避免重复计算，提高系统性能
 * 
 * 设计原则：
 * 1. 仅在用户注册时更新推广等级
 * 2. 使用总粉丝数作为统一计算标准（不区分付费/非付费）
 * 3. 其他业务场景直接读取数据库中的promotion_level字段
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class PromotionLevelCalculator {

    private final RevenueConfigMapper revenueConfigMapper;
    private final UserMapper userMapper;

    /**
     * 根据总粉丝数计算推广等级（统一标准）
     * 
     * @param totalFansCount 总粉丝数（包括付费和非付费粉丝）
     * @return 推广等级
     */
    public int calculatePromotionLevelByTotalFans(int totalFansCount) {
        try {
            // 获取推广等级配置
            List<RevenueConfig> configs = revenueConfigMapper.selectByConfigType("promotion");
            if (configs == null || configs.isEmpty()) {
                log.warn("推广等级配置为空，返回默认等级1");
                return 1;
            }
            
            log.debug("计算推广等级 - totalFansCount: {}, 可用配置数量: {}", totalFansCount, configs.size());
            
            // 按粉丝数要求倒序排列，找到第一个满足条件的等级
            RevenueConfig matchedConfig = configs.stream()
                    .filter(config -> {
                        boolean matches = config.getMinFans() != null && totalFansCount >= config.getMinFans();
                        log.debug("等级配置检查 - level: {}, minFans: {}, totalFans: {}, 是否匹配: {}", 
                                config.getLevel(), config.getMinFans(), totalFansCount, matches);
                        return matches;
                    })
                    .sorted((a, b) -> Integer.compare(b.getMinFans(), a.getMinFans())) // 倒序排序，优先匹配高等级
                    .findFirst()
                    .orElse(null);
            
            int resultLevel = matchedConfig != null ? matchedConfig.getLevel() : 1;
            log.debug("推广等级计算结果 - totalFansCount: {}, resultLevel: {}", totalFansCount, resultLevel);
            
            return resultLevel;
            
        } catch (Exception e) {
            log.error("计算推广等级失败 - totalFansCount: {}", totalFansCount, e);
            return 1; // 异常时返回默认等级1
        }
    }

    /**
     * 更新用户推广等级（仅在注册时使用）
     * 
     * @param userId 用户ID
     * @return 是否更新成功
     */
    @Transactional
    public boolean updateUserPromotionLevelOnRegistration(Long userId) {
        try {
            if (userId == null) {
                log.warn("用户ID为空，无法更新推广等级");
                return false;
            }
            
            // 1. 统计用户当前总粉丝数
            int totalFansCount = userMapper.countFansByInviterId(userId);
            
            // 2. 计算新的推广等级
            int newLevel = calculatePromotionLevelByTotalFans(totalFansCount);
            
            // 3. 获取用户当前等级
            Integer currentLevel = getCurrentPromotionLevel(userId);
            
            // 4. 如果等级发生变化或当前等级为空，则更新
            if (currentLevel == null || currentLevel != newLevel) {
                int updateResult = userMapper.updatePromotionLevel(userId, newLevel);
                if (updateResult > 0) {
                    log.info("注册时更新用户推广等级成功 - userId: {}, level: {} -> {}, totalFans: {}", 
                            userId, currentLevel, newLevel, totalFansCount);
                    return true;
                } else {
                    log.error("注册时更新用户推广等级失败 - userId: {}, 数据库更新返回: {}", userId, updateResult);
                    return false;
                }
            } else {
                log.debug("用户推广等级无需更新 - userId: {}, level: {}, totalFans: {}", 
                        userId, currentLevel, totalFansCount);
                return true;
            }
            
        } catch (Exception e) {
            log.error("注册时更新用户推广等级异常 - userId: {}", userId, e);
            return false;
        }
    }

    /**
     * 批量更新多个用户的推广等级（仅在数据迁移时使用）
     * 
     * @param userIds 用户ID列表
     * @return 更新成功的用户数量
     */
    @Transactional
    public int batchUpdatePromotionLevelsOnMigration(List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return 0;
        }
        
        int successCount = 0;
        log.info("开始批量更新推广等级 - 用户数量: {}", userIds.size());
        
        for (Long userId : userIds) {
            try {
                // 直接在这里实现逻辑，避免调用本类的其他事务方法
                if (userId != null) {
                    int totalFansCount = userMapper.countFansByInviterId(userId);
                    int newLevel = calculatePromotionLevelByTotalFans(totalFansCount);
                    Integer currentLevel = getCurrentPromotionLevel(userId);
                    
                    if (currentLevel == null || currentLevel != newLevel) {
                        int updateResult = userMapper.updatePromotionLevel(userId, newLevel);
                        if (updateResult > 0) {
                            log.debug("批量更新推广等级成功 - userId: {}, level: {} -> {}, totalFans: {}", 
                                    userId, currentLevel, newLevel, totalFansCount);
                            successCount++;
                        }
                    } else {
                        successCount++; // 无需更新也算成功
                    }
                }
            } catch (Exception e) {
                log.error("批量更新推广等级失败 - userId: {}", userId, e);
                // 继续处理其他用户，不中断整个批量操作
            }
        }
        
        log.info("批量更新推广等级完成 - 成功: {}/{}", successCount, userIds.size());
        return successCount;
    }

    /**
     * 获取用户当前推广等级（直接从数据库读取）
     * 
     * @param userId 用户ID
     * @return 当前推广等级，用户不存在时返回null
     */
    public Integer getCurrentPromotionLevel(Long userId) {
        try {
            if (userId == null) {
                return null;
            }
            
            return userMapper.selectPromotionLevelById(userId);
            
        } catch (Exception e) {
            log.error("获取用户推广等级失败 - userId: {}", userId, e);
            return null;
        }
    }

    /**
     * 验证推广等级计算逻辑的工具方法（仅用于测试和调试）
     * 
     * @param userId 用户ID
     * @return 计算结果信息
     */
    public String validatePromotionLevelCalculation(Long userId) {
        try {
            int totalFans = userMapper.countFansByInviterId(userId);
            int calculatedLevel = calculatePromotionLevelByTotalFans(totalFans);
            Integer currentLevel = getCurrentPromotionLevel(userId);
            
            return String.format("用户%d: 总粉丝%d, 计算等级%d, 当前等级%s, 是否一致: %s", 
                    userId, totalFans, calculatedLevel, currentLevel, 
                    currentLevel != null && currentLevel == calculatedLevel);
                    
        } catch (Exception e) {
            return String.format("用户%d: 验证失败 - %s", userId, e.getMessage());
        }
    }
}
