package com.ruoyi.project.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.math.BigDecimal;
import java.util.*;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.business.domain.dto.TtTrainDto;
import com.ruoyi.project.business.domain.dto.TtTrainSearchDto;
import com.ruoyi.project.business.domain.train.*;
import com.ruoyi.project.business.domain.vo.train.*;
import com.ruoyi.project.business.enums.train.TrainAssessCompleteFlagEnum;
import com.ruoyi.project.business.enums.train.TrainAssessFlagEnum;
import com.ruoyi.project.business.enums.train.TrainCompleteFlagEnum;
import com.ruoyi.project.business.mapper.*;
import com.ruoyi.project.business.service.ITtTrainService;
import com.ruoyi.project.business.enums.train.TrainStatusEnum;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.ISysUserService;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 培训考核Service业务层处理
 *
 * @author ruoyi
 * @date 2024-06-18
 */
@Service
@RequiredArgsConstructor
public class TtTrainServiceImpl extends ServiceImpl<TtTrainMapper, TtTrain> implements ITtTrainService {
    @Autowired
    private TtTrainMapper ttTrainMapper;
    @Autowired
    private TtTrainFileMapper ttTrainFileMapper;
    @Autowired
    private TtTrainTargetMapper ttTrainTargetMapper;
    @Autowired
    private TtTestPaperMapper ttTestPaperMapper;
    @Autowired
    private TtTestPaperDetailMapper ttTestPaperDetailMapper;
    @Autowired
    private ISysUserService sysUserService;

    /**
     * 查询培训考核
     *
     * @param id 培训考核主键
     * @return 培训考核
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TtTrainVo selectTtTrainById(Long id) {
        TtTrainVo ttTrainVo = new TtTrainVo();

        // 根据id获取培训主数据
        TtTrain ttTrain = baseMapper.selectTtTrainById(id);

        // 获取培训对象
        TtTrainTarget ttTrainTarget = new TtTrainTarget();
        ttTrainTarget.setTrainId(id);
        List<TtTrainTargetVo> ttTrainTargets = ttTrainTargetMapper.selectTtTrainTargetList(ttTrainTarget);
        List<Long> userIdList = new ArrayList<>();
        for (TtTrainTargetVo trainTarget : ttTrainTargets) {
            userIdList.add(trainTarget.getTargetPersonId());
        }

        SysUser sysUser = new SysUser();
        sysUser.setUserIdList(userIdList);
        List<SysUser> sysUsers = sysUserService.selectUserList(sysUser);
        // 设置 对象的角色
        for (SysUser user : sysUsers) {
            for (TtTrainTargetVo trainTarget : ttTrainTargets) {
                if (user.getUserId().equals(trainTarget.getTargetPersonId())) {
                    trainTarget.setRoleNames(user.getRoleNames());
                }
            }
        }

        // 获取该培训的附件列表
        TtTrainFile ttTrainFile = new TtTrainFile();
        ttTrainFile.setTrainId(id);
        List<TtTrainFile> ttTrainFiles = ttTrainFileMapper.selectTtTrainFileList(ttTrainFile);

        // 获取该培训的试卷
        QueryWrapper<TtTestPaper> testQueryWrapper = new QueryWrapper<>();
        testQueryWrapper.eq("train_id", id);
        testQueryWrapper.eq("del_flag", 0);
        List<TtTestPaper> ttTestPapers = ttTestPaperMapper.selectList(testQueryWrapper);
        BeanUtils.copyProperties(ttTrain, ttTrainVo);

        // 获取该培训试卷的试题详细
        if (CollectionUtils.isNotEmpty(ttTestPapers)) {
            TtTestPaperDetail ttTestPaperDetail = new TtTestPaperDetail();
            ttTestPaperDetail.setTestPaperId(ttTestPapers.get(0).getId());
            List<TtTestPaperDetailVo> ttTestPaperDetails = ttTestPaperDetailMapper.selectTestPaperDetailList(ttTestPaperDetail);
            // 创建一个Comparator来比较sortIndex字段
            Comparator<TtTestPaperDetailVo> comparator = Comparator.comparingLong(TtTestPaperDetailVo::getSortIndex);

            // 使用Collections.sort()方法进行排序
            ttTestPaperDetails.sort(comparator);
            ttTrainVo.setTtTestPaperDetailList(ttTestPaperDetails);
        }
        ttTrainVo.setTtTrainTargetList(ttTrainTargets);
        ttTrainVo.setTtTrainFileList(ttTrainFiles);
        ttTrainVo.setTtTestPaperList(ttTestPapers);
        return ttTrainVo;
    }

    /**
     * 查询培训考核列表
     *
     * @param ttTrainSearchDto 培训考核
     * @return 培训考核
     */
    @Override
    public List<TtTrainVo> selectTtTrainList(TtTrainSearchDto ttTrainSearchDto) {
        // mysql 中认为 “   ” == 0，防止搜索“   ”时能查到0的结果
        if (ttTrainSearchDto.getAssessmentCompletionRate() != null){
            // 若字符串trim为空，则设置为-1
            if(ttTrainSearchDto.getAssessmentCompletionRate().trim().isEmpty()){
                ttTrainSearchDto.setAssessmentCompletionRate("-1");
            }
        }
        if (ttTrainSearchDto.getTrainingCompletionRate() != null){
            // 若字符串trim为空，则设置为-1
            if(ttTrainSearchDto.getTrainingCompletionRate().trim().isEmpty()){
                ttTrainSearchDto.setTrainingCompletionRate("-1");
            }
        }
        return baseMapper.selectTtTrainList(ttTrainSearchDto);
    }

