package jnpf.cultivate.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jnpf.base.vo.PageListVO;
import jnpf.base.vo.PaginationVO;
import jnpf.cultivate.mapper.*;
import jnpf.cultivate.service.CultivateIdentifyApplyService;
import jnpf.cultivate.service.FtbCultivateExamUserService;
import jnpf.cultivate.service.FtbCultivatePositionForAppService;
import jnpf.cultivate.utils.CultivatePerUtils;
import jnpf.cultivate.utils.UserApiV2Util;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.bo.TriggerEventBO;
import jnpf.model.cultivate.dto.position.app.FtbCultivatePositionForAppNewDTO;
import jnpf.model.cultivate.event.JnpfApplicationEvent;
import jnpf.model.cultivate.event.dto.examidentify.ExamIdentifyTriggerEventDTO;
import jnpf.model.cultivate.po.course.FtbCultivateCourse;
import jnpf.model.cultivate.po.course.FtbCultivateCourseChapter;
import jnpf.model.cultivate.po.position.FtbCultivatePosition;
import jnpf.model.cultivate.po.position.FtbCultivatePositionCourceChapterLearning;
import jnpf.model.cultivate.po.position.FtbCultivatePositionCourceLearning;
import jnpf.model.cultivate.po.position.FtbCultivatePositionCourse;
import jnpf.model.cultivate.resp.CompleteExamVo;
import jnpf.model.cultivate.vo.course.app.FtbGlobalCurriculumAppVO;
import jnpf.model.cultivate.vo.identify.IdentifyApplyInfoApiVo;
import jnpf.model.cultivate.vo.position.app.FtbPopUpPromptVO;
import jnpf.model.cultivate.vo.position.app.FtbSubordinateLearningCoursesVO;
import jnpf.model.cultivate.vo.position.app.OnTheJobLearningCourseVO;
import jnpf.permission.vo.v2.position.PositionVO;
import jnpf.util.context.SpringContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Title: FtbCultivatePositionForAppServiceImpl
 * @Author:peng.hao
 * @create: 2023/12/2717:35
 */
@Slf4j
@Service
public class FtbCultivatePositionForAppServiceImpl implements FtbCultivatePositionForAppService {

    @Resource
    private CultivateIdentifyApplyService cultivateIdentifyApplyService;
    @Resource
    private FtbCultivatePositionCourceLearningMapper ftbCultivatePositionCourceLearningMapper;
    @Resource
    private FtbCultivateExamUserService ftbCultivateExamUserService;
    @Resource
    private FtbCultivatePositionCourseMapper ftbCultivatePositionCourseMapper;
    @Resource
    private FtbCultivatePositionCourceLearningService ftbCultivatePositionCourceLearningService;
    @Resource
    private FtbCultivatePositionCourceChapterLearningService ftbCultivatePositionCourceChapterLearningService;
    @Resource
    private FtbCultivateCourseChapterMapper ftbCultivateCourseChapterMapper;
    @Resource
    private FtbCultivatePositionMapper ftbCultivatePositionMapper;

    @Resource
    private FtbCultivateCourseMapper ftbCultivateCourseMapper;
    @Autowired
    private UserApiV2Util userApiV2Util;

