package org.xyzh.study.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageDomain;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.study.TbCourse;
import org.xyzh.common.dto.study.TbCourseChapter;
import org.xyzh.common.dto.study.TbCourseNode;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.common.vo.CourseItemVO;
import org.xyzh.study.mapper.CourseMapper;
import org.xyzh.study.mapper.CourseChapterMapper;
import org.xyzh.study.mapper.CourseNodeMapper;
import org.xyzh.study.service.SCCourseService;
import org.xyzh.system.utils.LoginUtil;
import org.xyzh.api.system.permission.ResourcePermissionService;
import org.xyzh.common.vo.UserDeptRoleVO;
import org.xyzh.common.core.enums.ResourceType;

/**
 * @description 课程服务实现类
 * @filename SCCourseServiceImpl.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-10-15
 */
@Service
public class SCCourseServiceImpl implements SCCourseService {

    private static final Logger logger = LoggerFactory.getLogger(SCCourseServiceImpl.class);

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private CourseChapterMapper courseChapterMapper;

    @Autowired
    private CourseNodeMapper courseNodeMapper;

    @Autowired
    private ResourcePermissionService resourcePermissionService;

    @Override
    public ResultDomain<TbCourse> getCourseList(TbCourse filter) {
        ResultDomain<TbCourse> resultDomain = new ResultDomain<>();
        // 获取当前用户的部门角色
        List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
        List<TbCourse> courses = courseMapper.selectCourses(filter, userDeptRoles);
        resultDomain.success("获取课程列表成功", courses);
        return resultDomain;
    }

    @Override
    public ResultDomain<TbCourse> getCoursePage(PageRequest<TbCourse> pageRequest) {
        ResultDomain<TbCourse> resultDomain = new ResultDomain<>();
        TbCourse filter = pageRequest.getFilter();
        PageParam pageParam = pageRequest.getPageParam();
        // 获取当前用户的部门角色
        List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
        List<TbCourse> courses = courseMapper.selectCoursesPage(filter, pageParam, userDeptRoles);
        int total = (int) courseMapper.countCourses(filter, userDeptRoles);
        int totalPages = (int) Math.ceil((double) total / pageParam.getPageSize());
        pageParam.setTotalPages(totalPages);
        pageParam.setTotalElements(total);
        PageDomain<TbCourse> pageDomain = new PageDomain<>(pageParam, courses);
        resultDomain.success("获取课程列表成功", pageDomain);
        return resultDomain;
    }

    @Override
    public ResultDomain<CourseItemVO> getCourseById(String courseID) {
        ResultDomain<CourseItemVO> resultDomain = new ResultDomain<>();
        // 查询课程
        TbCourse course = courseMapper.selectByCourseId(courseID);
        if (course == null) {
            resultDomain.fail("课程不存在");
            return resultDomain;
        }

        // 从课程实体创建CourseItemVO
        CourseItemVO courseItemVO = CourseItemVO.fromCourse(course);

        // 查询课程章节
        TbCourseChapter filter = new TbCourseChapter();
        filter.setCourseID(courseID);
        List<TbCourseChapter> chapters = courseChapterMapper.selectCourseChapters(filter);
        
        // 查询并构建章节及节点结构
        if (!chapters.isEmpty()) {
            List<String> chapterIDs = chapters.stream()
                .map(TbCourseChapter::getChapterID)
                .collect(Collectors.toList());
            
            // 查询所有节点
            List<TbCourseNode> nodes = courseNodeMapper.selectCourseNodesByChapterIDs(chapterIDs);
            
            // 转换章节为CourseItemVO列表
            List<CourseItemVO> chapterVOs = chapters.stream()
                .map(CourseItemVO::fromChapter)
                .collect(Collectors.toList());
            
            // 转换节点为CourseItemVO，并按章节ID分组
            Map<String, List<CourseItemVO>> nodesMap = nodes.stream()
                .map(CourseItemVO::fromNode)
                .collect(Collectors.groupingBy(CourseItemVO::getChapterID));
            
            // 设置章节列表和章节节点映射
            courseItemVO.setChapters(chapterVOs);
            courseItemVO.setChapterNodes(nodesMap);
        }

        resultDomain.success("获取课程详情成功", courseItemVO);
        return resultDomain;
    }