    /**
     * 新增培训
     *
     * @param ttTrainDto 【新增培训信息】
     * @return 结果
     */
    @Override
    @Transactional
    public int insertTtTrain(TtTrainDto ttTrainDto) {
        // 获取登录人
        Long loginUserId = SecurityUtils.getLoginUser().getUserId();
        TtTrain ttTrain = new TtTrain();
        BeanUtils.copyProperties(ttTrainDto, ttTrain);
        // 设置培训状态(未开始)
        Date currentDate = DateUtils.getNowDate();

        // 根据培训设定的 开始和结束时间，设置培训状态
        if (currentDate.after(ttTrain.getStartDate()) && currentDate.before(ttTrain.getEndDate())) {
            ttTrain.setTrainStatus(TrainStatusEnum.STARTED.getCode());
        } else if (currentDate.after(ttTrain.getEndDate())) {
            ttTrain.setTrainStatus(TrainStatusEnum.ENDED.getCode());
        } else ttTrain.setTrainStatus(TrainStatusEnum.NOT_START.getCode());

        ttTrain.setDelFlag("0");
        // 设置创建者创建时间，更新这更新时间
        ttTrain.setCreateBy(loginUserId.toString());
        ttTrain.setCreateTime(DateUtils.getNowDate());
        ttTrain.setUpdateBy(loginUserId.toString());
        ttTrain.setUpdateTime(DateUtils.getNowDate());
        // 一、插入培训主数据
        int result = baseMapper.insertTtTrain(ttTrain);

        List<TtTrainFile> ttTrainFileList = new ArrayList<>();
        List<TtTrainTarget> ttTrainTargetList = new ArrayList<>();
        // 二、培训与培训对象关联表批量新增
        if (ttTrainDto.getUserIdList() != null && ttTrainDto.getUserIdList().length > 0) {
            for (Long userId : ttTrainDto.getUserIdList()) {
                TtTrainTarget ttTrainTarget = new TtTrainTarget();
                // 培训对象id
                ttTrainTarget.setTargetPersonId(userId);
                // 培训id
                ttTrainTarget.setTrainId(ttTrain.getId());
                ttTrainTarget.setTrainCompleteFlag(TrainCompleteFlagEnum.NOT_FINISHED.getCode());
                ttTrainTarget.setAssessCompleteFlag(TrainAssessCompleteFlagEnum.ASSESS_NOT_COMPLETE.getCode());
                ttTrainTarget.setDelFlag("0");
                // 设置创建者创建时间，更新者更新时间
                ttTrainTarget.setCreateBy(loginUserId.toString());
                ttTrainTarget.setCreateTime(DateUtils.getNowDate());
                ttTrainTarget.setUpdateBy(loginUserId.toString());
                ttTrainTarget.setUpdateTime(DateUtils.getNowDate());
                ttTrainTargetList.add(ttTrainTarget);
            }
            // 批量插入培训对象信息
            ttTrainTargetMapper.insertTtTrainTargetBatch(ttTrainTargetList);
        }

        // 三、培训与附件关联表批量新增
        if (ttTrainDto.getFileIdList() != null && ttTrainDto.getFileIdList().length > 0) {
            for (Long fileId : ttTrainDto.getFileIdList()) {
                TtTrainFile ttTrainFile = new TtTrainFile();
                // 附件id
                ttTrainFile.setFileId(fileId);
                // 培训id
                ttTrainFile.setTrainId(ttTrain.getId());
                ttTrainFileList.add(ttTrainFile);
                ttTrainFile.setDelFlag("0");
                // 设置创建者创建时间，更新这更新时间
                ttTrainFile.setCreateBy(loginUserId.toString());
                ttTrainFile.setCreateTime(DateUtils.getNowDate());
                ttTrainFile.setUpdateBy(loginUserId.toString());
                ttTrainFile.setUpdateTime(DateUtils.getNowDate());
            }
            // 批量插入附件信息
            ttTrainFileMapper.insertTtTrainFileBatch(ttTrainFileList);
        }
        // 如何不考核，则不需要插入试卷
        if (Objects.equals(ttTrainDto.getAssessFlag(), TrainAssessFlagEnum.NO_ASSESS.getCode())) {
            return result;
        }

        // 四、插入试卷
        TtTestPaper ttTestPaper = new TtTestPaper();
        // 设置绑定的培训id
        ttTestPaper.setTrainId(ttTrain.getId());
        // 试卷名
        ttTestPaper.setTestPaperName(ttTrainDto.getTestPaperName());
        // 通过分数
        ttTestPaper.setPassScore(ttTrainDto.getPassScore());
        // 考试说明
        ttTestPaper.setRemark(ttTrainDto.getTestRemark());
        ttTestPaper.setDelFlag("0");
        // 设置创建者创建时间，更新这更新时间
        ttTestPaper.setCreateBy(loginUserId.toString());
        ttTestPaper.setCreateTime(DateUtils.getNowDate());
        ttTestPaper.setUpdateBy(loginUserId.toString());
        ttTestPaper.setUpdateTime(DateUtils.getNowDate());
        ttTestPaperMapper.insert(ttTestPaper);
        // 五、批量插入试卷详细
        List<TtTestPaperDetail> ttTestPaperDetailList = new ArrayList<>();
        Long index = 1L;
        for (TtQuestionDatabase item : ttTrainDto.getQuestionList()) {
            TtTestPaperDetail ttTestDetail = new TtTestPaperDetail();
            ttTestDetail.setQuestionId(item.getId());
            // 设置排序
            ttTestDetail.setSortIndex(index);
            index++;
            ttTestDetail.setTestPaperId(ttTestPaper.getId());
            ttTestDetail.setQuestionScore(BigDecimal.valueOf(item.getScore()));
            ttTestDetail.setDelFlag("0");
            // 设置创建者创建时间，更新这更新时间
            ttTestDetail.setCreateBy(loginUserId.toString());
            ttTestDetail.setCreateTime(DateUtils.getNowDate());
            ttTestDetail.setUpdateBy(loginUserId.toString());
            ttTestDetail.setUpdateTime(DateUtils.getNowDate());
            ttTestPaperDetailList.add(ttTestDetail);
        }

        return ttTestPaperDetailMapper.batchInsert(ttTestPaperDetailList);
    }