    @Override
    @Transactional
    public OnTheJobLearningCourseVO onTheJobLearningCourse(FtbCultivatePositionForAppNewDTO dto) {
        // 课程是否初始化
        isTheCourseInitialized(dto.getUserId(), dto.getPostId());
        OnTheJobLearningCourseVO onTheJobLearningCourse = new OnTheJobLearningCourseVO();
        // 课程内容
        List<FtbGlobalCurriculumAppVO> fullCurriculumAppList = ftbCultivatePositionCourceLearningMapper.onTheJobLearningCourse(dto);
        // 课程总数
        onTheJobLearningCourse.setTotalCourse(fullCurriculumAppList.size());
        // 已学习课程数
        long alreadyLearnedCourse = fullCurriculumAppList.stream().filter(a -> a.getLearnState() == 1).count();
        onTheJobLearningCourse.setAlreadyLearnedCourse(alreadyLearnedCourse);
        fullCurriculumAppList.forEach(item -> {
            // 学习总人数
            LambdaQueryWrapper<FtbCultivatePositionCourceLearning> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(FtbCultivatePositionCourceLearning::getState, List.of(1, 2));
            queryWrapper.eq(FtbCultivatePositionCourceLearning::getCourceId, item.getCourseId());
            queryWrapper.eq(FtbCultivatePositionCourceLearning::getEnabledMark, 0);
            item.setLearnTotalNumber(ftbCultivatePositionCourceLearningMapper.selectCount(queryWrapper));
            item.setIsOffline(0);
            // 是否为线下培训课程，0否，1是
            Integer trainingCourses = ftbCultivatePositionCourceLearningMapper.whetherToAddOfflineTrainingCourses(dto.getUserId(), item.getCourseId());
            if (trainingCourses > 0) {
                item.setIsOffline(1);
            }
        });
        onTheJobLearningCourse.setFullCurriculumAppList(fullCurriculumAppList);
        // bug编号12888，修复如果岗位学习中存在1，2, 3 课程时，如果1，2 课程已学习完，然后把3课程下架或者删除，无法触发考试与鉴定
        // 下层做业务幂等性，会存在重复调用的情况

        String userId = dto.getUserId();
        Integer compulsory = dto.getCompulsory();

        if (compulsory == 0) {
            // 任务必修课程
            LambdaQueryWrapper<FtbCultivatePositionCourse> courseWrper = new LambdaQueryWrapper<>();
            courseWrper.eq(FtbCultivatePositionCourse::getPostRankId, dto.getPostId());
            courseWrper.eq(FtbCultivatePositionCourse::getCompulsory, 0);
            courseWrper.eq(FtbCultivatePositionCourse::getEnabledMark, 0);
            List<FtbCultivatePositionCourse> ftbCultivatePositionCourses = ftbCultivatePositionCourseMapper.selectList(courseWrper);
            List<String> courseIds = ftbCultivatePositionCourses.stream()
                    .map(FtbCultivatePositionCourse::getCourseId)
                    .collect(Collectors.toList());
            if (CollUtil.isNotEmpty(courseIds)) {
                boolean isStartStudyCourse = checkCourseStudyStatus(userId, courseIds);
                if (isStartStudyCourse) {
                    int needStudyNum = 0;
                    LambdaQueryWrapper<FtbCultivateCourse> courseWraper = Wrappers.lambdaQuery();
                    courseWraper.in(FtbCultivateCourse::getId, courseIds);
                    courseWraper.eq(FtbCultivateCourse::getEnableMark, 0);
                    courseWraper.eq(FtbCultivateCourse::getIsGroundIng, 1);//上下架（0下架，1上架）
                    List<FtbCultivateCourse> ftbCultivateCourses = ftbCultivateCourseMapper.selectList(courseWraper);
                    if (CollUtil.isEmpty(ftbCultivateCourses)) {
                        needStudyNum = 0;
                    } else {
                        needStudyNum = ftbCultivateCourses.size();
                        courseIds = ftbCultivateCourses.stream()
                                .map(FtbCultivateCourse::getId)
                                .collect(Collectors.toList());
                    }
                    if (needStudyNum == 0 || hasTheCourseBeenCompleted(userId, courseIds)) {
                        SpringContext.getApplicationContext()
                                .publishEvent(new JnpfApplicationEvent<>(
                                        ExamIdentifyTriggerEventDTO.builder()
                                                .postId(dto.getPostId())
                                                .userId(dto.getUserId())
                                                .triggerEventType(TriggerEventBO.TriggerEventType.POST)
                                                .build()));
                    }
                }
            }
        }
        return onTheJobLearningCourse;
    }


    /**
     * 查询课是否开始学习
     *
     * @param userId    用户ID
     * @param courseIds 课程ID集合
     * @return boolean  false-未开始学习  true-开始学习
     */
    protected boolean checkCourseStudyStatus(String userId, List<String> courseIds) {
        LambdaQueryWrapper<FtbCultivatePositionCourceLearning> query = Wrappers.lambdaQuery();
        query.eq(FtbCultivatePositionCourceLearning::getUserId, userId);
        query.in(FtbCultivatePositionCourceLearning::getCourceId, courseIds);
        query.in(FtbCultivatePositionCourceLearning::getState, List.of("1"));//学习状态 1已学习，0未学习,2学习中
        query.eq(FtbCultivatePositionCourceLearning::getEnabledMark, 0);
        return ftbCultivatePositionCourceLearningMapper.selectCount(query) > 0;
    }

