package com.dora.service.impl;

import com.dora.entity.ContentRevenueStage;
import com.dora.entity.Course;
import com.dora.entity.CourseChapter;
import com.dora.entity.CourseVideo;
import com.dora.entity.RevenueConfig;
import com.dora.entity.Video;
import com.dora.entity.Workflow;
import com.dora.mapper.ContentRevenueStageMapper;
import com.dora.mapper.CourseChapterMapper;
import com.dora.mapper.CourseMapper;
import com.dora.mapper.CourseVideoMapper;
import com.dora.mapper.RevenueConfigMapper;
import com.dora.mapper.VideoMapper;
import com.dora.mapper.WorkflowMapper;
import com.dora.mapper.WorkflowCopyStatMapper;
import com.dora.service.ContentRevenueStageService;
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 java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 内容收益阶段服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ContentRevenueStageServiceImpl implements ContentRevenueStageService {

    private final ContentRevenueStageMapper contentRevenueStageMapper;
    private final RevenueConfigMapper revenueConfigMapper;
    private final WorkflowMapper workflowMapper;
    private final WorkflowCopyStatMapper workflowCopyStatMapper;
    private final VideoMapper videoMapper;
    private final UserBalanceService userBalanceService;
    private final CourseMapper courseMapper;
    private final CourseVideoMapper courseVideoMapper;
    private final CourseChapterMapper courseChapterMapper;

    @Override
    @Transactional
    public List<ContentRevenueStage> checkAndUpdateVideoRevenueStages(Long videoId, Long ownerId, Integer currentViewCount) {
        List<ContentRevenueStage> newlyAchievedStages = new ArrayList<>();
        
        try {
            log.info("检查视频收益阶段 - videoId: {}, ownerId: {}, currentViewCount: {}", 
                    videoId, ownerId, currentViewCount);

            // 获取该视频的所有收益阶段
            List<ContentRevenueStage> stages = contentRevenueStageMapper.selectByContentId(2, videoId);
            
            if (stages.isEmpty()) {
                // 如果没有收益阶段配置，初始化配置
                log.info("视频没有收益阶段配置，开始初始化 - videoId: {}", videoId);
                initializeVideoRevenueStages(videoId, ownerId);
                stages = contentRevenueStageMapper.selectByContentId(2, videoId);
            }

            // 检查并更新每个阶段
            for (ContentRevenueStage stage : stages) {
                // 更新当前数量
                if (!stage.getCurrentCount().equals(currentViewCount)) {
                    contentRevenueStageMapper.updateCurrentCount(stage.getId(), currentViewCount);
                    stage.setCurrentCount(currentViewCount);
                }

                // 检查是否新达到目标（确保一个阶段只触发一次）
                if (stage.getIsAchieved() == 0 && currentViewCount >= stage.getTargetCount()) {
                    // 标记为已达到
                    LocalDateTime now = LocalDateTime.now();
                    contentRevenueStageMapper.markAsAchieved(stage.getId(), now);
                    stage.setIsAchieved(1);
                    stage.setAchievedAt(now);
                    newlyAchievedStages.add(stage);
                    
                    log.info("视频达到新的收益阶段 - videoId: {}, stage: {}, targetCount: {}, rewardAmount: {}", 
                            videoId, stage.getStageName(), stage.getTargetCount(), stage.getRewardAmount());
                    
                    // 自动分成到用户余额
                    try {
                        // 获取视频信息（添加空指针防护）
                        String videoTitle = "未知视频";
                        if (videoMapper != null) {
                            try {
                                Video video = videoMapper.selectById(videoId);
                                if (video != null && video.getTitle() != null) {
                                    videoTitle = video.getTitle();
                                }
                            } catch (Exception e) {
                                log.warn("获取视频信息失败，使用默认标题 - videoId: {}", videoId, e);
                            }
                        } else {
                            log.warn("videoMapper为null，使用默认视频标题 - videoId: {}", videoId);
                        }
                        
                        userBalanceService.increaseBalance(
                            ownerId,
                            stage.getRewardAmount(),
                            "video",
                            videoId,
                            String.format("【视频收益】%s 达到%s阶段奖励 - 观看次数达到%d次，获得%.2f元收益", 
                                    videoTitle, stage.getStageName(), stage.getTargetCount(), stage.getRewardAmount())
                        );
                        
                        log.info("视频收益自动分成成功 - videoId: {}, ownerId: {}, amount: {}", 
                                videoId, ownerId, stage.getRewardAmount());
                    } catch (Exception e) {
                        log.error("视频收益自动分成失败 - videoId: {}, ownerId: {}, amount: {}", 
                                videoId, ownerId, stage.getRewardAmount(), e);
                        // 不抛出异常，避免影响主流程
                    }
                }
            }

            if (!newlyAchievedStages.isEmpty()) {
                BigDecimal totalNewRevenue = newlyAchievedStages.stream()
                        .map(ContentRevenueStage::getRewardAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                
                log.info("视频收益阶段检查完成 - videoId: {}, 新达到阶段数: {}, 新获得收益: {}", 
                        videoId, newlyAchievedStages.size(), totalNewRevenue);
            }

            return newlyAchievedStages;

        } catch (Exception e) {
            log.error("检查视频收益阶段失败 - videoId: {}, ownerId: {}", videoId, ownerId, e);
            return new ArrayList<>();
        }
    }

    @Override
    public boolean isWorkflowVideo(String vodVideoId) {
        try {
            // 通过 vodVideoId 查询是否存在对应的工作流
            Integer workflowCount = workflowMapper.countByVodVideoId(vodVideoId);
            boolean isWorkflow = workflowCount != null && workflowCount > 0;
            
            if (isWorkflow) {
                log.debug("视频属于工作流，不参与收益分成 - vodVideoId: {}", vodVideoId);
            }
            
            return isWorkflow;
        } catch (Exception e) {
            log.error("检查工作流视频失败 - vodVideoId: {}", vodVideoId, e);
            // 出错时默认为非工作流视频，确保收益逻辑正常运行
            return false;
        }
    }

    @Override
    public boolean isFreeAccessVideo(Long videoId, Long courseId) {
        try {
            log.debug("检查视频是否对免费用户开放 - videoId: {}, courseId: {}", videoId, courseId);
            
            // 如果提供了课程ID，检查课程是否对免费用户开放
            if (courseId != null) {
                Course course = courseMapper.selectById(courseId);
                if (course != null) {
                    // 检查课程是否免费或对免费用户开放（level=0表示所有用户都可访问）
                    boolean courseFreeAccess = course.getIsFree() == 1 || course.getLevel() == 0;
                    if (courseFreeAccess) {
                        log.debug("课程对免费用户开放，不参与收益分成 - courseId: {}, isFree: {}, level: {}", 
                                courseId, course.getIsFree(), course.getLevel());
                        return true;
                    }
                    return false;
                }
            }
            
            // 如果没有课程ID，检查是否是课程中的视频
            CourseVideo courseVideo = courseVideoMapper.selectByVideoId(videoId);
            if (courseVideo != null && courseVideo.getChapterId() != null) {
                // 是课程视频，通过章节ID获取课程ID
                CourseChapter chapter = courseChapterMapper.selectById(courseVideo.getChapterId());
                if (chapter != null && chapter.getCourseId() != null) {
                    // 递归检查课程权限
                    return isFreeAccessVideo(videoId, chapter.getCourseId());
                }
            }
            
            // 不是课程视频，检查视频本身的公开状态
            // 注意：这里需要通过 videoId 获取视频信息，但我们已经在调用方有video对象
            // 为了避免重复查询，这里假设普通视频（非课程视频）如果是公开的就不参与收益分成
            // 实际业务中可能需要更精确的判断逻辑
            log.debug("普通视频，假设参与收益分成 - videoId: {}", videoId);
            return false;
            
        } catch (Exception e) {
            log.error("检查免费视频失败 - videoId: {}, courseId: {}", videoId, courseId, e);
            // 出错时默认为需要付费权限，确保收益逻辑正常运行
            return false;
        }
    }

    @Override
    @Transactional
    public void initializeVideoRevenueStages(Long videoId, Long ownerId) {
        try {
            log.info("初始化视频收益阶段配置 - videoId: {}, ownerId: {}", videoId, ownerId);

            // 获取视频收益配置
            List<RevenueConfig> videoConfigs = revenueConfigMapper.selectByConfigType("video");
            
            if (videoConfigs.isEmpty()) {
                log.warn("没有找到视频收益配置，跳过初始化 - videoId: {}", videoId);
                return;
            }

            // 为每个配置创建收益阶段记录
            for (RevenueConfig config : videoConfigs) {
                ContentRevenueStage stage = new ContentRevenueStage();
                stage.setContentType(2); // 2=视频
                stage.setContentId(videoId);
                stage.setUserId(ownerId);
                stage.setStageLevel(config.getLevel());
                stage.setStageName(config.getLevelName());
                stage.setTargetCount(config.getTargetCount());
                stage.setRewardAmount(config.getRewardAmount());
                stage.setCurrentCount(0);
                stage.setIsAchieved(0);
                stage.setIsWithdrawn(0);
                stage.setCreateTime(LocalDateTime.now());
                stage.setUpdateTime(LocalDateTime.now());
                stage.setIsDeleted(0);

                // 插入收益阶段记录
                int insertResult = contentRevenueStageMapper.insert(stage);
                if (insertResult > 0) {
                    log.info("成功创建收益阶段配置 - videoId: {}, level: {}, targetCount: {}, rewardAmount: {}", 
                            videoId, stage.getStageLevel(), stage.getTargetCount(), stage.getRewardAmount());
                } else {
                    log.error("创建收益阶段配置失败 - videoId: {}, level: {}", videoId, stage.getStageLevel());
                }
            }

            log.info("视频收益阶段配置初始化完成 - videoId: {}, 创建阶段数: {}", videoId, videoConfigs.size());

        } catch (Exception e) {
            log.error("初始化视频收益阶段配置失败 - videoId: {}, ownerId: {}", videoId, ownerId, e);
        }
    }

    @Override
    public List<ContentRevenueStage> getVideoRevenueStages(Long videoId) {
        try {
            return contentRevenueStageMapper.selectByContentId(2, videoId);
        } catch (Exception e) {
            log.error("获取视频收益阶段失败 - videoId: {}", videoId, e);
            return new ArrayList<>();
        }
    }

    @Override
    public BigDecimal calculateTotalRevenue(Long userId, Integer contentType) {
        try {
            BigDecimal totalRevenue = contentRevenueStageMapper.sumUnwithdrawnAmount(userId);
            return totalRevenue != null ? totalRevenue : BigDecimal.ZERO;
        } catch (Exception e) {
            log.error("计算用户总收益失败 - userId: {}, contentType: {}", userId, contentType, e);
            return BigDecimal.ZERO;
        }
    }

    @Override
    @Transactional  
    public List<ContentRevenueStage> checkAndUpdateWorkflowRevenueStages(Long workflowId, Long ownerId, Integer currentCopyCount) {
        // 这个方法现在改为处理单次使用奖励，不再使用阶段分成逻辑
        return processWorkflowPerUseRevenue(workflowId, ownerId);
    }
    
    /**
     * 处理工作流单次使用收益（每个用户首次使用给固定金额）
     */
    @Transactional
    public List<ContentRevenueStage> processWorkflowPerUseRevenue(Long workflowId, Long ownerId) {
        List<ContentRevenueStage> rewardRecords = new ArrayList<>();
        
        try {
            log.info("处理工作流单次使用收益 - workflowId: {}, ownerId: {}", workflowId, ownerId);

            // 检查工作流是否为免费工作流，免费工作流不参与收益分成
            Workflow workflow = workflowMapper.selectById(workflowId);
            if (workflow == null) {
                log.warn("工作流不存在，跳过收益检查 - workflowId: {}", workflowId);
                return new ArrayList<>();
            }
            
            if (workflow.getIsFree() != null && workflow.getIsFree() == 1) {
                log.info("工作流为免费工作流，不参与收益分成 - workflowId: {}, isFree: {}", workflowId, workflow.getIsFree());
                return new ArrayList<>();
            }

            // 获取工作流单次使用奖励配置
            RevenueConfig perUseConfig = revenueConfigMapper.selectByConfigKey("workflow_per_use_reward");
            if (perUseConfig == null) {
                log.warn("未找到工作流单次使用奖励配置，跳过收益发放 - configKey: workflow_per_use_reward");
                return new ArrayList<>();
            }
            
            BigDecimal perUseReward = perUseConfig.getRewardAmount();
            if (perUseReward == null || perUseReward.compareTo(BigDecimal.ZERO) <= 0) {
                log.info("工作流单次使用奖励金额为0，跳过收益发放 - workflowId: {}, rewardAmount: {}", workflowId, perUseReward);
                return new ArrayList<>();
            }

            // 发放单次使用奖励
            try {
                userBalanceService.increaseBalance(
                    ownerId,
                    perUseReward,
                    "workflow",
                    workflowId,
                    String.format("【工作流收益】%s 获得新用户使用奖励 - 每个用户首次使用获得%.2f元收益", workflow.getName(), perUseReward)
                );
                
                log.info("工作流单次使用收益发放成功 - workflowId: {}, ownerId: {}, amount: {}", 
                        workflowId, ownerId, perUseReward);
                        
                // 创建奖励记录（用于返回）
                ContentRevenueStage rewardRecord = new ContentRevenueStage();
                rewardRecord.setContentType(1);
                rewardRecord.setContentId(workflowId);
                rewardRecord.setUserId(ownerId);
                rewardRecord.setRewardAmount(perUseReward);
                rewardRecord.setStageName("单次使用奖励");
                rewardRecords.add(rewardRecord);
                
            } catch (Exception e) {
                log.error("工作流单次使用收益发放失败 - workflowId: {}, ownerId: {}, amount: {}", 
                        workflowId, ownerId, perUseReward, e);
                // 不抛出异常，避免影响主流程
            }

            return rewardRecords;

        } catch (Exception e) {
            log.error("处理工作流单次使用收益失败 - workflowId: {}, ownerId: {}", workflowId, ownerId, e);
            return new ArrayList<>();
        }
    }

    @Override
    @Transactional
    public void initializeWorkflowRevenueStages(Long workflowId, Long ownerId) {
        // 单次使用奖励模式不需要为每个工作流初始化收益阶段
        // 所有工作流共用全局的单次使用奖励配置
        log.info("工作流收益模式已改为单次使用奖励，无需初始化收益阶段 - workflowId: {}, ownerId: {}", workflowId, ownerId);
    }
}