    /**
     * 修改培训考核
     *
     * @param ttTrainDto 培训考核
     * @return 结果
     */
    @Override
    @Transactional
    public int updateTtTrain(TtTrainDto ttTrainDto) {
        // 获取登录人
        Long loginUserId = SecurityUtils.getLoginUser().getUserId();
        TtTrain ttTrain = new TtTrain();
        BeanUtils.copyProperties(ttTrainDto, ttTrain);
        ttTrain.setUpdateTime(DateUtils.getNowDate());
        ttTrain.setUpdateBy(loginUserId.toString());
        // 根据培训设定的 开始和结束时间，设置培训状态
        Date currentDate = DateUtils.getNowDate();
        if (currentDate.after(ttTrain.getStartDate()) && currentDate.before(ttTrain.getEndDate())) {
            ttTrain.setTrainStatus(TrainStatusEnum.STARTED.getCode());
        } else if (currentDate.after(ttTrain.getEndDate())) {
            ttTrain.setTrainStatus(TrainStatusEnum.ENDED.getCode());
        } else ttTrain.setTrainStatus(TrainStatusEnum.NOT_START.getCode());
        int result = baseMapper.updateTtTrain(ttTrain);

        Long[] ids = {ttTrainDto.getId()};

        /*3. 编辑情况：
            1. 之前有考核 && 本次编辑有考核     更新试卷，删除旧题目，新增新题目
            2. 之前有考核 && 本次编辑没有考核   删除之前的试卷，并且删除之前的题目
            3. 之前没有考核 && 本次编辑有考核   新增试卷，新增新题目
            4. 之前没有考核 && 本次编辑没有考核  不需要修改*/

        List<Long> testIds = deleteTtTrainByIdToEdit(ids, ttTrainDto);

        insertTtTrainToEdit(ttTrainDto, testIds);

        return result;
    }