    @Override
    public ResultDomain<CourseItemVO> createCourse(CourseItemVO courseItemVO) {
        ResultDomain<CourseItemVO> resultDomain = new ResultDomain<>();
        TbSysUser user = LoginUtil.getCurrentUser();
        if (user == null) {
            resultDomain.fail("请先登录");
            return resultDomain;
        }
        
        // 转换为课程实体并保存
        TbCourse course = courseItemVO.toCourse();
        String courseID = IDUtils.generateID();
        course.setID(IDUtils.generateID());
        course.setCreator(user.getID());
        course.setCourseID(courseID);
        Date now = new Date();
        course.setCreateTime(now);
        if (course.getStatus() == null) {
            course.setStatus(0);
        }
        courseMapper.insertCourse(course);
        courseItemVO.setCourseID(courseID);

        // 处理章节和节点
        List<CourseItemVO> chapterVOs = courseItemVO.getChapters();
        if (chapterVOs != null && !chapterVOs.isEmpty()) {
            List<TbCourseChapter> chapters = new ArrayList<>();
            List<TbCourseNode> allNodes = new ArrayList<>();
            
            for (int i = 0; i < chapterVOs.size(); i++) {
                CourseItemVO chapterVO = chapterVOs.get(i);
                TbCourseChapter chapter = chapterVO.toChapter();
                
                String chapterID = IDUtils.generateID();
                chapter.setID(IDUtils.generateID());
                chapter.setChapterID(chapterID);
                chapter.setCourseID(courseID);
                chapter.setCreator(user.getID());
                chapter.setCreateTime(now);
                chapter.setOrderNum(i);
                chapters.add(chapter);
                
                // 更新chapterVO中的ID
                chapterVO.setChapterID(chapterID);

                // 处理该章节的节点
                List<CourseItemVO> nodeVOs = chapterVO.getChapters(); // 节点存储在chapters字段中
                if (nodeVOs != null && !nodeVOs.isEmpty()) {
                    for (int j = 0; j < nodeVOs.size(); j++) {
                        CourseItemVO nodeVO = nodeVOs.get(j);
                        TbCourseNode node = nodeVO.toNode();
                        
                        String nodeID = IDUtils.generateID();
                        node.setID(IDUtils.generateID());
                        node.setNodeID(nodeID);
                        node.setChapterID(chapterID);
                        node.setCreator(user.getID());
                        node.setCreateTime(now);
                        node.setOrderNum(j);
                        allNodes.add(node);
                        
                        // 更新nodeVO中的ID
                        nodeVO.setNodeID(nodeID);
                    }
                }
            }
            
            if (!chapters.isEmpty()) {
                courseChapterMapper.batchInsertCourseChapters(chapters);
            }
            if (!allNodes.isEmpty()) {
                courseNodeMapper.batchInsertCourseNodes(allNodes);
            }
        }
        
        // 创建课程资源权限
        try {
            List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
            if (userDeptRoles != null && !userDeptRoles.isEmpty()) {
                // 使用用户的第一个部门角色创建权限
                resourcePermissionService.createResourcePermission(
                    ResourceType.COURSE.getCode(), 
                    courseID, 
                    userDeptRoles.get(0)
                );
                logger.info("创建课程权限成功: {}", courseID);
            }
        } catch (Exception e) {
            logger.error("创建课程权限异常，但不影响课程创建: {}", e.getMessage(), e);
        }
        
        resultDomain.success("创建课程成功", courseItemVO);
        return resultDomain;
    }

