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.study.TbCourseTag;
import org.xyzh.common.dto.study.TbLearningRecord;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.utils.IDUtils;
import org.xyzh.common.vo.ChapterVO;
import org.xyzh.common.vo.CourseVO;
import org.xyzh.study.mapper.CourseMapper;
import org.xyzh.study.mapper.CourseTagMapper;
import org.xyzh.study.mapper.CourseChapterMapper;
import org.xyzh.study.mapper.CourseNodeMapper;
import org.xyzh.study.service.SCCourseService;
import org.xyzh.system.utils.LoginUtil;

/**
 * @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 CourseTagMapper courseTagMapper;

    @Autowired
    private CourseNodeMapper courseNodeMapper;

    @Override
    public ResultDomain<TbCourse> getCourseList(TbCourse filter) {
        ResultDomain<TbCourse> resultDomain = new ResultDomain<>();
        List<TbCourse> courses = courseMapper.selectCourses(filter);
        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<TbCourse> courses = courseMapper.selectCoursesPage(filter, pageParam);
        int total = (int) courseMapper.countCourses(filter);
        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<CourseVO> getCourseById(String courseID) {
        ResultDomain<CourseVO> resultDomain = new ResultDomain<>();
        // 查询课程
        TbCourse course = courseMapper.selectByCourseId(courseID);
        // 查询标签
        List<TbCourseTag> tags = courseTagMapper.selectByCourseId(courseID);
        CourseVO courseVO = new CourseVO();
        courseVO.setCourse(course);
        courseVO.setCourseTags(tags);

        // 查询课程章节
        TbCourseChapter filter = new TbCourseChapter();
        filter.setCourseID(courseID);
        List<TbCourseChapter> chapters = courseChapterMapper.selectCourseChapters(filter);
        // 查询子节点
        if (chapters.size() > 0) {
            List<String> chapterIDs = chapters.stream().map(TbCourseChapter::getChapterID).collect(Collectors.toList());
            List<TbCourseNode> nodes = courseNodeMapper.selectCourseNodesByChapterIDs(chapterIDs);
            Map<String, List<TbCourseNode>> nodesMap = nodes.stream().collect(Collectors.groupingBy(TbCourseNode::getChapterID));
            List<ChapterVO> chapterVOs = chapters.stream().map(chapter -> {
                ChapterVO chapterVO = new ChapterVO();
                chapterVO.setChapter(chapter);
                chapterVO.setNodes(nodesMap.get(chapter.getChapterID()));
                return chapterVO;
            }).collect(Collectors.toList());
            courseVO.setCourseChapters(chapterVOs);
        }

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

    @Override
    public ResultDomain<CourseVO> createCourse(CourseVO courseVO) {
        ResultDomain<CourseVO> resultDomain = new ResultDomain<>();
        TbSysUser user = LoginUtil.getCurrentUser();
        if (user == null) {
            resultDomain.fail("请先登录");
            return resultDomain;
        }
        TbCourse course = courseVO.getCourse();
        String courseID = IDUtils.generateID();
        course.setCreator(user.getID());
        course.setCourseID(courseID);
        Date now = new Date();
        course.setCreateTime(now);
        course.setStatus(0);


        courseMapper.insertCourse(course);

        List<ChapterVO> courseChapters = courseVO.getCourseChapters();
        List<TbCourseChapter> chapters = new ArrayList<>();
        List<TbCourseNode> nodes = new ArrayList<>();
        int length = courseChapters.size();
        for (int i=0; i<length; i++) {
            ChapterVO chapterVO = courseChapters.get(i);
            TbCourseChapter chapter = chapterVO.getChapter();
            List<TbCourseNode> nodesList = chapterVO.getNodes();

            chapter.setCourseID(courseID);
            String chapterID = IDUtils.generateID();
            chapter.setID(IDUtils.generateID());
            chapter.setChapterID(chapterID);
            chapter.setCreator(user.getID());
            chapter.setCreateTime(now);
            chapter.setOrderNum(i);
            chapters.add(chapter);

            for (int j=0; j<nodesList.size(); j++) {
                TbCourseNode node = nodesList.get(j);
                node.setNodeID(IDUtils.generateID());
                node.setChapterID(chapterID);
                node.setCreator(user.getID());
                node.setCreateTime(now);
                nodes.add(node);
            }
        }
        courseChapterMapper.batchInsertCourseChapters(chapters);
        courseNodeMapper.batchInsertCourseNodes(nodes);

        List<TbCourseTag> courseTags = courseVO.getCourseTags();
        length = courseTags.size();
        if (length > 0) {
            for (int i=0; i<length; i++) {
                TbCourseTag tag = courseTags.get(i);
                tag.setCourseID(courseID);
                tag.setTagID(IDUtils.generateID());
                tag.setCreator(user.getID());
                tag.setCreateTime(now);
            }
            courseTagMapper.batchInsertCourseTags(courseTags);
        }

        
        resultDomain.success("创建课程成功",courseVO);
        return resultDomain;
    }

    @Override
    public ResultDomain<CourseVO> updateCourse(CourseVO courseVO) {
        ResultDomain<CourseVO> resultDomain = new ResultDomain<>();
        
        TbSysUser user = LoginUtil.getCurrentUser();
        if (user == null) {
            resultDomain.fail("请先登录");
            return resultDomain;
        }
        
        TbCourse course = courseVO.getCourse();
        String courseID = course.getCourseID();
        
        if (courseID == null || courseID.isEmpty()) {
            resultDomain.fail("课程ID不能为空");
            return resultDomain;
        }
        
        // 1. 更新课程基本信息
        course.setUpdater(user.getID());
        course.setUpdateTime(new Date());
        courseMapper.updateCourse(course);
        
        // 2. 处理章节和节点
        List<ChapterVO> newChapterVOs = courseVO.getCourseChapters();
        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<>();
        Date now = new Date();
        
        // 遍历新的章节
        for (int i = 0; i < newChapterVOs.size(); i++) {
            ChapterVO chapterVO = newChapterVOs.get(i);
            TbCourseChapter chapter = chapterVO.getChapter();
            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<TbCourseNode> newNodes = chapterVO.getNodes();
            if (newNodes == null) {
                newNodes = 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 < newNodes.size(); j++) {
                TbCourseNode node = newNodes.get(j);
                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);
            }
        }
        
        // 3. 处理标签
        List<TbCourseTag> newTags = courseVO.getCourseTags();
        if (newTags == null) {
            newTags = new ArrayList<>();
        }
        
        // 获取现有标签
        List<TbCourseTag> existingTags = courseTagMapper.selectByCourseId(courseID);
        Map<String, TbCourseTag> existingTagMap = existingTags.stream()
                .collect(Collectors.toMap(TbCourseTag::getTagID, tag -> tag));
        
        Set<String> newTagIDs = new HashSet<>();
        List<TbCourseTag> tagsToInsert = new ArrayList<>();
        
        // 处理新标签
        for (TbCourseTag tag : newTags) {
            String tagID = tag.getTagID();
            
            if (tagID == null || tagID.isEmpty() || !existingTagMap.containsKey(tagID)) {
                // 新增标签
                tag.setID(IDUtils.generateID());
                tag.setCourseID(courseID);
                tag.setCreator(user.getID());
                tag.setCreateTime(now);
                tagsToInsert.add(tag);
            } else {
                newTagIDs.add(tagID);
            }
        }
        
        // 找出要删除的标签
        List<String> tagIDsToDelete = existingTagMap.keySet().stream()
                .filter(id -> !newTagIDs.contains(id))
                .collect(Collectors.toList());
        
        if (!tagIDsToDelete.isEmpty()) {
            courseTagMapper.batchDeleteCourseTags(tagIDsToDelete);
        }
        
        if (!tagsToInsert.isEmpty()) {
            courseTagMapper.batchInsertCourseTags(tagsToInsert);
        }
        
        resultDomain.success("更新课程成功", courseVO);
        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: 实现增加课程学习人数
        return null;
    }

    @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;
        }
    }
}