    /**
     * 批量删除培训考核
     *
     * @param ids 需要删除的培训考核主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteTtTrainByIds(Long[] ids) {
        // 删除培训主表
        int result = ttTrainMapper.deleteTtTrainByIds(ids);
        // 一、根据培训id 删除培训对象列表
        ttTrainTargetMapper.deleteTtTrainTargetByTrainIds(ids);

        // 二、根据培训id删除 附件
        ttTrainFileMapper.deleteTtTrainFileByTrainIds(ids);

        // 获取该培训对应的试卷id
        QueryWrapper<TtTestPaper> qw = new QueryWrapper<>();
        List<Long> idList = Arrays.asList(ids);
        qw.in("train_id", idList);
        qw.ne("del_flag", "1");
        List<TtTestPaper> ttTestPapers = ttTestPaperMapper.selectList(qw);
        if (CollectionUtils.isNotEmpty(ttTestPapers)) {
            List<Long> ttTestPaperIds = ttTestPapers.stream()  // ttTestPapers 是一个 List<TtTestPaper>
                    .map(TtTestPaper::getId)  // 使用map映射每个TtTestPaper对象的id
                    .collect(Collectors.toList());
            // 三、根据培训id 删除试卷
            QueryWrapper<TtTestPaper> testQueryWrapper = new QueryWrapper<>();
            // 构造更新条件
            testQueryWrapper.in("train_id", ttTestPaperIds);
            // 设置更新字段
            TtTestPaper ttTestPaper = new TtTestPaper();
            ttTestPaper.setDelFlag("1");
            ttTestPaperMapper.update(ttTestPaper, testQueryWrapper);

            // 四、根据试卷id 删除题目
            QueryWrapper<TtTestPaperDetail> ttTestPaperDetailQueryWrapper = new QueryWrapper<>();
            // 构造更新条件
            ttTestPaperDetailQueryWrapper.in("test_paper_id", ttTestPaperIds);
            // 设置更新字段
            TtTestPaperDetail ttTestPaperDetail = new TtTestPaperDetail();
            ttTestPaperDetail.setDelFlag("1");
            return ttTestPaperDetailMapper.update(ttTestPaperDetail, ttTestPaperDetailQueryWrapper);
        }
        return result;
    }

    /**
     * 根据主数据id 删除该主数据的子表数据，用于编辑
     * （
     * 情况1：更新试卷，删除旧题目   情况2：删除之前的试卷，并且删除之前的题目
     * 情况3：无操作  情况4：无操作
     * ）
     *
     * @param ids,ttTrainDto 需要删除的培训考核主键,相关数据
     * @return List<Long> 试卷id
     */
    private List<Long> deleteTtTrainByIdToEdit(Long[] ids, TtTrainDto ttTrainDto) {
        List<Long> idList = Arrays.asList(ids);
        // 一、根据培训id 删除培训对象列表
        QueryWrapper<TtTrainTarget> ttTrainTargetQueryWrapper = new QueryWrapper<>();
        ttTrainTargetQueryWrapper.in("train_id", idList);
        ttTrainTargetMapper.delete(ttTrainTargetQueryWrapper);

        // 二、根据培训id删除 附件
        QueryWrapper<TtTrainFile> ttTrainFileQueryWrapper = new QueryWrapper<>();
        ttTrainFileQueryWrapper.in("train_id", idList);
        ttTrainFileMapper.delete(ttTrainFileQueryWrapper);

        // 获取该培训对应的试卷id
        QueryWrapper<TtTestPaper> qw = new QueryWrapper<>();
        // 培训id列表

        qw.in("train_id", idList);
        qw.ne("del_flag", "1");
        List<TtTestPaper> ttTestPapers = ttTestPaperMapper.selectList(qw);
        // 之前有考核
        if (CollectionUtils.isNotEmpty(ttTestPapers)) {
            List<Long> ttTestPaperIds = ttTestPapers.stream()
                    .map(TtTestPaper::getId)
                    .collect(Collectors.toList());

            // 情况1：之前有考核，本次编辑也有考核  => 更新试卷，删除旧题目
            if (ttTrainDto.getAssessFlag().equals(TrainAssessFlagEnum.ASSESS.getCode())) {
                // 三、根据培训id 更新试卷
                QueryWrapper<TtTestPaper> testQueryWrapper = new QueryWrapper<>();
                // 构造更新条件
                testQueryWrapper.in("train_id", idList);
                // 设置更新字段
                TtTestPaper ttTestPaper = new TtTestPaper();
                ttTestPaper.setTestPaperName(ttTrainDto.getTestPaperName());
                ttTestPaper.setPassScore(ttTrainDto.getPassScore());
                ttTestPaper.setRemark(ttTrainDto.getTestRemark());
                ttTestPaperMapper.update(ttTestPaper, testQueryWrapper);
                // 四、根据试卷id 删除题目
                QueryWrapper<TtTestPaperDetail> ttTestPaperDetailQueryWrapper = new QueryWrapper<>();
                // 构造更新条件
                ttTestPaperDetailQueryWrapper.in("test_paper_id", ttTestPaperIds);
                ttTestPaperDetailMapper.delete(ttTestPaperDetailQueryWrapper);
                return ttTestPaperIds;
            }
            // 情况2 之前有考核 && 本次编辑没有考核  => 删除之前的试卷，并且删除之前的题目
            if (ttTrainDto.getAssessFlag().equals(TrainAssessFlagEnum.NO_ASSESS.getCode())) {
                // 三、根据培训id 删除试卷
                QueryWrapper<TtTestPaper> testQueryWrapper = new QueryWrapper<>();
                // 构造更新条件
                testQueryWrapper.in("train_id", idList);
                // 设置更新字段
                TtTestPaper ttTestPaper = new TtTestPaper();
                ttTestPaper.setDelFlag("1");
                ttTestPaperMapper.update(ttTestPaper, testQueryWrapper);
                // 四、根据试卷id 删除题目
                QueryWrapper<TtTestPaperDetail> ttTestPaperDetailQueryWrapper = new QueryWrapper<>();
                // 构造更新条件
                ttTestPaperDetailQueryWrapper.in("test_paper_id", ttTestPaperIds);
                ttTestPaperDetailMapper.delete(ttTestPaperDetailQueryWrapper);
                return ttTestPaperIds;
            }
        }

        // 若之前沒有考核，返回空列表（没有试卷id）
        return new ArrayList<>();
    }

