package jnpf.cultivate.event.impl.course;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.cultivate.event.JnpfApplicationEventService;
import jnpf.cultivate.mapper.FtbCultivateCourseChapterMapper;
import jnpf.cultivate.mapper.FtbCultivateCourseMapper;
import jnpf.cultivate.service.CultivateCourseMsgService;
import jnpf.cultivate.service.impl.FtbCultivatePositionCourceChapterLearningService;
import jnpf.cultivate.service.impl.FtbCultivatePositionCourceLearningService;
import jnpf.cultivate.utils.UserApiV2Util;
import jnpf.model.cultivate.event.dto.course.CourseEventDTO;
import jnpf.model.cultivate.po.course.FtbCultivateCourse;
import jnpf.model.cultivate.po.course.FtbCultivateCourseChapter;
import jnpf.model.cultivate.po.course.app.CultivateCourseMsg;
import jnpf.model.cultivate.po.paper.FtbCultivateTestPaperQuestion;
import jnpf.model.cultivate.po.position.FtbCultivatePositionCourceChapterLearning;
import jnpf.model.cultivate.po.position.FtbCultivatePositionCourceLearning;
import jnpf.model.enums.CourseEnums;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class JnpfApplicationEventCourseService implements JnpfApplicationEventService {

    private final FtbCultivatePositionCourceLearningService ftbCultivatePositionCourceLearningService;
    private final FtbCultivatePositionCourceChapterLearningService ftbCultivatePositionCourceChapterLearningService;
    private final FtbCultivateCourseChapterMapper ftbCultivateCourseChapterMapper;
    private final FtbCultivateCourseMapper ftbCultivateCourseMapper;
    private final CultivateCourseMsgService cultivateCourseMsgService;


    private static final ReentrantLock lock = new ReentrantLock();


    @Override
    public boolean isSupportedCourseEvent(Object event) {
        return event instanceof CourseEventDTO;
    }

    @Override
    public void handlerCourseEvent(Object courseEvent) {
        CourseEventDTO courseEventDTO = (CourseEventDTO) courseEvent;
        if (CollUtil.isEmpty(courseEventDTO.getCourseIds())) {
            return;
        }
        List<String> userIds = courseEventDTO.getUserIds();
        if (CollUtil.isNotEmpty(userIds)) {
            userIds = UserApiV2Util.uniqueStringList(userIds);
            courseEventDTO.setUserIds(userIds);
        }
        if(CollUtil.isNotEmpty(courseEventDTO.getCourseIds())){
            courseEventDTO.setCourseIds(UserApiV2Util.uniqueStringList(courseEventDTO.getCourseIds()));
        }
        try {
            // 课程并发操作数据库造成数据不一致，加锁
            lock.lock();
            if (courseEventDTO.getWhetherToChange()) {
                // 变更章节去进行重新学习
                if (CollectionUtils.isEmpty(userIds)) {
                    // 课程是否勾选已学习的才进行
                    LambdaQueryWrapper<FtbCultivateCourse> queryWrapper = Wrappers.lambdaQuery();
                    queryWrapper.select(FtbCultivateCourse::getId);
                    queryWrapper.in(FtbCultivateCourse::getId, courseEventDTO.getCourseIds());
                    queryWrapper.eq(FtbCultivateCourse::getEnableMark, 0);
                    queryWrapper.eq(FtbCultivateCourse::getCourseUpdate, 1);
                    List<FtbCultivateCourse> oldCourses = ftbCultivateCourseMapper.selectList(queryWrapper);
                    List<String> courseIds = oldCourses.stream()
                            .map(FtbCultivateCourse::getId).collect(Collectors.toList());
                    // 原始值替换
                    courseEventDTO.setCourseIds(courseIds);
                }
                if (CollUtil.isNotEmpty(courseEventDTO.getCourseIds())) {
                    // 课程变更，导致所有学习课程重新学一遍
                    LambdaQueryWrapper<FtbCultivatePositionCourceLearning> positionQueryWrapper = Wrappers.lambdaQuery();
                    positionQueryWrapper.in(FtbCultivatePositionCourceLearning::getCourceId, courseEventDTO.getCourseIds());
                    // 有用户则为学习地图清空，无则为变更课程章节
                    positionQueryWrapper.in(CollectionUtils.isNotEmpty(userIds), FtbCultivatePositionCourceLearning::getUserId, userIds);
                    List<FtbCultivatePositionCourceLearning> oldPositionCourceLearnings = ftbCultivatePositionCourceLearningService.list(positionQueryWrapper);
                    if (CollUtil.isNotEmpty(oldPositionCourceLearnings)) {
                        userIds = oldPositionCourceLearnings.stream()
                                .map(FtbCultivatePositionCourceLearning::getUserId)
                                .distinct()
                                .collect(Collectors.toList());
                        // 课程学习清空
                        ftbCultivatePositionCourceLearningService.remove(positionQueryWrapper);
                        // 课程章节学习清空
                        LambdaQueryWrapper<FtbCultivatePositionCourceChapterLearning> chapterQueryWrapper = Wrappers.lambdaQuery();
                        chapterQueryWrapper.in(FtbCultivatePositionCourceChapterLearning::getCourceId, courseEventDTO.getCourseIds());
                        // 有用户则为学习地图清空，无则为变更课程章节
                        chapterQueryWrapper.in(CollectionUtils.isNotEmpty(userIds), FtbCultivatePositionCourceChapterLearning::getUserId, userIds);
                        ftbCultivatePositionCourceChapterLearningService.remove(chapterQueryWrapper);
                        // 课程变更提醒
                        LambdaQueryWrapper<FtbCultivateCourse> courseQueryWrapper = Wrappers.lambdaQuery();
                        List<String> strings = oldPositionCourceLearnings.stream()
                                .map(FtbCultivatePositionCourceLearning::getCourceId)
                                .collect(Collectors.toList());
                        courseQueryWrapper.in(FtbCultivateCourse::getId, strings);
                        List<FtbCultivateCourse> ftbCultivateCourses = ftbCultivateCourseMapper.selectList(courseQueryWrapper);
                        Map<String, FtbCultivateCourse> collect = ftbCultivateCourses.stream()
                                .collect(Collectors.toMap(FtbCultivateCourse::getId, k -> k, (a, b) -> a));
                        List<CultivateCourseMsg> cultivateCourseMsgs = oldPositionCourceLearnings.stream()
                                .map(positionCourceLearning -> {
                                    FtbCultivateCourse ftbCultivateCourse = collect.getOrDefault(positionCourceLearning.getCourceId(), null);
                                    // 课程内容更新需要重新学习
                                    if (Objects.nonNull(ftbCultivateCourse) && ftbCultivateCourse.getCourseUpdate() == 1) {
                                        return positionCourceLearning.getState() == 0 ? null
                                                : getCultivateCourseMsg(positionCourceLearning, ftbCultivateCourse);
                                    }
                                    return null;
                                }).filter(Objects::nonNull).collect(Collectors.toList());
                        cultivateCourseMsgService.saveBatch(cultivateCourseMsgs);
                    }
                }
            }
            // 课程进度，参与培训所有人员需要学习的课程,线下培训课程需要和岗位学习课程同步
            List<FtbCultivatePositionCourceLearning> ftbCultivatePositionCourceLearnings = new ArrayList<>();
            List<FtbCultivatePositionCourceChapterLearning> ftbCultivatePositionCourceChapterLearnings = new ArrayList<>();
            userIds.forEach(userId -> {
                courseEventDTO.getCourseIds().forEach(courseId -> {
                    if (courseEventDTO.getWhetherToChange()) {
                        studyCourseAssembly(userId, courseId,
                                ftbCultivatePositionCourceLearnings, ftbCultivatePositionCourceChapterLearnings);
                        return;
                    }
                    // 课程是否已学习
                    LambdaQueryWrapper<FtbCultivatePositionCourceLearning> positionQueryWrapper = Wrappers.lambdaQuery();
                    positionQueryWrapper.eq(FtbCultivatePositionCourceLearning::getUserId, userId);
                    positionQueryWrapper.eq(FtbCultivatePositionCourceLearning::getState, 1);
                    positionQueryWrapper.eq(FtbCultivatePositionCourceLearning::getCourceId, courseId);
                    if (ftbCultivatePositionCourceLearningService.count(positionQueryWrapper) == 0) {
                        studyCourseAssembly(userId, courseId,
                                ftbCultivatePositionCourceLearnings, ftbCultivatePositionCourceChapterLearnings);
                    }
                });
            });
            // 课程进度和课程章节
            if(CollUtil.isNotEmpty(ftbCultivatePositionCourceLearnings)) {
                ftbCultivatePositionCourceLearningService.saveBatch(ftbCultivatePositionCourceLearnings);
            }
            if(CollUtil.isNotEmpty(ftbCultivatePositionCourceChapterLearnings)) {
                ftbCultivatePositionCourceChapterLearningService.saveBatch(ftbCultivatePositionCourceChapterLearnings);
            }
        } finally {
            if (lock.isLocked()) {
                lock.unlock();
            }
        }
    }

    @NotNull
    private static CultivateCourseMsg getCultivateCourseMsg(FtbCultivatePositionCourceLearning positionCourceLearning,
                                                            FtbCultivateCourse ftbCultivateCourse) {
        CultivateCourseMsg cultivateCourseMsg = new CultivateCourseMsg();
        if (positionCourceLearning.getState() == 1) {
            cultivateCourseMsg.setDesc("您正在学习的课程" + ftbCultivateCourse.getName() + "有更新，请重新学习");
        } else if (positionCourceLearning.getState() == 2) {
            cultivateCourseMsg.setDesc("您已学习过的课程" + ftbCultivateCourse.getName() + "学习内容有更新，您可以重新学习");
        }
        cultivateCourseMsg.setCourseId(ftbCultivateCourse.getId());
        return cultivateCourseMsg;
    }

    /**
     * 学习课程组装
     *
     * @param userId                                     用户 ID
     * @param courseId                                   课程 ID
     * @param ftbCultivatePositionCourceLearnings        FtbCultivatePositionCourceLearning 对象的列表，用于存储学习课程信息
     * @param ftbCultivatePositionCourceChapterLearnings FtbCultivatePositionCourceChapterLearning 对象的列表，用于存储学习课程章节信息
     */
    private void studyCourseAssembly(String userId, String courseId,
                                     List<FtbCultivatePositionCourceLearning> ftbCultivatePositionCourceLearnings,
                                     List<FtbCultivatePositionCourceChapterLearning> ftbCultivatePositionCourceChapterLearnings) {

        //查询用户课程进度，如果已存在则不继续添加课程进度
        QueryWrapper<FtbCultivatePositionCourceLearning> postionCourseLearningQueryWrapper = new QueryWrapper<>();
        postionCourseLearningQueryWrapper.lambda()
                .eq(FtbCultivatePositionCourceLearning::getCourceId, courseId)
                .eq(FtbCultivatePositionCourceLearning::getUserId, userId);
        List<FtbCultivatePositionCourceLearning> isExist = ftbCultivatePositionCourceLearningService.getBaseMapper().selectList(postionCourseLearningQueryWrapper);
        if (CollectionUtil.isEmpty(isExist)) {
            FtbCultivatePositionCourceLearning ftbCultivatePositionCourceLearning = new FtbCultivatePositionCourceLearning();
            ftbCultivatePositionCourceLearning.setCourceId(courseId);
            ftbCultivatePositionCourceLearning.setUserId(userId);
            ftbCultivatePositionCourceLearnings.add(ftbCultivatePositionCourceLearning);
        }

        // 课程章节
        LambdaQueryWrapper<FtbCultivateCourseChapter> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbCultivateCourseChapter::getCourseId, courseId);
        queryWrapper.eq(FtbCultivateCourseChapter::getEnableMark, 0);
        List<FtbCultivateCourseChapter> ftbCultivateCourseChapters = ftbCultivateCourseChapterMapper.selectList(queryWrapper);
        QueryWrapper<FtbCultivatePositionCourceChapterLearning> learnerQueryWrapper = new QueryWrapper<>();
        learnerQueryWrapper.lambda()
                .eq(FtbCultivatePositionCourceChapterLearning::getUserId, userId)
                .eq(FtbCultivatePositionCourceChapterLearning::getCourceId, courseId)
                .eq(FtbCultivatePositionCourceChapterLearning::getEnabledMark, 0);
        List<FtbCultivatePositionCourceChapterLearning> learnList = ftbCultivatePositionCourceChapterLearningService.list(learnerQueryWrapper);
        List<String> chapterIds = new ArrayList<>();
        if(CollUtil.isNotEmpty(learnList)) {
            chapterIds = learnList.stream().map(FtbCultivatePositionCourceChapterLearning::getChapterId).collect(Collectors.toList());
        }
        for (FtbCultivateCourseChapter ftbCultivateCourseChapter : ftbCultivateCourseChapters) {
            if(chapterIds.contains(ftbCultivateCourseChapter.getId())){
                continue;
            }
            FtbCultivatePositionCourceChapterLearning ftbCultivatePositionCourceChapterLearning = new FtbCultivatePositionCourceChapterLearning();
            ftbCultivatePositionCourceChapterLearning.setUserId(userId);
            ftbCultivatePositionCourceChapterLearning.setChapterId(ftbCultivateCourseChapter.getId());
            ftbCultivatePositionCourceChapterLearning.setCourceId(courseId);
            ftbCultivatePositionCourceChapterLearnings.add(ftbCultivatePositionCourceChapterLearning);
        }
    }
}
