package jnpf.cultivate.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.base.entity.SuperBaseEntity;
import jnpf.cultivate.mapper.FtbCultivateCourseMapper;
import jnpf.cultivate.service.*;
import jnpf.model.cultivate.dto.position.web.FtbCultivateAssociatedExamsCoursesDTO;
import jnpf.model.cultivate.dto.position.web.FtbCultivatePositionCopyDTO;
import jnpf.model.cultivate.dto.position.web.FtbCultivatePositionPassExaminationDTO;
import jnpf.model.cultivate.event.JnpfApplicationEvent;
import jnpf.model.cultivate.event.dto.course.PositionCourseEventDTO;
import jnpf.model.cultivate.po.course.FtbCultivateCourse;
import jnpf.model.cultivate.po.exam.FtbCultivateExam;
import jnpf.model.cultivate.po.position.FtbCultivatePosition;
import jnpf.model.cultivate.po.position.FtbCultivatePositionCourse;
import jnpf.model.cultivate.po.position.FtbCultivatePositionExam;
import jnpf.model.cultivate.po.position.FtbCultivatePositionExamIdentify;
import jnpf.model.cultivate.vo.position.web.FtbCopyRelatedPositionsVO;
import jnpf.model.cultivate.vo.position.web.FtbCultivatePositionCopyVO;
import jnpf.util.context.SpringContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class FtbCultivatePositionCopyServiceImpl implements FtbCultivatePositionCopyService {

    private final FtbCultivatePositionService ftbCultivatePositionService;
    private final FtbCultivatePositionCourseService ftbCultivatePositionCourseService;
    private final FtbCultivatePositionExamService ftbCultivatePositionExamService;
    private final FtbCultivatePositionExamIdentifyService ftbCultivatePositionExamIdentifyService;
    private final FtbCultivateCourseMapper ftbCultivateCourseMapper;
    private final FtbCultivateExamService ftbCultivateExamService;


    @Override
    @Transactional
    @SuppressWarnings("Duplicates")
    public FtbCultivatePositionCopyVO copyPosition(FtbCultivatePositionCopyDTO data) {
        FtbCultivatePositionCopyVO ftbCultivatePositionCopyVO = new FtbCultivatePositionCopyVO();
        // 旧岗位考试
        LambdaQueryWrapper<FtbCultivatePositionExam> positionExamLambdaQueryWrapper = Wrappers.lambdaQuery();
        positionExamLambdaQueryWrapper.select(FtbCultivatePositionExam::getExamId);
        positionExamLambdaQueryWrapper.eq(FtbCultivatePositionExam::getEnabledMark, 0);
        positionExamLambdaQueryWrapper.eq(FtbCultivatePositionExam::getPostRankId, data.getOldPositionId());
        positionExamLambdaQueryWrapper.last("limit 1");
        FtbCultivatePositionExam ftbCultivatePositionExam = ftbCultivatePositionExamService.getOne(positionExamLambdaQueryWrapper);
        FtbCultivateExam ftbCultivateExam = null;
        if (Objects.nonNull(ftbCultivatePositionExam)) {
            // 是否和新岗位有绑定关系
            ftbCultivateExam = ftbCultivateExamService.queryExamAndPositionRelation(ftbCultivatePositionExam.getExamId()
                    , data.getNewPositionId());
            // 无绑定关系
            if (ftbCultivateExam == null) {
                String examName = ftbCultivateCourseMapper.queryExamNameByExamId(ftbCultivatePositionExam.getExamId());
                FtbCopyRelatedPositionsVO ftbCopyRelatedPositionsVO = new FtbCopyRelatedPositionsVO();
                ftbCopyRelatedPositionsVO.setType(1);
                ftbCopyRelatedPositionsVO.setName(examName);
                ftbCopyRelatedPositionsVO.setFieldId(ftbCultivatePositionExam.getExamId());
                ftbCultivatePositionCopyVO.getCopyRelatedPositions().add(ftbCopyRelatedPositionsVO);
            }
        }
        // 旧岗位课程
        LambdaQueryWrapper<FtbCultivatePositionCourse> cultivatePositionCourseLambdaQueryWrapper = Wrappers.lambdaQuery();
        cultivatePositionCourseLambdaQueryWrapper.select(FtbCultivatePositionCourse::getCourseId);
        cultivatePositionCourseLambdaQueryWrapper.eq(FtbCultivatePositionCourse::getEnabledMark, 0);
        cultivatePositionCourseLambdaQueryWrapper.eq(FtbCultivatePositionCourse::getPostRankId, data.getOldPositionId());
        List<FtbCultivatePositionCourse> ftbCultivatePositionCourses = ftbCultivatePositionCourseService.list(cultivatePositionCourseLambdaQueryWrapper);
        // 是否和旧岗位有绑定关系，返回有关联关系的课程id
        List<String> existingCoursePositions = handleExistingExistingPositions(ftbCultivatePositionCopyVO, ftbCultivatePositionCourses, data.getNewPositionId());
        // 旧岗位实操鉴定
        LambdaQueryWrapper<FtbCultivatePositionExamIdentify> positionExamIdentifyQueryWrapper = Wrappers.lambdaQuery();
        positionExamIdentifyQueryWrapper.select(FtbCultivatePositionExamIdentify::getIdentifyId);
        positionExamIdentifyQueryWrapper.eq(FtbCultivatePositionExamIdentify::getEnabledMark, 0);
        positionExamIdentifyQueryWrapper.eq(FtbCultivatePositionExamIdentify::getPostRankId, data.getOldPositionId());
        positionExamIdentifyQueryWrapper.last("limit 1");
        FtbCultivatePositionExamIdentify ftbCultivatePositionExamIdentify = ftbCultivatePositionExamIdentifyService.getOne(positionExamIdentifyQueryWrapper);

        // 新岗位岗位学习数据插入
        FtbCultivatePosition ftbCultivatePosition = new FtbCultivatePosition();
        ftbCultivatePosition.setIsGrounding(0);
        ftbCultivatePosition.setPostId(data.getNewPositionId());
        ftbCultivatePositionService.save(ftbCultivatePosition);
        String postLearnId = ftbCultivatePosition.getId();

        // 新岗位实操鉴定插入
        if (Objects.nonNull(ftbCultivatePositionExamIdentify)) {
            FtbCultivatePositionExamIdentify newFtbCultivatePositionExamIdentify = new FtbCultivatePositionExamIdentify();
            newFtbCultivatePositionExamIdentify.setIdentifyId(ftbCultivatePositionExamIdentify.getIdentifyId());
            newFtbCultivatePositionExamIdentify.setEnabledMark(0);
            newFtbCultivatePositionExamIdentify.setPostLearnId(postLearnId);
            newFtbCultivatePositionExamIdentify.setPostRankId(data.getNewPositionId());
            ftbCultivatePositionExamIdentifyService.save(newFtbCultivatePositionExamIdentify);
        }

        // 新岗位考试插入
        if (Objects.nonNull(ftbCultivatePositionExam) && Objects.nonNull(ftbCultivateExam)) {
            FtbCultivatePositionExam newFtbCultivatePositionExam = new FtbCultivatePositionExam();
            newFtbCultivatePositionExam.setEnabledMark(0);
            newFtbCultivatePositionExam.setExamId(ftbCultivatePositionExam.getExamId());
            newFtbCultivatePositionExam.setPostLearnId(postLearnId);
            newFtbCultivatePositionExam.setPostRankId(data.getNewPositionId());
            ftbCultivatePositionExamService.save(newFtbCultivatePositionExam);
        }

        // 岗位学习课程
        List<FtbCultivatePositionCourse> newCultivatePositionCourses = existingCoursePositions.stream().map(a -> {
            FtbCultivatePositionCourse forgottenCoursePositionsCourse = new FtbCultivatePositionCourse();
            forgottenCoursePositionsCourse.setCourseId(a);
            forgottenCoursePositionsCourse.setEnabledMark(0);
            forgottenCoursePositionsCourse.setPostLearnId(postLearnId);
            forgottenCoursePositionsCourse.setPostRankId(data.getNewPositionId());
            return forgottenCoursePositionsCourse;
        }).collect(Collectors.toList());
        ftbCultivatePositionCourseService.saveBatch(newCultivatePositionCourses);
        // 岗位学习课程进度
        courseLearningProgressBinding(data.getNewPositionId(), existingCoursePositions);
        // 返回关联岗位数据
        ftbCultivatePositionCopyVO.getCopyRelatedPositions().forEach(a -> a.setPostLearnId(postLearnId));
        ftbCultivatePositionCopyVO.setPostLearnId(postLearnId);
        return ftbCultivatePositionCopyVO;
    }

    @Override
    @Transactional
    public void passingTheJobExaminationRevised(FtbCultivatePositionPassExaminationDTO data) {
        LambdaUpdateWrapper<FtbCultivatePosition> updateQueryWrapper = Wrappers.lambdaUpdate();
        updateQueryWrapper.eq(SuperBaseEntity.SuperIBaseEntity::getId, data.getPostLearnId());
        updateQueryWrapper.set(FtbCultivatePosition::getQualified, data.getQualified());
        ftbCultivatePositionService.update(new FtbCultivatePosition(), updateQueryWrapper);
    }

    @Override
    @Transactional
    public void associatedExamsAndCourses(FtbCultivateAssociatedExamsCoursesDTO data) {
        // 类型,0课程，1考试
        if (data.getType() == 0) {
            // 岗位学习课程
            FtbCultivatePositionCourse forgottenCoursePositionsCourse = new FtbCultivatePositionCourse();
            forgottenCoursePositionsCourse.setCourseId(data.getFieldId());
            forgottenCoursePositionsCourse.setEnabledMark(0);
            forgottenCoursePositionsCourse.setPostLearnId(data.getPostLearnId());
            forgottenCoursePositionsCourse.setPostRankId(data.getNewPostionId());
            ftbCultivatePositionCourseService.save(forgottenCoursePositionsCourse);
            // 课程修改增加学习岗位
            FtbCultivateCourse ftbCultivateCourse = ftbCultivateCourseMapper.selectById(data.getFieldId());
            LambdaUpdateWrapper<FtbCultivateCourse> courseLambdaUpdateWrapper = Wrappers.lambdaUpdate();
            courseLambdaUpdateWrapper.eq(SuperBaseEntity.SuperIBaseEntity::getId, data.getFieldId());
            courseLambdaUpdateWrapper.set(FtbCultivateCourse::getLearnJob,
                    doHandleLearnJob(ftbCultivateCourse.getLearnJob(), data.getNewPostionId()));
            ftbCultivateCourseMapper.update(new FtbCultivateCourse(), courseLambdaUpdateWrapper);
            courseLearningProgressBinding(data.getNewPostionId(), List.of(data.getFieldId()));
        } else {
            // 岗位考试
            FtbCultivatePositionExam ftbCultivatePositionExam = new FtbCultivatePositionExam();
            ftbCultivatePositionExam.setEnabledMark(0);
            ftbCultivatePositionExam.setExamId(data.getFieldId());
            ftbCultivatePositionExam.setPostLearnId(data.getPostLearnId());
            ftbCultivatePositionExam.setPostRankId(data.getNewPostionId());
            ftbCultivatePositionExamService.save(ftbCultivatePositionExam);
            // 考试与岗位进行绑定
            Boolean aBoolean = ftbCultivateExamService.bindExamAndPositionRelation(data.getFieldId(), data.getNewPostionId());
            if (!aBoolean) {
                throw new RuntimeException("考试与岗位绑定失败");
            }
        }

    }

    private void courseLearningProgressBinding(String postId, List<String> courseIds) {
        // 岗位课程事件
        SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(
                PositionCourseEventDTO.builder()
                        .courseIds(courseIds)
                        .postIds(List.of(postId))
                        .eventType(PositionCourseEventDTO.EventType.POST)
                        .whetherToChange(false)
                        .build()));
    }

    @Override
    public List<String> learningFromExistingPositions() {
        LambdaQueryWrapper<FtbCultivatePosition> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(FtbCultivatePosition::getPostId);
        queryWrapper.eq(FtbCultivatePosition::getEnabledMark, 0);
        List<FtbCultivatePosition> ftbCultivatePositions = ftbCultivatePositionService.list(queryWrapper);
        return ftbCultivatePositions.stream().map(FtbCultivatePosition::getPostId).collect(Collectors.toList());
    }

    private List<String> handleExistingExistingPositions(FtbCultivatePositionCopyVO ftbCultivatePositionCopyVO,
                                                         List<FtbCultivatePositionCourse> ftbCultivatePositionCourses,
                                                         String postId) {
        if (CollUtil.isEmpty(ftbCultivatePositionCourses)) {
            return Collections.emptyList();
        }
        List<String> courseIds = ftbCultivatePositionCourses.stream()
                .map(FtbCultivatePositionCourse::getCourseId)
                .collect(Collectors.toList());
        LambdaQueryWrapper<FtbCultivateCourse> courseLambdaQueryWrapper = Wrappers.lambdaQuery();
        courseLambdaQueryWrapper.select(
                SuperBaseEntity.SuperIBaseEntity::getId
                , FtbCultivateCourse::getLearnJob
                , FtbCultivateCourse::getName);
        courseLambdaQueryWrapper.eq(FtbCultivateCourse::getEnableMark, 0);
        courseLambdaQueryWrapper.eq(FtbCultivateCourse::getLabel, 2);
        courseLambdaQueryWrapper.in(SuperBaseEntity.SuperIBaseEntity::getId, courseIds);
        List<FtbCultivateCourse> ftbCultivateCourses = ftbCultivateCourseMapper.selectList(courseLambdaQueryWrapper);
        List<String> result = new ArrayList<>();
        for (FtbCultivateCourse ftbCultivateCourse : ftbCultivateCourses) {
            // 是否课程学习岗位包含新岗位
            String learnJob = ftbCultivateCourse.getLearnJob();
            if (learnJob.contains(postId)) {
                result.add(ftbCultivateCourse.getId());
            } else {
                FtbCopyRelatedPositionsVO ftbCopyRelatedPositionsVO = new FtbCopyRelatedPositionsVO();
                ftbCopyRelatedPositionsVO.setType(0);
                ftbCopyRelatedPositionsVO.setName(ftbCultivateCourse.getName());
                ftbCopyRelatedPositionsVO.setFieldId(ftbCultivateCourse.getId());
                ftbCultivatePositionCopyVO.getCopyRelatedPositions().add(ftbCopyRelatedPositionsVO);
            }
        }
        return result;
    }

    private String doHandleLearnJob(String learJob, String postId) {
        if (StrUtil.isBlank(learJob)) {
            return postId;
        }
        return learJob + StringPool.COMMA + postId;
    }

}