    /**
     * 新增培训
     * 方法2：
     * 重新新增子数据 （
     * 情况1：新增新题目 情况2：无操作
     * 情况3：新增试卷，新增新题目 情况4：无操作
     * ）
     *
     * @param ttTrainDto 【新增培训信息】
     */
    private void insertTtTrainToEdit(TtTrainDto ttTrainDto, List<Long> testIds) {
        // 获取登录人
        Long loginUserId = SecurityUtils.getLoginUser().getUserId();

        List<TtTrainFile> ttTrainFileList = new ArrayList<>();
        List<TtTrainTarget> ttTrainTargetList = new ArrayList<>();
        // 培训与培训对象关联表批量新增
        if (ArrayUtils.isNotEmpty(ttTrainDto.getUserIdList())) {
            for (Long userId : ttTrainDto.getUserIdList()) {
                TtTrainTarget ttTrainTarget = new TtTrainTarget();
                // 培训对象id
                ttTrainTarget.setTargetPersonId(userId);
                // 培训id
                ttTrainTarget.setTrainId(ttTrainDto.getId());
                // 0：未完成 1：完成
                ttTrainTarget.setTrainCompleteFlag(TrainCompleteFlagEnum.NOT_FINISHED.getCode());
                ttTrainTarget.setAssessCompleteFlag(TrainAssessCompleteFlagEnum.ASSESS_NOT_COMPLETE.getCode());
                ttTrainTarget.setDelFlag("0");
                // 设置创建者创建时间，更新者更新时间
                ttTrainTarget.setCreateBy(loginUserId.toString());
                ttTrainTarget.setCreateTime(DateUtils.getNowDate());
                ttTrainTarget.setUpdateBy(loginUserId.toString());
                ttTrainTarget.setUpdateTime(DateUtils.getNowDate());
                ttTrainTargetList.add(ttTrainTarget);
            }
            // 批量插入培训对象信息
            ttTrainTargetMapper.insertTtTrainTargetBatch(ttTrainTargetList);
        }
        // 培训与附件关联表批量新增
        if (ArrayUtils.isNotEmpty(ttTrainDto.getFileIdList())) {
            for (Long fileId : ttTrainDto.getFileIdList()) {
                TtTrainFile ttTrainFile = new TtTrainFile();
                // 附件id
                ttTrainFile.setFileId(fileId);
                // 培训id
                ttTrainFile.setTrainId(ttTrainDto.getId());
                ttTrainFileList.add(ttTrainFile);
                ttTrainFile.setDelFlag("0");
                // 设置创建者创建时间，更新这更新时间
                ttTrainFile.setCreateBy(loginUserId.toString());
                ttTrainFile.setCreateTime(DateUtils.getNowDate());
                ttTrainFile.setUpdateBy(loginUserId.toString());
                ttTrainFile.setUpdateTime(DateUtils.getNowDate());
            }
            // 批量插入附件信息
            ttTrainFileMapper.insertTtTrainFileBatch(ttTrainFileList);
        }

        // s.getAssessFlag() == 0 不考核，则不需要插入试卷
        if (ttTrainDto.getAssessFlag().equals(TrainAssessFlagEnum.NO_ASSESS.getCode())) {
            return;
        }
        // 情况1：之前有考核 && 本次编辑有考核  新增新题目
        if (CollectionUtils.isNotEmpty(testIds) && ttTrainDto.getAssessFlag().equals(TrainAssessFlagEnum.ASSESS.getCode())) {
            // 批量插入试卷详细
            List<TtTestPaperDetail> ttTestPaperDetailList = new ArrayList<>();
            Long index = 1L;
            for (TtQuestionDatabase item : ttTrainDto.getQuestionList()) {
                TtTestPaperDetail ttTestDetail = new TtTestPaperDetail();
                ttTestDetail.setQuestionId(item.getId());
                // 设置排序
                ttTestDetail.setSortIndex(index);
                index++;
                ttTestDetail.setTestPaperId(testIds.get(0));
                ttTestDetail.setQuestionScore(BigDecimal.valueOf(item.getScore()));
                ttTestDetail.setDelFlag("0");
                // 设置创建者创建时间，更新这更新时间
                ttTestDetail.setCreateBy(loginUserId.toString());
                ttTestDetail.setCreateTime(DateUtils.getNowDate());
                ttTestDetail.setUpdateBy(loginUserId.toString());
                ttTestDetail.setUpdateTime(DateUtils.getNowDate());
                ttTestPaperDetailList.add(ttTestDetail);
            }
            ttTestPaperDetailMapper.batchInsert(ttTestPaperDetailList);
        }
        // 情况2：之前有考核 && 本次编辑没有考核  无操作
        // 情况3：之前没有考核 && 本次编辑有考核  新增试卷，新增新题目
        if (CollectionUtils.isEmpty(testIds) && ttTrainDto.getAssessFlag().equals(TrainAssessFlagEnum.ASSESS.getCode())) {
            // 五、插入试卷
            TtTestPaper ttTestPaper = new TtTestPaper();
            // 设置绑定的培训id
            ttTestPaper.setTrainId(ttTrainDto.getId());
            // 试卷名
            ttTestPaper.setTestPaperName(ttTrainDto.getTestPaperName());
            // 通过分数
            ttTestPaper.setPassScore(ttTrainDto.getPassScore());
            // 考试说明
            ttTestPaper.setRemark(ttTrainDto.getTestRemark());
            ttTestPaper.setDelFlag("0");
            // 设置创建者创建时间，更新这更新时间
            ttTestPaper.setCreateBy(loginUserId.toString());
            ttTestPaper.setCreateTime(DateUtils.getNowDate());
            ttTestPaper.setUpdateBy(loginUserId.toString());
            ttTestPaper.setUpdateTime(DateUtils.getNowDate());
            ttTestPaperMapper.insert(ttTestPaper);
            // 六、批量插入试卷详细
            List<TtTestPaperDetail> ttTestPaperDetailList = new ArrayList<>();
            Long index = 1L;
            for (TtQuestionDatabase item : ttTrainDto.getQuestionList()) {
                TtTestPaperDetail ttTestDetail = new TtTestPaperDetail();
                ttTestDetail.setQuestionId(item.getId());
                // 设置排序
                ttTestDetail.setSortIndex(index);
                index++;
                ttTestDetail.setTestPaperId(ttTestPaper.getId());
                ttTestDetail.setQuestionScore(BigDecimal.valueOf(item.getScore()));
                ttTestDetail.setDelFlag("0");
                // 设置创建者创建时间，更新这更新时间
                ttTestDetail.setCreateBy(loginUserId.toString());
                ttTestDetail.setCreateTime(DateUtils.getNowDate());
                ttTestDetail.setUpdateBy(loginUserId.toString());
                ttTestDetail.setUpdateTime(DateUtils.getNowDate());
                ttTestPaperDetailList.add(ttTestDetail);
            }
            ttTestPaperDetailMapper.batchInsert(ttTestPaperDetailList);
        }
        // 情况4：之前没有考核 && 本次编辑没有考核  无操作


    }