    @Override
    public ResultDomain<CourseItemVO> updateCourse(CourseItemVO courseItemVO) {
        ResultDomain<CourseItemVO> resultDomain = new ResultDomain<>();
        
        TbSysUser user = LoginUtil.getCurrentUser();
        if (user == null) {
            resultDomain.fail("请先登录");
            return resultDomain;
        }
        
        String courseID = courseItemVO.getCourseID();
        
        if (courseID == null || courseID.isEmpty()) {
            resultDomain.fail("课程ID不能为空");
            return resultDomain;
        }
        
        // 1. 更新课程基本信息
        TbCourse course = courseItemVO.toCourse();
        course.setUpdater(user.getID());
        Date now = new Date();
        course.setUpdateTime(now);
        courseMapper.updateCourse(course);
        
        // 2. 处理章节和节点
        List<CourseItemVO> newChapterVOs = courseItemVO.getChapters();
        if (newChapterVOs == null) {
            newChapterVOs = new ArrayList<>();
        }
        
        // 获取数据库中现有的章节
        TbCourseChapter filter = new TbCourseChapter();
        filter.setCourseID(courseID);
        List<TbCourseChapter> existingChapters = courseChapterMapper.selectCourseChapters(filter);
        Map<String, TbCourseChapter> existingChapterMap = existingChapters.stream()
                .collect(Collectors.toMap(TbCourseChapter::getChapterID, chapter -> chapter));
        
        // 获取数据库中现有的节点
        List<String> existingChapterIDs = existingChapters.stream()
                .map(TbCourseChapter::getChapterID)
                .collect(Collectors.toList());
        
        Map<String, List<TbCourseNode>> existingNodesMap = new HashMap<>();
        if (!existingChapterIDs.isEmpty()) {
            List<TbCourseNode> existingNodes = courseNodeMapper.selectCourseNodesByChapterIDs(existingChapterIDs);
            existingNodesMap = existingNodes.stream()
                    .collect(Collectors.groupingBy(TbCourseNode::getChapterID));
        }
        
        // 收集新的章节ID和节点
        List<TbCourseChapter> chaptersToInsert = new ArrayList<>();
        List<TbCourseChapter> chaptersToUpdate = new ArrayList<>();
        List<TbCourseNode> nodesToInsert = new ArrayList<>();
        List<TbCourseNode> nodesToUpdate = new ArrayList<>();
        
        Set<String> newChapterIDs = new HashSet<>();
        
        // 遍历新的章节
        for (int i = 0; i < newChapterVOs.size(); i++) {
            CourseItemVO chapterVO = newChapterVOs.get(i);
            TbCourseChapter chapter = chapterVO.toChapter();
            String chapterID = chapter.getChapterID();
            
            chapter.setCourseID(courseID);
            chapter.setOrderNum(i);
            
            // 判断是新增还是更新
            if (chapterID == null || chapterID.isEmpty() || !existingChapterMap.containsKey(chapterID)) {
                // 新增章节
                chapterID = IDUtils.generateID();
                chapter.setID(IDUtils.generateID());
                chapter.setChapterID(chapterID);
                chapter.setCreator(user.getID());
                chapter.setCreateTime(now);
                chaptersToInsert.add(chapter);
            } else {
                // 更新章节
                chapter.setID(existingChapterMap.get(chapterID).getID());
                chapter.setUpdater(user.getID());
                chapter.setUpdateTime(now);
                chaptersToUpdate.add(chapter);
            }
            
            newChapterIDs.add(chapterID);
            
            // 处理该章节的节点
            List<CourseItemVO> newNodeVOs = chapterVO.getChapters(); // 节点存储在chapters字段中
            if (newNodeVOs == null) {
                newNodeVOs = new ArrayList<>();
            }
            
            List<TbCourseNode> existingNodesForChapter = existingNodesMap.getOrDefault(chapterID, new ArrayList<>());
            Map<String, TbCourseNode> existingNodeMap = existingNodesForChapter.stream()
                    .collect(Collectors.toMap(TbCourseNode::getNodeID, node -> node));
            
            Set<String> newNodeIDs = new HashSet<>();
            
            // 遍历新的节点
            for (int j = 0; j < newNodeVOs.size(); j++) {
                CourseItemVO nodeVO = newNodeVOs.get(j);
                TbCourseNode node = nodeVO.toNode();
                String nodeID = node.getNodeID();
                
                node.setChapterID(chapterID);
                node.setOrderNum(j);
                
                // 判断是新增还是更新
                if (nodeID == null || nodeID.isEmpty() || !existingNodeMap.containsKey(nodeID)) {
                    // 新增节点
                    nodeID = IDUtils.generateID();
                    node.setID(IDUtils.generateID());
                    node.setNodeID(nodeID);
                    node.setCreator(user.getID());
                    node.setCreateTime(now);
                    nodesToInsert.add(node);
                } else {
                    // 更新节点
                    node.setID(existingNodeMap.get(nodeID).getID());
                    node.setUpdater(user.getID());
                    node.setUpdateTime(now);
                    nodesToUpdate.add(node);
                }
                
                newNodeIDs.add(nodeID);
            }
            
            // 找出要删除的节点
            List<String> nodeIDsToDelete = existingNodeMap.keySet().stream()
                    .filter(id -> !newNodeIDs.contains(id))
                    .collect(Collectors.toList());
            
            if (!nodeIDsToDelete.isEmpty()) {
                courseNodeMapper.batchDeleteCourseNodes(nodeIDsToDelete);
            }
        }
        
        // 找出要删除的章节
        List<String> chapterIDsToDelete = existingChapterMap.keySet().stream()
                .filter(id -> !newChapterIDs.contains(id))
                .collect(Collectors.toList());
        
        // 删除章节及其节点
        if (!chapterIDsToDelete.isEmpty()) {
            for (String chapterId : chapterIDsToDelete) {
                courseNodeMapper.deleteByChapterId(chapterId);
            }
            courseChapterMapper.batchDeleteCourseChapters(chapterIDsToDelete);
        }
        
        // 执行批量插入和更新
        if (!chaptersToInsert.isEmpty()) {
            courseChapterMapper.batchInsertCourseChapters(chaptersToInsert);
        }
        
        if (!chaptersToUpdate.isEmpty()) {
            for (TbCourseChapter chapter : chaptersToUpdate) {
                courseChapterMapper.updateCourseChapter(chapter);
            }
        }
        
        if (!nodesToInsert.isEmpty()) {
            courseNodeMapper.batchInsertCourseNodes(nodesToInsert);
        }
        
        if (!nodesToUpdate.isEmpty()) {
            for (TbCourseNode node : nodesToUpdate) {
                courseNodeMapper.updateCourseNode(node);
            }
        }
        
        resultDomain.success("更新课程成功", courseItemVO);
        return resultDomain;
    }