    /**
     * 查询是否完成了课程学习
     *
     * @param userId    用户id
     * @param courseIds 课程id
     * @return
     */
    private boolean hasTheCourseBeenCompleted(String userId, List<String> courseIds) {
        LambdaQueryWrapper<FtbCultivatePositionCourceLearning> query = Wrappers.lambdaQuery();
        query.eq(FtbCultivatePositionCourceLearning::getUserId, userId);
        query.in(FtbCultivatePositionCourceLearning::getCourceId, courseIds);
        query.in(FtbCultivatePositionCourceLearning::getState, List.of("0", "2"));
        query.eq(FtbCultivatePositionCourceLearning::getEnabledMark, 0);
        return ftbCultivatePositionCourceLearningMapper.selectCount(query) == 0;
    }

    private void isTheCourseInitialized(String userId, String postId) {
        List<String> courseIds = ftbCultivatePositionCourseMapper.getAnExistingCoursePostId(postId);
        if (CollectionUtils.isNotEmpty(courseIds)) {
            List<String> anExistingCourse = ftbCultivatePositionCourseMapper.getAnExistingCourse(courseIds, userId);
            List<String> courseUnExistingCourseIds = courseIds.stream()
                    .filter(a -> !anExistingCourse.contains(a))
                    .collect(Collectors.toList());
            checkCourse(courseUnExistingCourseIds, userId);
        }
    }

    private void checkCourse(List<String> courseIds, String userId) {
        if (CollectionUtils.isNotEmpty(courseIds)) {
            List<FtbCultivatePositionCourceLearning> ftbCultivatePositionCourceLearnings = new ArrayList<>();
            List<FtbCultivatePositionCourceChapterLearning> ftbCultivatePositionCourceChapterLearningList = new ArrayList<>();
            courseIds.forEach(courseId -> {
                // 课程
                FtbCultivatePositionCourceLearning ftbCultivatePositionCourceLearning = new FtbCultivatePositionCourceLearning();
                ftbCultivatePositionCourceLearning.setCourceId(courseId);
                ftbCultivatePositionCourceLearning.setLearnTime(0);
                ftbCultivatePositionCourceLearning.setUserId(userId);
                ftbCultivatePositionCourceLearning.setState(0);
                ftbCultivatePositionCourceLearnings.add(ftbCultivatePositionCourceLearning);
                // 章节
                LambdaQueryWrapper<FtbCultivateCourseChapter> ftbCultivateCourseChapterLambdaQueryWrapper = Wrappers.lambdaQuery();
                ftbCultivateCourseChapterLambdaQueryWrapper.eq(FtbCultivateCourseChapter::getEnableMark, 0);
                ftbCultivateCourseChapterLambdaQueryWrapper.eq(FtbCultivateCourseChapter::getCourseId, courseId);
                List<FtbCultivateCourseChapter> ftbCultivateCourseChapters = ftbCultivateCourseChapterMapper.selectList(ftbCultivateCourseChapterLambdaQueryWrapper);
                if (CollectionUtils.isNotEmpty(ftbCultivateCourseChapters)) {
                    ftbCultivateCourseChapters.forEach(ftbCultivateCourseChapter -> {
                        FtbCultivatePositionCourceChapterLearning ftbCultivatePositionCourceChapterLearning = new FtbCultivatePositionCourceChapterLearning();
                        ftbCultivatePositionCourceChapterLearning.setChapterId(ftbCultivateCourseChapter.getId());
                        ftbCultivatePositionCourceChapterLearning.setState(0);
                        ftbCultivatePositionCourceChapterLearning.setCourceId(courseId);
                        ftbCultivatePositionCourceChapterLearning.setChapterTime(0);
                        ftbCultivatePositionCourceChapterLearning.setUserId(userId);
                        ftbCultivatePositionCourceChapterLearningList.add(ftbCultivatePositionCourceChapterLearning);
                    });
                }
            });
            ftbCultivatePositionCourceLearningService.saveBatch(ftbCultivatePositionCourceLearnings);
            ftbCultivatePositionCourceChapterLearningService.saveBatch(ftbCultivatePositionCourceChapterLearningList);
        }
    }

    @Override
    public Page<FtbSubordinateLearningCoursesVO> subordinateLearningCourses(FtbCultivatePositionForAppNewDTO dto, Page<FtbSubordinateLearningCoursesVO> result) {
        result = ftbCultivatePositionCourceLearningMapper.subordinateLearningCourses(result, dto);
        return result;
    }