    /**
     * 删除培训考核信息
     *
     * @param id 培训考核主键
     * @return 结果
     */
    @Override
    public int deleteTtTrainById(Long id) {
        return baseMapper.deleteTtTrainById(id);
    }

    @Override
    public List<TrainParticipantRes> selectParticipantTrainListCur(TrainParticipantReq req) {
        req.setUserId(SecurityUtils.getLoginUser().getUserId());
        return baseMapper.selectParticipantTrainListUserId(req);
    }

    @Override
    public TtTestPaperVo selectTestPaperDetail(TtTrainDto ttTrainDto) {

        // 1. 根据试卷id 获取试卷详细
        QueryWrapper<TtTestPaper> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("train_id", ttTrainDto.getId());
        queryWrapper.eq("del_flag", "0");
        TtTestPaper ttTestPaper = ttTestPaperMapper.selectOne(queryWrapper);
        TtTestPaperVo result = new TtTestPaperVo();
        BeanUtils.copyProperties(ttTestPaper, result);

        // 2. 根据试卷id 获取试题详细
        TtTestPaperDetail ttTestPaperDetail = new TtTestPaperDetail();
        ttTestPaperDetail.setTestPaperId(ttTestPaper.getId());
        result.setTtTestPaperDetailVoList(ttTestPaperDetailMapper.selectTestPaperDetailList(ttTestPaperDetail));

        return result;
    }