    @Override
    public ResultDomain<Boolean> deleteCourse(String courseID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        TbCourse course = new TbCourse();
        course.setCourseID(courseID);
        int result = courseMapper.deleteCourse(course);
        if (result > 0) {
            resultDomain.success("删除课程成功", true);
            return resultDomain;
        } else {
            resultDomain.fail("删除课程失败");
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbCourse> updateCourseStatus(TbCourse course) {
        ResultDomain<TbCourse> resultDomain = new ResultDomain<>();
        int result = courseMapper.updateCourse(course);
        if (result > 0) {
            resultDomain.success("更新课程状态成功", course);
            return resultDomain;
        }
        else {
            resultDomain.fail("更新课程状态失败");
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Boolean> incrementViewCount(String courseID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        int result = courseMapper.incrementViewCount(courseID);
        if (result > 0) {
            resultDomain.success("增加课程浏览次数成功", true);
            return resultDomain;
        } else {
            resultDomain.fail("增加课程浏览次数失败");
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbCourse> incrementLearnCount(String courseID) {
        // TODO: 实现增加课程学习人数
        ResultDomain<TbCourse> resultDomain = new ResultDomain<>();
        int i = courseMapper.incrementLearnCount(courseID,1);
        if (i > 0) {
            TbCourse course = courseMapper.selectByCourseId(courseID);
            resultDomain.success("开始学习", course);
            return resultDomain;
        }
        resultDomain.fail("报名失败");
        return resultDomain;
    }

    @Override
    public ResultDomain<TbCourseChapter> getCourseChapters(String courseID) {
        // TODO: 实现获取课程章节列表
        return null;
    }

    @Override
    public ResultDomain<TbCourseChapter> getChapterById(String chapterID) {
        // TODO: 实现根据ID获取章节详情
        return null;
    }

    @Override
    public ResultDomain<TbCourseChapter> createChapter(TbCourseChapter chapter) {
        ResultDomain<TbCourseChapter> resultDomain = new ResultDomain<>();
        int result = courseChapterMapper.insertCourseChapter(chapter);
        if (result > 0) {
            resultDomain.success("创建课程章节成功", chapter);
            return resultDomain;
        } else {
            resultDomain.fail("创建课程章节失败");
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbCourseChapter> updateChapter(TbCourseChapter chapter) {
        ResultDomain<TbCourseChapter> resultDomain = new ResultDomain<>();
        int result = courseChapterMapper.updateCourseChapter(chapter);
        if (result > 0) {
            resultDomain.success("更新课程章节成功", chapter);
            return resultDomain;
        } else {
            resultDomain.fail("更新课程章节失败");
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Boolean> deleteChapter(String chapterID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        TbCourseChapter chapter = new TbCourseChapter();
        chapter.setChapterID(chapterID);
        int result = courseChapterMapper.deleteCourseChapter(chapter);
        if (result > 0) {
            resultDomain.success("删除课程章节成功", true);
            return resultDomain;
        } else {
            resultDomain.fail("删除课程章节失败");
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<TbCourseChapter> updateChapterOrder(String chapterID, Integer orderNum) {
        // TODO: 实现更新章节排序
        return null;
    }

    @Override
    public ResultDomain<TbCourseNode> createChapterNode(TbCourseNode node) {
        ResultDomain<TbCourseNode> resultDomain = new ResultDomain<>();
        int result = courseNodeMapper.insertCourseNode(node);
        if (result > 0) {
            resultDomain.success("创建课程章节节点成功", node);
            return resultDomain;
        }else{
            resultDomain.fail("创建课程章节节点失败");
            return resultDomain;
        }

    }

    @Override
    public ResultDomain<TbCourseNode> updateChapterNode(TbCourseNode node) {
        ResultDomain<TbCourseNode> resultDomain = new ResultDomain<>();
        int result = courseNodeMapper.updateCourseNode(node);
        if (result > 0) {
            resultDomain.success("更新课程章节节点成功", node);
            return resultDomain;
        }else{
            resultDomain.fail("更新课程章节节点失败");
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<Boolean> deleteChapterNode(String nodeID) {
        ResultDomain<Boolean> resultDomain = new ResultDomain<>();
        TbCourseNode node = new TbCourseNode();
        node.setNodeID(nodeID);
        int result = courseNodeMapper.deleteCourseNode(node);
        if (result > 0) {
            resultDomain.success("删除课程章节节点成功", true);
            return resultDomain;
        } else {
            resultDomain.fail("删除课程章节节点失败");
            return resultDomain;
        }
    }

    @Override
    public ResultDomain<CourseItemVO> getCourseProgress(String courseID) {
        ResultDomain<CourseItemVO> resultDomain = new ResultDomain<>();

        // 获取当前用户
        TbSysUser user = LoginUtil.getCurrentUser();
        if (user == null) {
            resultDomain.fail("用户未登录");
            return resultDomain;
        }

        // 查询课程
        TbCourse course = courseMapper.selectByCourseId(courseID);
        if (course == null) {
            resultDomain.fail("课程不存在");
            return resultDomain;
        }

        // 从课程实体创建CourseItemVO
        CourseItemVO courseItemVO = CourseItemVO.fromCourse(course);

        // 查询课程章节
        TbCourseChapter filter = new TbCourseChapter();
        filter.setCourseID(courseID);
        List<TbCourseChapter> chapters = courseChapterMapper.selectCourseChapters(filter);

        // 查询并构建章节及节点结构（带进度）
        if (!chapters.isEmpty()) {
            List<String> chapterIDs = chapters.stream()
                .map(TbCourseChapter::getChapterID)
                .collect(Collectors.toList());

            // 查询带进度的节点（传入用户ID）
            List<CourseItemVO> nodesWithProgress = courseNodeMapper.selectNodesProgress(chapterIDs, user.getID());

            // 转换章节为CourseItemVO列表
            List<CourseItemVO> chapterVOs = chapters.stream()
                .map(CourseItemVO::fromChapter)
                .collect(Collectors.toList());

            // 按章节ID分组节点
            Map<String, List<CourseItemVO>> nodesMap = nodesWithProgress.stream()
                .collect(Collectors.groupingBy(CourseItemVO::getChapterID));

            // 设置章节列表和章节节点映射
            courseItemVO.setChapters(chapterVOs);
            courseItemVO.setChapterNodes(nodesMap);
        }

        resultDomain.success("获取课程进度成功", courseItemVO);
        return resultDomain;
    }

    @Override
    public ResultDomain<Integer> getCourseCount(TbCourse filter) {
        ResultDomain<Integer> resultDomain = new ResultDomain<>();
        try {
            // 获取当前用户的部门角色
            List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
            long count = courseMapper.countCourses(filter, userDeptRoles);
            resultDomain.success("获取课程数量成功", (int) count);
        } catch (Exception e) {
            logger.error("获取课程数量失败", e);
            resultDomain.fail("获取课程数量失败: " + e.getMessage());
        }
        return resultDomain;
    }
}
