package com.dora.service.impl;

import com.dora.dto.UserBalanceDto;
import com.dora.dto.WithdrawDto;
import com.dora.entity.UserBalance;
import com.dora.entity.UserBalanceLog;
import com.dora.entity.Workflow;
import com.dora.entity.Video;
import com.dora.mapper.FanPromotionCommissionMapper;
import com.dora.mapper.UserBalanceLogMapper;
import com.dora.mapper.UserBalanceMapper;
import com.dora.mapper.WithdrawRequestMapper;
import com.dora.mapper.WorkflowMapper;
import com.dora.mapper.VideoMapper;
import com.dora.service.UserBalanceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户余额服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserBalanceServiceImpl implements UserBalanceService {

    private final UserBalanceMapper userBalanceMapper;
    private final UserBalanceLogMapper userBalanceLogMapper;
    private final WithdrawRequestMapper withdrawRequestMapper;
    private final WorkflowMapper workflowMapper;
    private final VideoMapper videoMapper;
    private final FanPromotionCommissionMapper fanPromotionCommissionMapper;

    @Override
    public UserBalance getUserBalance(Long userId) {
        UserBalance userBalance = userBalanceMapper.selectByUserId(userId);
        if (userBalance == null) {
            // 如果用户余额记录不存在，创建一条初始记录
            userBalance = new UserBalance();
            userBalance.setUserId(userId);
            userBalance.setBalance(BigDecimal.ZERO);
            userBalance.setTotalIncome(BigDecimal.ZERO);
            userBalance.setTotalWithdrawn(BigDecimal.ZERO);
            userBalance.setFrozenAmount(BigDecimal.ZERO);
            userBalance.setLastUpdatedAt(LocalDateTime.now());
            userBalance.setCreateTime(LocalDateTime.now());
            userBalance.setUpdateTime(LocalDateTime.now());
            userBalance.setIsDeleted(0);
            
            userBalanceMapper.insert(userBalance);
        }
        return userBalance;
    }

    @Override
    @Transactional
    public void increaseBalance(Long userId, BigDecimal amount, String sourceType, Long sourceId, String description) {
        UserBalance userBalance = getUserBalance(userId);
        
        BigDecimal balanceBefore = userBalance.getBalance();
        BigDecimal balanceAfter = balanceBefore.add(amount);
        BigDecimal totalIncome = userBalance.getTotalIncome().add(amount);
        
        // 更新余额
        userBalanceMapper.increaseBalance(userId, amount, amount);
        
        // 记录变动日志
        UserBalanceLog balanceLog = new UserBalanceLog();
        balanceLog.setUserId(userId);
        balanceLog.setChangeType("income");
        balanceLog.setChangeAmount(amount);
        balanceLog.setBalanceBefore(balanceBefore);
        balanceLog.setBalanceAfter(balanceAfter);
        balanceLog.setSourceType(sourceType);
        balanceLog.setSourceId(sourceId);
        balanceLog.setDescription(description);
        balanceLog.setCreateTime(LocalDateTime.now());
        balanceLog.setIsDeleted(0);
        
        userBalanceLogMapper.insert(balanceLog);
        
        log.info("用户{}余额增加{}元，来源：{}，描述：{}", userId, amount, sourceType, description);
    }

    @Override
    @Transactional
    public void decreaseBalance(Long userId, BigDecimal amount, String sourceType, Long sourceId, String description) {
        UserBalance userBalance = getUserBalance(userId);
        
        BigDecimal balanceBefore = userBalance.getBalance();
        BigDecimal balanceAfter = balanceBefore.subtract(amount);
        BigDecimal totalWithdrawn = userBalance.getTotalWithdrawn().add(amount);
        
        // 更新余额
        userBalanceMapper.decreaseBalance(userId, amount, amount);
        
        // 记录变动日志
        UserBalanceLog balanceLog = new UserBalanceLog();
        balanceLog.setUserId(userId);
        balanceLog.setChangeType("withdraw");
        balanceLog.setChangeAmount(amount.negate());
        balanceLog.setBalanceBefore(balanceBefore);
        balanceLog.setBalanceAfter(balanceAfter);
        balanceLog.setSourceType(sourceType);
        balanceLog.setSourceId(sourceId);
        balanceLog.setDescription(description);
        balanceLog.setCreateTime(LocalDateTime.now());
        balanceLog.setIsDeleted(0);
        
        userBalanceLogMapper.insert(balanceLog);
        
        log.info("用户{}余额减少{}元，来源：{}，描述：{}", userId, amount, sourceType, description);
    }

    @Override
    @Transactional
    public void freezeBalance(Long userId, BigDecimal amount, String sourceType, Long sourceId, String description) {
        UserBalance userBalance = getUserBalance(userId);
        
        BigDecimal balanceBefore = userBalance.getBalance();
        BigDecimal balanceAfter = balanceBefore; // 冻结时不改变余额
        
        // 冻结余额
        userBalanceMapper.freezeBalance(userId, amount);
        
        // 记录变动日志
        UserBalanceLog balanceLog = new UserBalanceLog();
        balanceLog.setUserId(userId);
        balanceLog.setChangeType("freeze");
        balanceLog.setChangeAmount(amount.negate());
        balanceLog.setBalanceBefore(balanceBefore);
        balanceLog.setBalanceAfter(balanceAfter);
        balanceLog.setSourceType(sourceType);
        balanceLog.setSourceId(sourceId);
        balanceLog.setDescription(description);
        balanceLog.setCreateTime(LocalDateTime.now());
        balanceLog.setIsDeleted(0);
        
        userBalanceLogMapper.insert(balanceLog);
        
        log.info("用户{}余额冻结{}元，来源：{}，描述：{}", userId, amount, sourceType, description);
    }

    @Override
    @Transactional
    public void unfreezeBalance(Long userId, BigDecimal amount, String sourceType, Long sourceId, String description) {
        UserBalance userBalance = getUserBalance(userId);
        
        BigDecimal balanceBefore = userBalance.getBalance();
        BigDecimal balanceAfter = balanceBefore; // 解冻时余额不变，只是冻结金额减少
        
        // 解冻余额
        userBalanceMapper.unfreezeBalance(userId, amount);
        
        // 记录变动日志
        UserBalanceLog balanceLog = new UserBalanceLog();
        balanceLog.setUserId(userId);
        balanceLog.setChangeType("unfreeze");
        balanceLog.setChangeAmount(amount);
        balanceLog.setBalanceBefore(balanceBefore);
        balanceLog.setBalanceAfter(balanceAfter);
        balanceLog.setSourceType(sourceType);
        balanceLog.setSourceId(sourceId);
        balanceLog.setDescription(description);
        balanceLog.setCreateTime(LocalDateTime.now());
        balanceLog.setIsDeleted(0);
        
        userBalanceLogMapper.insert(balanceLog);
        
        log.info("用户{}余额解冻{}元，来源：{}，描述：{}", userId, amount, sourceType, description);
    }

    @Override
    public List<UserBalanceLog> getBalanceLogs(Long userId, int page, int size) {
        int offset = (page - 1) * size;
        return userBalanceLogMapper.selectByUserId(userId, offset, size);
    }

    @Override
    public Long getBalanceLogsCount(Long userId) {
        return userBalanceLogMapper.countByUserId(userId);
    }

    @Override
    public boolean validateWithdrawCondition(Long userId, BigDecimal amount) {
        UserBalance userBalance = getUserBalance(userId);
        
        // 计算可用余额 = 总余额 - 冻结金额
        BigDecimal availableBalance = userBalance.getBalance().subtract(userBalance.getFrozenAmount());
        
        // 检查可用余额是否足够
        if (availableBalance.compareTo(amount) < 0) {
            return false;
        }
        
        // 检查提现金额是否达到最小要求（100元）
        if (amount.compareTo(new BigDecimal("100")) < 0) {
            return false;
        }
        
        return true;
    }

    @Override
    @Transactional
    public WithdrawDto.WithdrawResponse submitWithdrawRequest(Long userId, WithdrawDto.WithdrawRequest request) {
        // 1. 验证提现条件
        if (!validateWithdrawCondition(userId, request.getAmount())) {
            throw new RuntimeException("不满足提现条件，余额不足或金额少于100元");
        }

        // 2. 验证银行卡信息
        if ("bank".equals(request.getAccountType()) && !StringUtils.hasText(request.getBankName())) {
            throw new RuntimeException("银行卡提现必须提供开户行名称");
        }

        // 3. 冻结余额
        freezeBalance(userId, request.getAmount(), "withdraw", null, "提现申请冻结");

        // 4. 创建提现申请
        com.dora.entity.WithdrawRequest withdrawRequest = new com.dora.entity.WithdrawRequest();
        withdrawRequest.setUserId(userId);
        withdrawRequest.setAmount(request.getAmount());
        withdrawRequest.setWithdrawType("balance"); // 统一使用balance类型
        withdrawRequest.setContentId(null); // 余额提现不需要作品ID
        withdrawRequest.setAccountType(request.getAccountType());
        withdrawRequest.setAccount(request.getAccount());
        withdrawRequest.setAccountName(request.getAccountName());
        withdrawRequest.setBankName(request.getBankName());
        withdrawRequest.setBankBranch(request.getBankBranch());
        withdrawRequest.setStatus(0); // 待审核
        withdrawRequest.setCreateTime(LocalDateTime.now());
        withdrawRequest.setUpdateTime(LocalDateTime.now());
        withdrawRequest.setIsDeleted(0);

        // 5. 保存到数据库
        withdrawRequestMapper.insert(withdrawRequest);

        // 6. 返回响应
        return convertToResponse(withdrawRequest);
    }

    /**
     * 转换为响应对象
     */
    private WithdrawDto.WithdrawResponse convertToResponse(com.dora.entity.WithdrawRequest withdrawRequest) {
        WithdrawDto.WithdrawResponse response = new WithdrawDto.WithdrawResponse();
        response.setId(withdrawRequest.getId());
        response.setAmount(withdrawRequest.getAmount());
        response.setAccountType(withdrawRequest.getAccountType());
        response.setAccount(withdrawRequest.getAccount());
        response.setAccountName(withdrawRequest.getAccountName());
        response.setBankName(withdrawRequest.getBankName());
        response.setBankBranch(withdrawRequest.getBankBranch());
        response.setStatus(withdrawRequest.getStatus());
        response.setReason(withdrawRequest.getReason());
        response.setTransactionNo(withdrawRequest.getTransactionNo());
        response.setFeeAmount(withdrawRequest.getFeeAmount());
        response.setActualAmount(withdrawRequest.getActualAmount());
        response.setProcessedAt(withdrawRequest.getProcessedAt());
        response.setCreateTime(withdrawRequest.getCreateTime());
        response.setReviewedAt(withdrawRequest.getReviewedAt());
        return response;
    }

    @Override
    public UserBalanceDto.UserBalanceResponse getUserBalanceInfo(Long userId) {
        UserBalance userBalance = getUserBalance(userId);
        
        // 计算昨日收益
        BigDecimal yesterdayIncome = calculateYesterdayIncome(userId);
        
        // 计算可用余额，确保不会出现负数
        BigDecimal availableBalance = userBalance.getBalance().subtract(userBalance.getFrozenAmount());
        if (availableBalance.compareTo(BigDecimal.ZERO) < 0) {
            availableBalance = BigDecimal.ZERO;
        }
        
        UserBalanceDto.UserBalanceResponse response = new UserBalanceDto.UserBalanceResponse();
        response.setBalance(userBalance.getBalance());
        response.setTotalIncome(userBalance.getTotalIncome());
        response.setTotalWithdrawn(userBalance.getTotalWithdrawn());
        response.setFrozenAmount(userBalance.getFrozenAmount());
        response.setAvailableBalance(availableBalance);
        response.setYesterdayIncome(yesterdayIncome);
        response.setLastUpdatedAt(userBalance.getLastUpdatedAt());
        
        return response;
    }

    /**
     * 计算昨日收益
     */
    private BigDecimal calculateYesterdayIncome(Long userId) {
        // 获取昨天的开始和结束时间
        LocalDateTime yesterdayStart = LocalDateTime.now().minusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime yesterdayEnd = yesterdayStart.plusDays(1).minusNanos(1);
        
        // 从余额变动记录中统计昨天的收入
        List<UserBalanceLog> yesterdayLogs = userBalanceLogMapper.selectByUserIdAndTimeRange(userId, yesterdayStart, yesterdayEnd);
        return yesterdayLogs.stream()
                .filter(log -> "income".equals(log.getChangeType()))
                .map(UserBalanceLog::getChangeAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    @Override
    public UserBalanceDto.BalanceLogResponse getUserBalanceLogs(Long userId, int page, int size, String changeType) {
        int offset = (page - 1) * size;
        
        List<UserBalanceLog> logs;
        Long total;
        
        if (changeType != null && !changeType.trim().isEmpty()) {
            logs = userBalanceLogMapper.selectByUserIdAndChangeType(userId, changeType, offset, size);
            total = userBalanceLogMapper.countByUserIdAndChangeType(userId, changeType);
        } else {
            logs = userBalanceLogMapper.selectByUserId(userId, offset, size);
            total = userBalanceLogMapper.countByUserId(userId);
        }
        
        // 转换为DTO
        List<UserBalanceDto.BalanceLogItem> items = logs.stream()
                .map(this::convertToBalanceLogItem)
                .toList();
        
        UserBalanceDto.BalanceLogResponse response = new UserBalanceDto.BalanceLogResponse();
        response.setRecords(items);
        response.setTotal(total);
        response.setPage(page);
        response.setSize(size);
        
        return response;
    }

    @Override
    public UserBalanceDto.UserBalanceResponse getUserBalanceStats(Long userId) {
        // 统计信息与余额信息相同，直接调用余额信息接口
        return getUserBalanceInfo(userId);
    }

    @Override
    public UserBalanceDto.IncomeDetailResponse getUserIncomeDetail(Long userId) {
        // 获取推广收益
        BigDecimal promotionIncome = getPromotionIncome(userId);
        
        // 获取推广收益明细
        List<UserBalanceDto.PromotionIncomeItem> promotionIncomes = getPromotionIncomeDetails(userId);
        
        // 获取内容收益
        List<UserBalanceDto.ContentIncomeItem> contentIncomes = getContentIncomes(userId);
        
        // 计算总收益
        BigDecimal totalContentIncome = contentIncomes.stream()
                .map(UserBalanceDto.ContentIncomeItem::getIncomeAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalIncome = promotionIncome.add(totalContentIncome);
        
        UserBalanceDto.IncomeDetailResponse response = new UserBalanceDto.IncomeDetailResponse();
        response.setPromotionIncome(promotionIncome);
        response.setPromotionIncomes(promotionIncomes);
        response.setContentIncomes(contentIncomes);
        response.setTotalIncome(totalIncome);
        
        return response;
    }

    /**
     * 获取推广收益
     */
    private BigDecimal getPromotionIncome(Long userId) {
        // 从余额变动记录中统计推广收益
        List<UserBalanceLog> promotionLogs = userBalanceLogMapper.selectByUserIdAndChangeType(userId, "income", 0, 1000);
        return promotionLogs.stream()
                .filter(log -> "promotion".equals(log.getSourceType()) || "promotion_commission".equals(log.getSourceType()))
                .map(UserBalanceLog::getChangeAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 获取推广收益明细
     */
    private List<UserBalanceDto.PromotionIncomeItem> getPromotionIncomeDetails(Long userId) {
        try {
            // 从推广分成表直接查询详细信息
            List<UserBalanceDto.PromotionIncomeItem> promotionIncomes = 
                    fanPromotionCommissionMapper.selectPromotionIncomeDetailsByPromoterId(userId);
            
            log.debug("获取用户{}的推广收益明细，共{}条记录", userId, promotionIncomes.size());
            
            return promotionIncomes;
        } catch (Exception e) {
            log.error("获取用户{}推广收益明细失败", userId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取内容收益
     */
    private List<UserBalanceDto.ContentIncomeItem> getContentIncomes(Long userId) {
        List<UserBalanceDto.ContentIncomeItem> items = new ArrayList<>();
        
        // 获取所有收入记录
        List<UserBalanceLog> incomeLogs = userBalanceLogMapper.selectByUserIdAndChangeType(userId, "income", 0, 1000);
        
        // 按内容类型和ID分组统计收益
        Map<String, Map<Long, List<UserBalanceLog>>> groupedLogs = incomeLogs.stream()
                .filter(log -> "workflow".equals(log.getSourceType()) || "video".equals(log.getSourceType()))
                .collect(Collectors.groupingBy(
                    UserBalanceLog::getSourceType,
                    Collectors.groupingBy(UserBalanceLog::getSourceId)
                ));
        
        // 处理工作流收益
        if (groupedLogs.containsKey("workflow")) {
            Map<Long, List<UserBalanceLog>> workflowLogs = groupedLogs.get("workflow");
            List<Long> workflowIds = new ArrayList<>(workflowLogs.keySet());
            
            if (!workflowIds.isEmpty()) {
                // 批量查询工作流信息
                List<Workflow> workflows = workflowMapper.selectByIds(workflowIds);
                Map<Long, Workflow> workflowMap = workflows.stream()
                        .collect(Collectors.toMap(Workflow::getId, workflow -> workflow));
                
                for (Map.Entry<Long, List<UserBalanceLog>> entry : workflowLogs.entrySet()) {
                    Long workflowId = entry.getKey();
                    List<UserBalanceLog> logs = entry.getValue();
                    
                    // 计算总收益
                    BigDecimal totalIncome = logs.stream()
                            .map(UserBalanceLog::getChangeAmount)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    
                    // 获取最新收益时间
                    LocalDateTime latestTime = logs.stream()
                            .map(UserBalanceLog::getCreateTime)
                            .max(LocalDateTime::compareTo)
                            .orElse(LocalDateTime.now());
                    
                    UserBalanceDto.ContentIncomeItem item = new UserBalanceDto.ContentIncomeItem();
                    item.setContentType("workflow");
                    item.setContentTypeName("工作流");
                    item.setContentId(workflowId);
                    
                    // 获取真实的工作流名称
                    Workflow workflow = workflowMap.get(workflowId);
                    String workflowName;
                    if (workflow != null) {
                        workflowName = workflow.getName();
                        item.setContentName(workflowName);
                    } else {
                        // 工作流已被删除，尝试从原始描述中提取名称
                        workflowName = extractWorkflowNameFromDescription(logs);
                        if (workflowName == null) {
                            workflowName = "已删除的工作流" + workflowId;
                        }
                        item.setContentName(workflowName);
                    }
                    
                    item.setIncomeAmount(totalIncome);
                    item.setIncomeTime(latestTime);
                    
                    // 生成工作流收益描述
                    int userCount = logs.size(); // 简化统计，实际应该统计唯一用户数
                    item.setDescription(String.format("【工作流收益】%s 获得用户使用奖励 - 累计%d次收益，共计%.2f元", 
                            workflowName, userCount, totalIncome));
                    
                    items.add(item);
                }
            }
        }
        
        // 处理视频收益
        if (groupedLogs.containsKey("video")) {
            Map<Long, List<UserBalanceLog>> videoLogs = groupedLogs.get("video");
            List<Long> videoIds = new ArrayList<>(videoLogs.keySet());
            
            if (!videoIds.isEmpty()) {
                // 批量查询视频信息
                List<Video> videos = videoMapper.selectByIds(videoIds);
                Map<Long, Video> videoMap = videos.stream()
                        .collect(Collectors.toMap(Video::getId, video -> video));
                
                for (Map.Entry<Long, List<UserBalanceLog>> entry : videoLogs.entrySet()) {
                    Long videoId = entry.getKey();
                    List<UserBalanceLog> logs = entry.getValue();
                    
                    // 计算总收益
                    BigDecimal totalIncome = logs.stream()
                            .map(UserBalanceLog::getChangeAmount)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    
                    // 获取最新收益时间
                    LocalDateTime latestTime = logs.stream()
                            .map(UserBalanceLog::getCreateTime)
                            .max(LocalDateTime::compareTo)
                            .orElse(LocalDateTime.now());
                    
                    UserBalanceDto.ContentIncomeItem item = new UserBalanceDto.ContentIncomeItem();
                    item.setContentType("video");
                    item.setContentTypeName("视频");
                    item.setContentId(videoId);
                    
                    // 获取真实的视频标题
                    Video video = videoMap.get(videoId);
                    String videoTitle;
                    if (video != null) {
                        videoTitle = video.getTitle();
                        item.setContentName(videoTitle);
                    } else {
                        // 视频已被删除，尝试从原始描述中提取名称
                        videoTitle = extractVideoTitleFromDescription(logs);
                        if (videoTitle == null) {
                            videoTitle = "已删除的视频" + videoId;
                        }
                        item.setContentName(videoTitle);
                    }
                    
                    item.setIncomeAmount(totalIncome);
                    item.setIncomeTime(latestTime);
                    
                    // 生成视频收益描述
                    int achievementCount = logs.size(); // 达到的阶段数
                    item.setDescription(String.format("【视频收益】%s 达到收益阶段奖励 - 累计%d个阶段，共计%.2f元", 
                            videoTitle, achievementCount, totalIncome));
                    
                    items.add(item);
                }
            }
        }
        
        return items;
    }

    /**
     * 转换余额变动记录为DTO
     */
    private UserBalanceDto.BalanceLogItem convertToBalanceLogItem(UserBalanceLog log) {
        UserBalanceDto.BalanceLogItem item = new UserBalanceDto.BalanceLogItem();
        item.setId(log.getId());
        item.setChangeType(log.getChangeType());
        item.setChangeTypeName(UserBalanceDto.ChangeType.getChangeTypeName(log.getChangeType()));
        item.setChangeAmount(log.getChangeAmount());
        item.setBalanceBefore(log.getBalanceBefore());
        item.setBalanceAfter(log.getBalanceAfter());
        item.setSourceType(log.getSourceType());
        item.setSourceTypeName(UserBalanceDto.SourceType.getSourceTypeName(log.getSourceType()));
        item.setSourceId(log.getSourceId());
        item.setDescription(log.getDescription());
        item.setCreateTime(log.getCreateTime());
        return item;
    }

    /**
     * 从用户余额记录的原始描述中提取工作流名称
     * @param logs 余额记录列表
     * @return 工作流名称，如果提取失败返回null
     */
    private String extractWorkflowNameFromDescription(List<UserBalanceLog> logs) {
        if (logs == null || logs.isEmpty()) {
            return null;
        }
        
        // 获取第一条记录的描述（包含原始工作流名称）
        String description = logs.get(0).getDescription();
        if (description == null || !description.contains("【工作流收益】")) {
            return null;
        }
        
        try {
            // 提取模式：【工作流收益】工作流名称 获得...
            String pattern = "【工作流收益】";
            int startIndex = description.indexOf(pattern);
            if (startIndex == -1) {
                return null;
            }
            
            startIndex += pattern.length();
            int endIndex = description.indexOf(" 获得", startIndex);
            if (endIndex == -1) {
                // 尝试其他可能的结束标记
                endIndex = description.indexOf(" 达到", startIndex);
                if (endIndex == -1) {
                    return null;
                }
            }
            
            String workflowName = description.substring(startIndex, endIndex).trim();
            return workflowName.isEmpty() ? null : workflowName;
            
        } catch (Exception e) {
            log.warn("从描述中提取工作流名称失败：{}", description, e);
            return null;
        }
    }

    /**
     * 从用户余额记录的原始描述中提取视频名称
     * @param logs 余额记录列表
     * @return 视频名称，如果提取失败返回null
     */
    private String extractVideoTitleFromDescription(List<UserBalanceLog> logs) {
        if (logs == null || logs.isEmpty()) {
            return null;
        }
        
        // 获取第一条记录的描述（包含原始视频名称）
        String description = logs.get(0).getDescription();
        if (description == null || !description.contains("【视频收益】")) {
            return null;
        }
        
        try {
            // 提取模式：【视频收益】视频名称 达到...
            String pattern = "【视频收益】";
            int startIndex = description.indexOf(pattern);
            if (startIndex == -1) {
                return null;
            }
            
            startIndex += pattern.length();
            int endIndex = description.indexOf(" 达到", startIndex);
            if (endIndex == -1) {
                // 尝试其他可能的结束标记
                endIndex = description.indexOf(" 获得", startIndex);
                if (endIndex == -1) {
                    return null;
                }
            }
            
            String videoTitle = description.substring(startIndex, endIndex).trim();
            return videoTitle.isEmpty() ? null : videoTitle;
            
        } catch (Exception e) {
            log.warn("从描述中提取视频名称失败：{}", description, e);
            return null;
        }
    }

    @Override
    public WithdrawDto.WithdrawListResponse getWithdrawList(Long userId, int page, int size) {
        int offset = (page - 1) * size;
        
        // 查询提现记录
        List<com.dora.entity.WithdrawRequest> records = withdrawRequestMapper.selectByUserId(userId, offset, size);
        Long total = withdrawRequestMapper.countByUserId(userId);

        // 转换为响应对象
        List<WithdrawDto.WithdrawResponse> responses = records.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());

        WithdrawDto.WithdrawListResponse response = new WithdrawDto.WithdrawListResponse();
        response.setRecords(responses);
        response.setTotal(total);
        response.setPage(page);
        response.setSize(size);
        
        return response;
    }
} 