    @Override
    public TtTestPaperVo selectTestResult(TtTrainDto ttTrainDto) {
        // 1. 根据试卷id 获取试卷详细
        QueryWrapper<TtTestPaper> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("train_id", ttTrainDto.getId());
        queryWrapper.eq("del_flag", "0");
        TtTestPaper ttTestPaper = ttTestPaperMapper.selectOne(queryWrapper);
        TtTestPaperVo result = new TtTestPaperVo();
        BeanUtils.copyProperties(ttTestPaper, result);

        // 2. 根据试卷id 获取试题详细及我的答案，和试题设定分数
        TtTestPaperDetail ttTestPaperDetail = new TtTestPaperDetail();
        ttTestPaperDetail.setTestPaperId(ttTestPaper.getId());
        ttTestPaperDetail.setLoginUserId(SecurityUtils.getLoginUser().getUserId());
        result.setTtTestPaperDetailVoList(ttTestPaperDetailMapper.selectTestPaperDetailList(ttTestPaperDetail));

        return result;
    }

    @Override
    public List<TtTrainTargetVo> selectTrainResult(TtTrainDto ttTrainDto) {
        // 1. 根据培训id 获取人员详细

        TtTrainTarget ttTrainTarget = new TtTrainTarget();
        ttTrainTarget.setTrainId(ttTrainDto.getId());
        List<TtTrainTargetVo> ttTrainTargets = ttTrainTargetMapper.selectTtTrainTargetList(ttTrainTarget);

        // 获取培训对象id集合
        List<Long> targetIds = new ArrayList<>();
        for (TtTrainTargetVo tt : ttTrainTargets) {
            targetIds.add(tt.getTargetPersonId());
        }

        // 2. 根据培训对象id集合 获取人员详细
        SysUser sysUser = new SysUser();
        sysUser.setUserIdList(targetIds);
        List<SysUser> sysUsers = sysUserService.selectUserList(sysUser);
        // 设置 对象的角色
        for (SysUser user : sysUsers) {
            for (TtTrainTargetVo trainTarget : ttTrainTargets) {
                if (user.getUserId().equals(trainTarget.getTargetPersonId())) {
                    trainTarget.setRoleNames(user.getRoleNames());
                }
            }
        }

        return ttTrainTargets;
    }