    @Override
    public PageListVO<IdentifyApplyInfoApiVo> queryIdentityTrainDataDetail(FtbCultivatePositionForAppNewDTO dto,
                                                                           CultivatePage page) {
        List<IdentifyApplyInfoApiVo> userIdentifyInfoApi = cultivateIdentifyApplyService.getUserIdentifyInfoWithUserId(dto.getUserId());
        return CultivatePage.paginate(userIdentifyInfoApi, page.coverCultivatePage());
    }

    @Override
    public PageListVO<IdentifyApplyInfoApiVo> subordinatePracticalAppraisal(FtbCultivatePositionForAppNewDTO dto, CultivatePage page) {
        Page<String> voPage = page.coverCultivatePage();
        String[] split = dto.getPostId().split(",");
        voPage = ftbCultivatePositionCourceLearningMapper.practicalAppraisalList(voPage, dto.getUserId(), List.of(split));
        PageListVO<IdentifyApplyInfoApiVo> result = new PageListVO<>();
        PaginationVO pagination = new PaginationVO();
        pagination.setTotal((int) voPage.getTotal());
        pagination.setPageSize(voPage.getSize());
        pagination.setCurrentPage(voPage.getCurrent());
        result.setPagination(pagination);
        if (CollUtil.isNotEmpty(voPage.getRecords())) {
            List<IdentifyApplyInfoApiVo> userIdentifyInfoApi = cultivateIdentifyApplyService.getUserIdentifyInfoApi(voPage.getRecords());
            result.setList(userIdentifyInfoApi);
        }
        return result;
    }

    @Override
    public Page<FtbSubordinateLearningCoursesVO> subordinateLearningCoursess(FtbCultivatePositionForAppNewDTO dto, Page<FtbSubordinateLearningCoursesVO> result) {
        result = ftbCultivatePositionCourceLearningMapper.subordinateLearningCoursess(result, dto, List.of(dto.getPostId().split(",")));
        return result;
    }

    @Override
    public FtbPopUpPromptVO popUpPrompt(String userId, String positionId) {
        FtbPopUpPromptVO ftbPopUpPromptVO = new FtbPopUpPromptVO();
        // 是否已经考试，根据岗位id+用户id查询
        CompleteExamVo completeExamVo = ftbCultivateExamUserService.checkIsCompleteExamForUserId(positionId, userId);
        if (Objects.nonNull(completeExamVo)) {
            if (completeExamVo.getIsHasExam()) {
                ftbPopUpPromptVO.setIsExam(1);
            }
            if (completeExamVo.getIsComplete()) {
                ftbPopUpPromptVO.setExamResults(1);
            }
        }
        // 实操鉴定，根据岗位id+用户id查询，解决换绑问题
        String identifyId = ftbCultivatePositionMapper.queryPracticalAppraisalByPostId(positionId, userId);
        if (StrUtil.isNotBlank(identifyId)) {
            ftbPopUpPromptVO.setIsIdentify(1);
            // 是否已经鉴定
            if (ftbCultivatePositionMapper.queryIdentificationResults(positionId, userId, identifyId) > 0) {
                ftbPopUpPromptVO.setIdentificationResults(1);
            }
        }
        // 岗位考试合格后才能进行鉴定,0否1是
        LambdaQueryWrapper<FtbCultivatePosition> ftbCultivatePositionLambdaQueryWrapper = Wrappers.lambdaQuery();
        ftbCultivatePositionLambdaQueryWrapper.select(FtbCultivatePosition::getQualified);
        ftbCultivatePositionLambdaQueryWrapper.eq(FtbCultivatePosition::getEnabledMark, 0);
        ftbCultivatePositionLambdaQueryWrapper.eq(FtbCultivatePosition::getPostId, positionId);
        ftbCultivatePositionLambdaQueryWrapper.eq(FtbCultivatePosition::getIsGrounding, 1);
        FtbCultivatePosition ftbCultivatePosition = ftbCultivatePositionMapper.selectOne(ftbCultivatePositionLambdaQueryWrapper);
        if (Objects.nonNull(ftbCultivatePosition)) {
            ftbPopUpPromptVO.setQualified(ftbCultivatePosition.getQualified());
        }
        // 岗位名称
//        PositionEntity positionEntity = positionApi.queryInfoById(positionId);
        PositionVO positionEntity = userApiV2Util.infoPosition(positionId, null);
        if(positionEntity != null) {
            ftbPopUpPromptVO.setPositionName(positionEntity.getFullName());
        }
        return ftbPopUpPromptVO;
    }

}

