package com.dora.service;

import com.dora.dto.FanListResponseDto;
import com.dora.dto.PromotionDto;
import com.dora.entity.PromotionLevelConfig;
import com.dora.entity.RevenueConfig;
import com.dora.entity.User;
import com.dora.mapper.RevenueConfigMapper;
import com.dora.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Random;

/**
 * 推广服务类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PromotionService {

    private final UserMapper userMapper;
    private final RevenueConfigMapper revenueConfigMapper;

    /**
     * 生成用户专属推广码
     *
     * @param userId 用户ID
     * @return 推广码
     */
    public String generateInviteCode(Long userId) {
        try {
            // 检查用户是否已有推广码
            User user = userMapper.selectById(userId);
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }

            // 如果已有推广码，直接返回
            if (user.getInviteCode() != null && !user.getInviteCode().isEmpty()) {
                return user.getInviteCode();
            }

            // 生成唯一推广码
            String inviteCode = generateUniqueInviteCode();
            
            // 更新用户推广码
            user.setInviteCode(inviteCode);
            userMapper.updateById(user);
            
            log.info("为用户 {} 生成推广码: {}", userId, inviteCode);
            return inviteCode;
            
        } catch (Exception e) {
            log.error("生成推广码失败 - userId: {}", userId, e);
            throw new RuntimeException("生成推广码失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户推广信息
     *
     * @param userId 用户ID
     * @return 推广信息
     */
    public PromotionDto getPromotionInfo(Long userId) {
        try {
            User user = userMapper.selectById(userId);
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }

            // 如果没有推广码，先生成
            if (user.getInviteCode() == null || user.getInviteCode().isEmpty()) {
                user.setInviteCode(generateInviteCode(userId));
            }

            // 获取粉丝统计
            int totalFansCount = userMapper.countFansByInviterId(userId);
            int paidFansCount = userMapper.countPaidFansByInviterId(userId);
            
            // 获取提成统计
            BigDecimal totalCommission = userMapper.getTotalCommissionByUserId(userId);
            if (totalCommission == null) {
                totalCommission = BigDecimal.ZERO;
            }

            // 获取当前提成比例（根据推广等级）
            BigDecimal commissionRate = getCommissionRateByLevel(user.getPromotionLevel());

            PromotionDto promotionDto = new PromotionDto();
            promotionDto.setInviteCode(user.getInviteCode());
            promotionDto.setPromotionLevel(user.getPromotionLevel());
            promotionDto.setLevelName(getLevelNameByLevel(user.getPromotionLevel()));
            promotionDto.setPaidFansCount(paidFansCount);
            promotionDto.setTotalFansCount(totalFansCount);
            promotionDto.setCommissionRate(commissionRate);
            promotionDto.setTotalCommission(totalCommission);
            promotionDto.setPoints(user.getPoints());
            promotionDto.setPointsExpiresAt(user.getPointsExpiresAt());
            promotionDto.setCreateTime(user.getCreateTime());

            return promotionDto;
            
        } catch (Exception e) {
            log.error("获取推广信息失败 - userId: {}", userId, e);
            throw new RuntimeException("获取推广信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户粉丝列表（包含统计信息）
     *
     * @param userId 用户ID
     * @param page 页码
     * @param size 每页大小
     * @param status 粉丝状态（paid-付费粉丝，gift-赠送会员，exchange-兑换会员，none-非VIP，all-所有粉丝）
     * @return 粉丝列表响应（包含统计信息）
     */
    public FanListResponseDto getFansListWithStats(Long userId, int page, int size, String status) {
        try {
            int offset = (page - 1) * size;
            
            // 获取粉丝列表
            List<com.dora.dto.FanDto> fans;
            if ("all".equals(status)) {
                // 获取所有粉丝
                fans = userMapper.selectFansByInviterId(userId, offset, size);
            } else if ("paid".equals(status)) {
                // 只获取付费粉丝（真正付费的，不包括赠送和兑换的）
                fans = userMapper.selectPaidFansByInviterId(userId, offset, size);
            } else {
                // 根据状态筛选粉丝
                fans = userMapper.selectFansByInviterIdAndStatus(userId, status, offset, size);
            }

            // 获取用户信息
            User user = userMapper.selectById(userId);
            if (user == null) {
                throw new RuntimeException("用户不存在");
            }

            // 根据当前筛选状态获取对应的总数
            int currentStatusCount;
            if ("all".equals(status)) {
                currentStatusCount = userMapper.countFansByInviterId(userId);
            } else if ("paid".equals(status)) {
                currentStatusCount = userMapper.countPaidFansByInviterId(userId);
            } else {
                currentStatusCount = userMapper.countFansByInviterIdAndStatus(userId, status);
            }

            // 获取总体统计信息（用于推广等级计算）
            int totalFansCount = userMapper.countFansByInviterId(userId);
            int paidFansCount = userMapper.countPaidFansByInviterId(userId);
            
            // 根据付费粉丝数量获取推广等级配置
            List<RevenueConfig> configs = revenueConfigMapper.selectByConfigType("promotion");
            
            // 按粉丝数要求倒序排列，找到第一个满足条件的等级
            RevenueConfig matchedConfig = configs.stream()
                    .filter(config -> config.getMinFans() != null && paidFansCount >= config.getMinFans())
                    .sorted((a, b) -> Integer.compare(b.getMinFans(), a.getMinFans())) // 倒序排序
                    .findFirst()
                    .orElse(null);
                    
            // 转换为 PromotionLevelConfig 以保持接口兼容
            PromotionLevelConfig levelConfig = matchedConfig != null ? convertToPromotionLevelConfig(matchedConfig) : null;
            
            // 构建响应对象
            FanListResponseDto response = new FanListResponseDto();
            response.setFans(fans);
            response.setTotalFansCount(currentStatusCount); // 使用当前筛选状态的数量
            response.setPaidFansCount(paidFansCount);
            response.setPage(page);
            response.setSize(size);
            
            // 计算总页数
            response.setTotalPages((int) Math.ceil((double) currentStatusCount / size));

            // 设置推广等级信息
            if (levelConfig != null) {
                response.setPromotionLevel(levelConfig.getId().intValue());
                response.setLevelName(levelConfig.getLevelName());
                response.setCommissionRate(levelConfig.getCommissionRate());
            } else {
                // 如果没有找到配置，使用默认值
                response.setPromotionLevel(0);
                response.setLevelName("Lv0");
                response.setCommissionRate(BigDecimal.ZERO);
            }

            return response;
            
        } catch (Exception e) {
            log.error("获取粉丝列表统计信息失败 - userId: {}, page: {}, size: {}, status: {}", userId, page, size, status, e);
            throw new RuntimeException("获取粉丝列表统计信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户粉丝列表
     *
     * @param userId 用户ID
     * @param page 页码
     * @param size 每页大小
     * @param status 粉丝状态（paid-付费粉丝，gift-赠送会员，exchange-兑换会员，none-非VIP，all-所有粉丝）
     * @return 粉丝列表
     */
    public List<com.dora.dto.FanDto> getFansList(Long userId, int page, int size, String status) {
        try {
            int offset = (page - 1) * size;
            
            List<com.dora.dto.FanDto> fans;
            if ("all".equals(status)) {
                // 获取所有粉丝
                fans = userMapper.selectFansByInviterId(userId, offset, size);
            } else if ("paid".equals(status)) {
                // 只获取付费粉丝（真正付费的，不包括赠送和兑换的）
                fans = userMapper.selectPaidFansByInviterId(userId, offset, size);
            } else {
                // 根据状态筛选粉丝
                fans = userMapper.selectFansByInviterIdAndStatus(userId, status, offset, size);
            }

            return fans;
            
        } catch (Exception e) {
            log.error("获取粉丝列表失败 - userId: {}, page: {}, size: {}, status: {}", userId, page, size, status, e);
            throw new RuntimeException("获取粉丝列表失败: " + e.getMessage());
        }
    }

    /**
     * 验证推广码是否有效
     *
     * @param inviteCode 推广码
     * @return 是否有效
     */
    public boolean validateInviteCode(String inviteCode) {
        try {
            return userMapper.selectByInviteCode(inviteCode) != null;
        } catch (Exception e) {
            log.error("验证推广码失败 - inviteCode: {}", inviteCode, e);
            return false;
        }
    }

    /**
     * 根据推广码获取用户ID
     *
     * @param inviteCode 推广码
     * @return 用户ID
     */
    public Long getUserIdByInviteCode(String inviteCode) {
        try {
            User user = userMapper.selectByInviteCode(inviteCode);
            return user != null ? user.getId() : null;
        } catch (Exception e) {
            log.error("根据推广码获取用户ID失败 - inviteCode: {}", inviteCode, e);
            return null;
        }
    }

    /**
     * 生成唯一推广码
     *
     * @return 推广码
     */
    private String generateUniqueInviteCode() {
        Random random = new Random();
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder();
        
        // 生成8位推广码
        for (int i = 0; i < 8; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        
        String inviteCode = sb.toString();
        
        // 检查是否已存在，如果存在则重新生成
        while (userMapper.selectByInviteCode(inviteCode) != null) {
            sb = new StringBuilder();
            for (int i = 0; i < 8; i++) {
                sb.append(chars.charAt(random.nextInt(chars.length())));
            }
            inviteCode = sb.toString();
        }
        
        return inviteCode;
    }

    /**
     * 根据推广等级获取等级名称
     *
     * @param level 推广等级
     * @return 等级名称
     */
    private String getLevelNameByLevel(Integer level) {
        if (level == null) {
            return "Lv0";
        }
        switch (level) {
            case 1: return "Lv1";
            case 2: return "Lv2";
            case 3: return "Lv3";
            case 4: return "Lv4";
            case 5: return "Lv5";
            default: return "Lv" + level;
        }
    }

    /**
     * 根据推广等级获取提成比例
     *
     * @param level 推广等级
     * @return 提成比例
     */
    private BigDecimal getCommissionRateByLevel(Integer level) {
        if (level == null || level == 0) {
            return BigDecimal.ZERO;
        }
        
        // 这里可以根据实际业务需求配置不同等级的提成比例
        switch (level) {
            case 1: return new BigDecimal("0.05"); // 5%
            case 2: return new BigDecimal("0.08"); // 8%
            case 3: return new BigDecimal("0.12"); // 12%
            case 4: return new BigDecimal("0.15"); // 15%
            case 5: return new BigDecimal("0.20"); // 20%
            default: return new BigDecimal("0.05"); // 默认5%
        }
    }
    
    /**
     * 将 RevenueConfig 转换为 PromotionLevelConfig 以保持接口兼容性
     */
    private PromotionLevelConfig convertToPromotionLevelConfig(RevenueConfig revenueConfig) {
        PromotionLevelConfig config = new PromotionLevelConfig();
        config.setId(revenueConfig.getLevel() != null ? Long.valueOf(revenueConfig.getLevel()) : null);
        config.setLevelName(revenueConfig.getLevelName());
        config.setMinPaidFans(revenueConfig.getMinFans());
        config.setCommissionRate(revenueConfig.getCommissionRate());
        config.setCreateTime(revenueConfig.getCreateTime());
        config.setUpdateTime(revenueConfig.getUpdateTime());
        config.setIsDeleted(revenueConfig.getIsDeleted());
        return config;
    }
} 