    /**
     * 培训状态修改 定时任务
     */
    @Override
    public void updateTrainStatus() {
        // 查询所有未开始 和 已开始的培训
        QueryWrapper<TtTrain> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("train_status", TrainStatusEnum.ENDED.getCode());
        queryWrapper.ne("train_status", TrainStatusEnum.TERMINATION.getCode());
        List<TtTrain> ttTrains = ttTrainMapper.selectList(queryWrapper);
        // 遍历所有未开始 和 已开始的培训
        Date currentDate = new Date();
        List<TtTrain> ttTrainList = new ArrayList<>();

        for (TtTrain ttTrain : ttTrains) {
            // 1. 当前时间在开始时间后（已开始） 但状态仍然是未开始，则修改状态为已开始
            if (currentDate.after(ttTrain.getStartDate()) && currentDate.before(ttTrain.getEndDate()) && ttTrain.getTrainStatus().equals(TrainStatusEnum.NOT_START.getCode())) {
                ttTrain.setTrainStatus(TrainStatusEnum.STARTED.getCode());
                ttTrain.setUpdateTime(DateUtils.getNowDate());
                ttTrainList.add(ttTrain);
            }
            // 2. 当前时间在结束时间后（已结束） 但状态仍然是已开始，则修改状态为已结束
            if (currentDate.after(ttTrain.getEndDate())) {
                ttTrain.setTrainStatus(TrainStatusEnum.ENDED.getCode());
                ttTrain.setUpdateTime(DateUtils.getNowDate());
                ttTrainList.add(ttTrain);
            }
        }
        // 批量更新培训状态
        ttTrainMapper.updateBatchById(ttTrainList);
    }

    @Override
    public int updateTtTrainStatusByIds(Long[] ids) {
        QueryWrapper<TtTrain> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", Arrays.asList(ids));
        TtTrain ttTrain = new TtTrain();
        ttTrain.setTrainStatus(TrainStatusEnum.TERMINATION.getCode());
        return ttTrainMapper.update(ttTrain,queryWrapper);

    }
}