package com.testor.module.train.myManagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.biz.sys.user.service.SysUserService;
import com.testor.common.util.DateUtil;
import com.testor.module.partner.model.domain.TPartnerStaff;
import com.testor.module.partner.service.TPartnerStaffService;
import com.testor.module.train.course.dao.TTrainSmallNodeDao;
import com.testor.module.train.course.model.domain.TTrainCourse;
import com.testor.module.train.course.model.domain.TTrainSection;
import com.testor.module.train.course.model.domain.TTrainSmallNode;
import com.testor.module.train.course.model.dto.TTrainCourseParam;
import com.testor.module.train.course.model.dto.TTrainSectionParam;
import com.testor.module.train.course.model.dto.TTrainSmallNodeParam;
import com.testor.module.train.course.service.TTrainCourseService;
import com.testor.module.train.course.service.TTrainSectionService;
import com.testor.module.train.exam.model.domain.TTrainExamChoice;
import com.testor.module.train.exam.model.domain.TTrainExamJudgment;
import com.testor.module.train.exam.model.domain.TTrainQuestionBank;
import com.testor.module.train.exam.model.domain.TTrainTestQuestions;
import com.testor.module.train.exam.service.TTrainExamChoiceService;
import com.testor.module.train.exam.service.TTrainExamJudgmentService;
import com.testor.module.train.exam.service.TTrainQuestionBankService;
import com.testor.module.train.exam.service.TTrainTestQuestionsService;
import com.testor.module.train.examinationManage.model.domain.TTrainExaminationManage;
import com.testor.module.train.examinationManage.model.dto.TTrainExaminationManageParam;
import com.testor.module.train.examinationManage.model.dto.TTrainExaminationManageQueryParam;
import com.testor.module.train.examinationManage.service.TTrainExaminationManageService;
import com.testor.module.train.myManagement.dao.TTrainMyManagementDao;
import com.testor.module.train.myManagement.model.domain.TTrainCourseLearnStatistics;
import com.testor.module.train.myManagement.model.domain.TTrainMyManagement;
import com.testor.module.train.myManagement.model.domain.TTrainMyManagementRead;
import com.testor.module.train.myManagement.model.dto.TTrainMyManagementParam;
import com.testor.module.train.myManagement.service.TTrainCourseLearnStatisticsService;
import com.testor.module.train.myManagement.service.TTrainMyManagementReadService;
import com.testor.module.train.myManagement.service.TTrainMyManagementService;
import com.testor.module.train.paper.model.domain.TTrainPaper;
import com.testor.module.train.paper.model.dto.Options;
import com.testor.module.train.paper.model.dto.ReturnTrainPaper;
import com.testor.module.train.paper.model.dto.TestQuestionsContent;
import com.testor.module.train.paper.service.TTrainPaperService;
import com.testor.module.train.project.model.domain.TTrainProject;
import com.testor.module.train.project.model.dto.MyManagement;
import com.testor.module.train.project.service.TTrainProjectService;
import com.testor.module.video.util.Beans;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BizGeneralResponse;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.TypeHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 我的培训教育及考试—安全培训教育Service业务层处理
 *
 * @author testor-framework
 * @date 2022-07-28 15:25:02
 */
@Service
public class TTrainMyManagementServiceImpl extends SuperServiceImpl<TTrainMyManagementDao, TTrainMyManagement> implements TTrainMyManagementService {
    @Autowired(required = false)
    private TTrainMyManagementDao tTrainMyManagementDao;
    @Autowired
    private SysOrgService sysOrgService;
    @Autowired
    private TTrainProjectService tTrainProjectService;
    @Autowired
    private TTrainCourseService tTrainCourseService;
    @Autowired
    private TTrainCourseLearnStatisticsService tTrainCourseLearnStatisticsService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private TTrainQuestionBankService tTrainQuestionBankService;

    @Autowired
    private TTrainSmallNodeDao tTrainSmallNodeDao;

    @Autowired
    private TTrainPaperService tTrainPaperService;

    @Autowired
    private TTrainTestQuestionsService tTrainTestQuestionsService;

    @Autowired
    private TTrainExamChoiceService tTrainExamChoiceService;

    @Autowired
    private TTrainExamJudgmentService tTrainExamJudgmentService;

    @Autowired
    @Lazy
    private TTrainExaminationManageService manageService;

    @Autowired
    private TPartnerStaffService staffService;

    @Autowired
    private TTrainMyManagementReadService tTrainMyManagementReadService;

    @Autowired
    private TTrainSectionService tTrainSectionService;


    @Override
    public BaseResponse<TTrainMyManagement> addEntity(List<MyManagement> addRequest) {
        BaseResponse<TTrainMyManagement> baseResponse = new BaseResponse<>();
        UserInfo loginUser = ContextUtils.getLoginUser();
        SysOrg sysOrg = sysOrgService.getById(loginUser.getOrgId());
        if (ObjectHelper.isNotEmpty(addRequest)) {
            String id = null;
            List<TTrainMyManagement> myManagements = new ArrayList<>();
            for (MyManagement myManagement : addRequest) {
                TTrainMyManagement data = BeanHelper.beanToBean(myManagement, TTrainMyManagement.class);
                id = data.getId();
                if (StringHelper.isEmpty(id)) {
                    id = IdHelper.getId32bit();
                }
                String userId = data.getPersonId();
                SysUser user = sysUserService.getById(userId);
                data.setOrgId(user.getOrgId());
                data.setCompany(sysOrgService.getById(user.getOrgId()).getOrgName());
                data.setId(id);
                myManagements.add(data);
            }
            boolean result = this.saveOrUpdateBatch(myManagements);
            if (result) {
                TTrainMyManagement newEntity = new TTrainMyManagement();
                newEntity.setId(id);
                baseResponse.setData(newEntity);
            }
        }
        return baseResponse;
    }

    @Override
    public void deletePerson(String id) {
        this.remove(new QueryWrapper<TTrainMyManagement>()
                .eq(TTrainMyManagement.TASK_ID, id));
    }

    @Override
    public List<TTrainMyManagement> getPerson(String projectParamId) {
        List<TTrainMyManagement> list = this.list(new QueryWrapper<TTrainMyManagement>()
                .eq(TTrainMyManagement.TASK_ID, projectParamId)
                .orderByDesc(TTrainMyManagement.CURRENT_STATUS, TTrainMyManagement.CREATE_DATE)
        );
        return list;
    }

    @Override
    public List<TTrainMyManagement> getPerson(String projectParamId, String orgId, String name, String status) {
        return this.list(new LambdaQueryWrapper<TTrainMyManagement>()
                .eq(TTrainMyManagement::getTaskId, projectParamId)
                .eq(StringUtils.isNotBlank(orgId), TTrainMyManagement::getOrgId, orgId)
                .like(StringUtils.isNotBlank(name), TTrainMyManagement::getPersonName, name)
                .eq(StringUtils.isNotBlank(status), TTrainMyManagement::getCurrentStatus, status)
                .orderByDesc(TTrainMyManagement::getCurrentStatus, TTrainMyManagement::getCreateDate)
        );
    }

    @Override
    public IPage<TTrainMyManagementParam> staffTrainCase(TTrainMyManagementParam param, String parentIds, String orgId) {
        Long page = StringHelper.isEmpty(param.getPage()) ? BizConstants.PAGE : Long.valueOf(param.getPage());
        Long limit = StringHelper.isEmpty(param.getLimit()) ? BizConstants.LIMIT : Long.valueOf(param.getLimit());
        Page<TTrainMyManagementParam> resultPage = new Page<>(page, limit);
        return tTrainMyManagementDao.staffTrainCase(resultPage, param, parentIds, orgId);
    }

    @Override
    public void addCourse(MyManagement myManagement) throws Exception {
        TTrainMyManagement tTrainMyManagement = BeanHelper.beanToBean(myManagement, TTrainMyManagement.class);
        List<TTrainMyManagement> list = this.list(new QueryWrapper<TTrainMyManagement>()
                .eq(TTrainMyManagement.TASK_ID, tTrainMyManagement.getTaskId())
                .eq(TTrainMyManagement.PERSON_ID, tTrainMyManagement.getPersonId())
        );
        if (ObjectHelper.isNotEmpty(list)) {
            throw new BusinessException("已经加入，请勿重新加入");
        }
        this.save(tTrainMyManagement);
    }

    @Override
    public BaseResponse<List<TTrainCourseParam>> startLearn(TTrainMyManagement tTrainMyManagement) throws Exception {
        BaseResponse<List<TTrainCourseParam>> baseResponse = new BaseResponse<>();
        UserInfo loginUser = ContextUtils.getLoginUser();
        String taskId = null;
        String id = tTrainMyManagement.getId();
        if (ObjectHelper.isNotEmpty(tTrainMyManagement)) {
            TTrainMyManagement management = this.getById(id);
            // 获取任务id 判读是否是自主学习课程
            taskId = management.getTaskId();
            // 存储课程信息
            List<TTrainCourse> course = null;
            //自主学习
            if ("2".equals(management.getLearnWay())) {
                // 此时任务taskId为课程id , 获取课程信息
                course = tTrainCourseService.getCourse(taskId);
            }
            //线下
            if ("1".equals(management.getLearnWay()) || "0".equals(management.getLearnWay())) {
                // 此时任务id taskId为培训计划id  获取培训计划
                TTrainProject project = tTrainProjectService.getById(taskId);
                // 获取计划关联的课程id , 多个课程用逗号隔开
                String courseId = project.getCourseId();
                course = tTrainCourseService.getCourse(courseId);
            }
            // 交换集合
            List<TTrainCourseParam> collect = course.stream().map(bean -> bean.beanToBean(TTrainCourseParam.class)).collect(Collectors.toList());
            // 获取课程进度详情
            List<TTrainCourseLearnStatistics> list = tTrainCourseLearnStatisticsService.list(new QueryWrapper<TTrainCourseLearnStatistics>()
                    .eq(TTrainCourseLearnStatistics.TASK_ID, taskId)
                    .eq(TTrainCourseLearnStatistics.PERSON_ID, loginUser.getUserId())
            );
            // 获取计划中包含的课程的学习情况
            list = getMaxCourseStatistics(list);
            for (TTrainCourseParam tTrainCourseParam : collect) {
                tTrainCourseParam.setTaskId(taskId);
                //获取所有章节id
                List<Object> sectionIds = tTrainSectionService.listObjs(new QueryWrapper<TTrainSection>().select("id").in("course_id", tTrainCourseParam.getId()).eq("status", "0"));
                List<Object> nodeIds = tTrainSmallNodeDao.selectObjs(new QueryWrapper<TTrainSmallNode>().select("id").in("section_id", sectionIds));

                //设置进度百分比
                String coursePercentage = tTrainSmallNodeDao.getPercentageByNodeIds(sectionIds, nodeIds, loginUser.getUserId(), id);
                tTrainCourseParam.setCoursePlan(coursePercentage);
/*                for (TTrainCourseLearnStatistics statistics : list) {
                    if (tTrainCourseParam.getId().equals(statistics.getCourseId())) {
                        tTrainCourseParam.setCoursePlan(statistics.getCoursePlan());
                    }
                }*/
            }
            // 统计个人学习情况 到t_train_my_management
            statisticsToMyManagement(collect, id);
            baseResponse.setData(collect);
        } else {
            throw new BusinessException("参数有误");
        }
        return baseResponse;
    }

    /**
     * 获取课程学习情况最大占比
     *
     * @param list
     * @return
     */
    private List<TTrainCourseLearnStatistics> getMaxCourseStatistics(List<TTrainCourseLearnStatistics> list) {
        Map<String, List<TTrainCourseLearnStatistics>> collect = list.stream().collect(Collectors.groupingBy(item -> item.getCourseId()));
        List<TTrainCourseLearnStatistics> arrayList = new ArrayList<>();
        for (String s : collect.keySet()) {
            List<TTrainCourseLearnStatistics> tTrainCourseLearnStatistics = collect.get(s);
            tTrainCourseLearnStatistics.stream().forEach(item -> {
                try {
                    int coursePlanInt = Integer.parseInt(item.getCoursePlan());
                    item.setCoursePlanI(coursePlanInt);
                } catch (NumberFormatException e) {
                    item.setCoursePlanI(0);
                }
            });
            // 获取集合中课程进度最多的
            TTrainCourseLearnStatistics tTrainCourseLearnStatistics1 =
                    tTrainCourseLearnStatistics.stream().max(Comparator.comparing(TTrainCourseLearnStatistics::getCoursePlanI)).get();
            arrayList.add(tTrainCourseLearnStatistics1);

        }
        return arrayList;
    }

    /**
     * 统计个人学习情况，同步数据库
     *
     * @param collect
     */
    public void statisticsToMyManagement(List<TTrainCourseParam> collect, String id) throws ParseException {
        // 包含的课程数
        int size = collect.size() * 100;
        // 学习进度总和
        int count = 0;
        for (TTrainCourseParam courseParam : collect) {
            String coursePlan = courseParam.getCoursePlan();
            if (StringHelper.isNotEmpty(coursePlan)) {
                String number = getNumber(coursePlan);
                int i = 0;
                try {
                    i = Integer.parseInt(number);
                } catch (NumberFormatException e) {
                    i = 0;
                }
                count += i;
            }
        }
        // 个人总的学习情况占比
        String ratio = getRatio(count, size);
        // 更新个人学习情况记录表
        this.update(new UpdateWrapper<TTrainMyManagement>()
                .eq(TTrainMyManagement.ID, id)
                .set(TTrainMyManagement.PERCENTAGE, ratio)
        );
    }

    /**
     * 根据百分比获取数字字符串
     *
     * @param s
     * @return
     */
    private static String getNumber(String s) {
        String replace = s.replace("%", "");
        int i = replace.indexOf(".");
        if (i != -1) {
            String substring1 = replace.substring(i + 1, i + 2);
            int i1 = Integer.parseInt(substring1);
            String substring = replace.substring(0, i);
            if (i1 >= 4) {
                int i2 = Integer.parseInt(substring);
                int i3 = i2 += 1;
                substring = Integer.toString(i3);
            } else {
                substring = substring;
            }
            return substring;
        }
        return replace;
    }

    /**
     * 计算百分比
     *
     * @param number1
     * @param number2
     * @return
     */
    public String getRatio(Integer number1, Integer number2) {
        DecimalFormat df = new DecimalFormat("0.0");
        if (number2 != 0) {
            return df.format((float) (number1 / (double) number2) * 100) + "%";
        } else {
            return "0%";
        }
    }


    @Override
    public BaseResponse<TTrainCourseParam> getCourseDetail(String id, String taskId) throws Exception {
        BaseResponse<TTrainCourseParam> courseServiceByIds = tTrainCourseService.getBySection(id, taskId);
        // 获取该课程的进度详情
        /*List<TTrainCourseLearnStatistics> list = tTrainCourseLearnStatisticsService.list(new QueryWrapper<TTrainCourseLearnStatistics>()
                .eq(TTrainCourseLearnStatistics.TASK_ID, taskId)
                .eq(TTrainCourseLearnStatistics.COURSE_ID, id)
                .eq(TTrainCourseLearnStatistics.PERSON_ID, loginUser.getUserId())
                .orderByDesc("cast(course_plan as UNSIGNED INTEGER)")
                .apply("order by cast(course_plan as UNSIGNED INTEGER) desc")
        );*/
        // 给详情添加课程进度
        setCourseProgress(courseServiceByIds.getData(), taskId);
        //courseServiceByIds = addCoursePlan(courseServiceByIds, list, taskId);
        return courseServiceByIds;
//        String userId = ContextUtils.getLoginUser().getUserId();
//        List<TTrainCourseParam> courseIds  = tTrainMyManagementDao.getCourseDetail(id, taskId,userId);
    }

    private void setCourseProgress(TTrainCourseParam courseServiceByIds, String taskId) {
        String loginUserId = ContextUtils.getLoginUserId();

        // 获取所有章节ID
        List<Object> sectionIds = getSectionIdsByCourseId(courseServiceByIds.getId());

        // 获取所有小节ID
        List<Object> nodeIds = getNodeIdsBySectionIds(sectionIds);

        // 设置课程进度百分比
        String coursePercentage = tTrainSmallNodeDao.getPercentageByNodeIds(sectionIds, nodeIds, loginUserId, taskId);
        courseServiceByIds.setCoursePlan(coursePercentage);

        List<TTrainSectionParam> trainSectionParams = courseServiceByIds.getTrainSectionParams();
        for (TTrainSectionParam trainSectionParam : trainSectionParams) {
            List<TTrainSmallNodeParam> nodes = trainSectionParam.getTTrainSmallNodes();
            if (CollectionUtils.isNotEmpty(nodes)) {
                List<String> nodeIdsList = getNodeIdsList(nodes);
                int count = tTrainMyManagementReadService.count(new QueryWrapper<TTrainMyManagementRead>()
                        .in("node_id", nodeIdsList)
                        .eq("management_id", taskId));
                int size = nodes.size();
                BigDecimal divide = new BigDecimal(count)
                        .divide(new BigDecimal(size), 2, RoundingMode.DOWN)
                        .multiply(new BigDecimal("100"));
                String chapterProgress = divide.toString();
                trainSectionParam.setSectionPlan(chapterProgress);
            } else {
                trainSectionParam.setSectionPlan("100");
            }
        }
    }

    // 获取章节ID列表
    private List<Object> getSectionIdsByCourseId(String courseId) {
        return tTrainSectionService.listObjs(new QueryWrapper<TTrainSection>()
                .select("id")
                .in("course_id", courseId)
                .eq("status", "0"));
    }

    // 获取小节ID列表
    private List<Object> getNodeIdsBySectionIds(List<Object> sectionIds) {
        return tTrainSmallNodeDao.selectObjs(new QueryWrapper<TTrainSmallNode>()
                .select("id")
                .in("section_id", sectionIds));
    }

    // 获取小节ID字符串列表
    private List<String> getNodeIdsList(List<TTrainSmallNodeParam> nodes) {
        return nodes.stream()
                .map(TTrainSmallNodeParam::getId)
                .collect(Collectors.toList());
    }



    /**
     * 给详情添加观看进度
     *
     * @param courseServiceByIds
     * @param list               观看进度记录
     * @param taskId             任务id
     * @return
     */
    private BaseResponse<TTrainCourseParam> addCoursePlan(BaseResponse<TTrainCourseParam> courseServiceByIds, List<TTrainCourseLearnStatistics> list, String taskId) {
        BaseResponse<TTrainCourseParam> courseParamBaseResponse = new BaseResponse<>();
        TTrainCourseParam data = courseServiceByIds.getData();
        data.setTaskId(taskId);
        // 获取课程所有的章节和小节
        List<TTrainSectionParam> trainSectionParams = data.getTrainSectionParams();
        // 存储改变后的集合
        if (ObjectHelper.isNotEmpty(list)) {
            List<TTrainSectionParam> paramList = new ArrayList<>();
            for (TTrainSectionParam trainSectionParam : trainSectionParams) {
                data.setCoursePlan(list.get(0).getCoursePlan());
                TTrainSectionParam tTrainSectionParam = BeanHelper.beanToBean(trainSectionParam, TTrainSectionParam.class);
                for (TTrainCourseLearnStatistics one : list) {
                    if (tTrainSectionParam.getId().equals(one.getSectionId())) {
                        if (ObjectHelper.isEmpty(tTrainSectionParam.getSectionPlan())) {
                            tTrainSectionParam.setSectionPlan(one.getSectionPlan());
                        } else {
                            if (Integer.parseInt(one.getSectionPlan()) > Integer.parseInt(tTrainSectionParam.getSectionPlan())) {
                                tTrainSectionParam.setSectionPlan(one.getSectionPlan());
                            }
                        }

                    }
                }
                List<TTrainSmallNodeParam> tTrainSmallNodes = new ArrayList<>();
                for (TTrainSmallNodeParam tTrainSmallNode : tTrainSectionParam.getTTrainSmallNodes()) {
                    TTrainSmallNodeParam tTrainSmallNode1 = BeanHelper.beanToBean(tTrainSmallNode, TTrainSmallNodeParam.class);
                    for (TTrainCourseLearnStatistics one : list) {
                        if (tTrainSmallNode1.getId().equals(one.getSmallNodeId())) {
                            tTrainSmallNode1.setSmallPlan(one.getSmallPlan());
                        }
                    }
                    tTrainSmallNodes.add(tTrainSmallNode1);
                }
                tTrainSectionParam.setTTrainSmallNodes(tTrainSmallNodes);
                paramList.add(tTrainSectionParam);
            }
            data.setTrainSectionParams(paramList);
        }
        courseParamBaseResponse.setData(data);
        return courseParamBaseResponse;
    }

    @Override
    public BaseResponse<TTrainCourseLearnStatistics> planStatistics(List<TTrainCourseLearnStatistics> courseLearnStatistics) throws Exception {
        BaseResponse<TTrainCourseLearnStatistics> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(courseLearnStatistics)) {
            UserInfo loginUser = ContextUtils.getLoginUser();
            for (TTrainCourseLearnStatistics courseLearnStatistic : courseLearnStatistics) {
                String id32bit = IdHelper.getId32bit();
                courseLearnStatistic.setId(id32bit);
                courseLearnStatistic.setPersonId(loginUser.getUserId());
                UpdateWrapper<TTrainCourseLearnStatistics> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq(TTrainCourseLearnStatistics.TASK_ID, courseLearnStatistic.getTaskId())
                        .eq(TTrainCourseLearnStatistics.COURSE_ID, courseLearnStatistic.getCourseId())
                        .eq(TTrainCourseLearnStatistics.SECTION_ID, courseLearnStatistic.getSectionId())
                        .eq(TTrainCourseLearnStatistics.SMALL_NODE_ID, courseLearnStatistic.getSmallNodeId())
                        .eq(TTrainCourseLearnStatistics.PERSON_ID, loginUser.getUserId());
                tTrainCourseLearnStatisticsService.saveOrUpdate(courseLearnStatistic, updateWrapper);
            }
        } else {
            throw new BusinessException("参数异常");
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<TTrainMyManagement> lineTrainSign(String id) throws Exception {
        BaseResponse<TTrainMyManagement> response = new BaseResponse<>();
        TTrainProject service = tTrainProjectService.getById(id);
        TTrainMyManagement one = this.getOne(new QueryWrapper<TTrainMyManagement>()
                .eq(TTrainMyManagement.TASK_ID, id)
                .eq(TTrainMyManagement.PERSON_ID, ContextUtils.getLoginUser().getUserId())
                .ne(TTrainMyManagement.STATUS, BizConstants.STATUS_DELETE)
        );
        if (ObjectHelper.isNotEmpty(one)) {
            this.update(new UpdateWrapper<TTrainMyManagement>()
                    .eq(TTrainMyManagement.ID, one.getId())
                    .set(TTrainMyManagement.PERCENTAGE, "100%")
                    .set(TTrainMyManagement.CURRENT_STATUS, "3")
            );
        } else {
            throw new BusinessException("此人不存在该计划");
        }
        return response;
    }

    @Override
    public BaseResponse<BizGeneralResponse> updateEntity(List<TTrainMyManagement> updateRequest) {
        BaseResponse<BizGeneralResponse> baseResponse = new BaseResponse<>();
        if (ObjectHelper.isNotEmpty(updateRequest)) {
            List<TTrainMyManagement> list = new ArrayList<>();
            for (TTrainMyManagement tTrainMyManagement : updateRequest) {
                TTrainMyManagement management = this.getById(tTrainMyManagement.getId());
                management.setTestScore(tTrainMyManagement.getTestScore());
                list.add(management);
            }
            boolean result = this.updateBatchById(list);
            baseResponse.setData(
                    BizGeneralResponse.builder().result(TypeHelper.castToString(result)).build());
        }
        return baseResponse;
    }

    @Override
    public BaseResponse<List<TTrainQuestionBank>> getTestBlankName() {
        BaseResponse<List<TTrainQuestionBank>> baseResponse = new BaseResponse<>();
        String loginUserId = ContextUtils.getLoginUserId();
        // 获取题库id
        List<TTrainMyManagement> list = this.list(new QueryWrapper<TTrainMyManagement>().eq(TTrainMyManagement.PERSON_ID, loginUserId)
                .ne(TTrainMyManagement.STATUS, BizConstants.STATUS_DELETE)
                .eq(TTrainMyManagement.TAB_STATUS, "3").select(TTrainMyManagement.TASK_ID)
        );

        List<String> taskIds = new ArrayList<>();
        List<TTrainMyManagement> collect = list.stream().filter(new Predicate<TTrainMyManagement>() {
            @Override
            public boolean test(TTrainMyManagement tTrainMyManagement) {
                String taskId = tTrainMyManagement.getTaskId();
                taskIds.add(taskId);
                return true;
            }
        }).collect(Collectors.toList());
        if (taskIds.size() > 0) {
            List<TTrainQuestionBank> questionBanks = tTrainQuestionBankService.list(new QueryWrapper<TTrainQuestionBank>().in(TTrainQuestionBank.ID, taskIds)
                    .ne(TTrainQuestionBank.STATUS, BizConstants.STATUS_DELETE).select(TTrainQuestionBank.ID, TTrainQuestionBank.QUESTION_BANK_NAME)
            );
            baseResponse.setData(questionBanks);
        }
        return baseResponse;
    }

    @Override
//    @Transactional
    public BaseResponse<TTrainExaminationManageQueryParam> scanCodeExam(String id) throws Exception {

        //ToDo 获取用户信息
        String loginUserId = ContextUtils.getLoginUserId();
        SysUser user = sysUserService.getById(loginUserId);
        List<TTrainMyManagement> list = this.list(new QueryWrapper<TTrainMyManagement>().eq(TTrainMyManagement.PERSON_ID, loginUserId)
                .ne(TTrainMyManagement.STATUS, BizConstants.STATUS_DELETE)
                .eq(TTrainMyManagement.TASK_ID, id)
        );
        //ToDo 校验当前登录用户是否为内部用户
        int status = staffService.count(new QueryWrapper<TPartnerStaff>().eq("sys_user_id", loginUserId).ne("status", "1"));

        if (!CollectionUtils.isEmpty(list) && "1".equals(list.get(0).getIsAddExam())) {
            throw new BusinessException("请勿重复考试");
        }
        BaseResponse<TTrainExaminationManageQueryParam> response = new BaseResponse<>();
        //todo 查看二维码是否过期
        TTrainExaminationManage byId = manageService.getById(id);
        if (!"3".equals(byId.getExamWay())) {
            throw new BusinessException("二维码无效");
        }
        LocalDateTime examEndTime = DateUtil.dateToLocalDateTime( byId.getExamEndTime());
        Date date = Date.from(examEndTime.atZone(ZoneId.systemDefault()).toInstant());
        if (!date.after(new Date())) {
            throw new BusinessException("二维码已过期");
        }
        TTrainExaminationManageParam tTrainProjectParam = BeanHelper.beanToBean(byId, TTrainExaminationManageParam.class);
        // 培训计划id
        String projectParamId = tTrainProjectParam.getId();
        // 试卷id
        String testPaperId = tTrainProjectParam.getPaperId();
        // 获取试卷名称
        String testPaperName = tTrainPaperService.getTestPaperName(testPaperId);
        tTrainProjectParam.setTestPaperName(testPaperName);
        TTrainExaminationManageQueryParam tTrainExaminationManageQueryParam =
                Beans.objectToBean(tTrainProjectParam, TTrainExaminationManageQueryParam.class);
        //todo 添加我的教育及培训考试信息
        if (CollectionUtils.isEmpty(list)) {
            SysOrg byId1 = sysOrgService.getById(user.getDeptId());
            TTrainMyManagement tTrainMyManagement = new TTrainMyManagement();
            String id32bit = IdHelper.getId32bit();
            tTrainMyManagement.setId(id32bit);
            tTrainMyManagement.setPersonId(loginUserId);
            tTrainMyManagement.setTaskId(id);
            tTrainMyManagement.setTaskType(byId.getExamType());
            if (status == 0) {
                tTrainMyManagement.setPersonAffiliation("1");
            } else {
                tTrainMyManagement.setPersonAffiliation("2");
            }
            tTrainMyManagement.setCompany(byId.getOrgName());
            if (byId1 != null) {
                tTrainMyManagement.setDeptName(byId1.getOrgName());
            }
            tTrainMyManagement.setPersonName(user.getUserName());
            tTrainMyManagement.setSex(user.getSex());
            tTrainMyManagement.setPercentage("0");
            tTrainMyManagement.setOrgId(byId.getOrgId());
            tTrainMyManagement.setCurrentStatus("0");
            tTrainMyManagement.setTabStatus("2");
            tTrainMyManagement.setTaskName(byId.getExamName());
            tTrainMyManagement.setLearnWay("3");
            tTrainMyManagement.setVisitEndTime(byId.getExamEndTime());
            tTrainMyManagement.setTestPaperId(byId.getPaperId());
            tTrainMyManagement.setExamDuration(byId.getExamDuration());
            tTrainMyManagement.setStatus("0");
            tTrainMyManagement.setIsAddExam("0");
            this.save(tTrainMyManagement);
            tTrainExaminationManageQueryParam.setMyId(id32bit);
        } else {
            tTrainExaminationManageQueryParam.setMyId(list.get(0).getId());
        }

        response.setData(tTrainExaminationManageQueryParam);
        return response;
    }

    @Override
    public BaseResponse<ReturnTrainPaper> startExam(String id) {
        BaseResponse<ReturnTrainPaper> baseResponse = new BaseResponse<>();
        TTrainMyManagement tTrainMyManagement = this.getById(id);
        String testPaperId = tTrainMyManagement.getTestPaperId();
        if (StringHelper.isNotEmpty(testPaperId)) {
            ReturnTrainPaper returnTrainPaper = new ReturnTrainPaper();
            TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
            String[] testQuestionsId = trainPaper.getTestQuestionsId().split(",");
            List<TTrainTestQuestions> questions = tTrainTestQuestionsService.list(new QueryWrapper<TTrainTestQuestions>()
                    .in(TTrainTestQuestions.ID, testQuestionsId)
                    .ne(TTrainTestQuestions.STATUS, BizConstants.STATUS_DELETE)
            );
            List<TestQuestionsContent> allTest = getRandomAllTest(questions, testPaperId);
            returnTrainPaper.setPassScore(trainPaper.getPassScore());
            returnTrainPaper.setFullScore(trainPaper.getFullScore());
            returnTrainPaper.setTestPaperName(trainPaper.getTestPaperName());
            returnTrainPaper.setTestQuestionsContent(allTest);
            baseResponse.setData(returnTrainPaper);
        }
        return baseResponse;
    }

    /**
     * 返回题库或试卷中试题的详细信息
     *
     * @param records 试题的集合
     * @return
     * @Param myid 个人中心主键id
     */
    private List<TestQuestionsContent> getRandomAllTest(List<TTrainTestQuestions> records, String testPaperId) {
        // 试卷中的所有试题
        List<TestQuestionsContent> testQuestionsContents = new ArrayList<>();
//        int num = 0;
        for (TTrainTestQuestions tTrainTestQuestions : records) {
            String testQuestionsType = tTrainTestQuestions.getTestQuestionsType();
            //试题id
            String questionsId = tTrainTestQuestions.getId();
//            num++;
            if ("SELECT".equals(testQuestionsType) || "MORE_SELECT".equals(testQuestionsType)) {
                // 每一个题目
                TestQuestionsContent testQuestionsContent = BeanHelper.beanToBean(tTrainTestQuestions, TestQuestionsContent.class);
                QueryWrapper<TTrainExamChoice> wrapper = new QueryWrapper<>();
                wrapper.eq(TTrainExamChoice.TEST_QUESTIONS_ID, questionsId);
                // 当前题目包含的所有选项
                List<TTrainExamChoice> list1 = tTrainExamChoiceService.list(wrapper);
                // 按照选项排序
                list1 = list1.stream().sorted(Comparator.comparing(TTrainExamChoice::getOptions))
                        .collect(Collectors.toList());
                List<Options> optionsList = new ArrayList<>();
                for (TTrainExamChoice tTrainExamChoice : list1) {
                    Options options = BeanHelper.beanToBean(tTrainExamChoice, Options.class);
                    String optionsTest = options.getOptions() + ": " + options.getOptionText();
                    options.setOptionText(optionsTest);
                    optionsList.add(options);
                }
                String testQuestionsContent1 = testQuestionsContent.getTestQuestionsContent();
                testQuestionsContent.setTestQuestionsContent(testQuestionsContent1);
                testQuestionsContent.setOptions(optionsList);
                String score = "";
                if (StringHelper.isNotEmpty(testPaperId)) {
                    TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                    if ("SELECT".equals(testQuestionsType)) {
                        score = "(单选题、" + trainPaper.getSingleScore() + "分)";
                    }
                    if ("MORE_SELECT".equals(testQuestionsType)) {
                        score = "(多选题、" + trainPaper.getMoreScore() + "分)";
                    }
                }
                testQuestionsContent.setScore(score);
                testQuestionsContent.setDictKey(testQuestionsType);
                testQuestionsContents.add(testQuestionsContent);
            }
            if ("JUDGE".equals(testQuestionsType)) {
                // 每一个题目
                TestQuestionsContent testQuestionsContent = BeanHelper.beanToBean(tTrainTestQuestions, TestQuestionsContent.class);
                QueryWrapper<TTrainExamJudgment> wrapper = new QueryWrapper<>();
                wrapper.eq(TTrainExamJudgment.TEST_QUESTIONS_ID, questionsId);
                // 当前题目包含的所有选项
                List<TTrainExamJudgment> list1 = tTrainExamJudgmentService.list(wrapper);
                // 按照选项排序
                list1 = list1.stream().sorted(Comparator.comparing(TTrainExamJudgment::getOptions))
                        .collect(Collectors.toList());
                List<Options> optionsList = new ArrayList<>();
                for (TTrainExamJudgment tTrainExamChoice : list1) {
                    Options options = BeanHelper.beanToBean(tTrainExamChoice, Options.class);
                    String optionsTest = options.getOptions() + ": " + options.getOptionText();
                    options.setOptionText(optionsTest);
                    optionsList.add(options);
                }
                String testQuestionsContent1 = testQuestionsContent.getTestQuestionsContent();
                testQuestionsContent.setTestQuestionsContent(testQuestionsContent1);
                testQuestionsContent.setOptions(optionsList);
                String score = "";
                if (StringHelper.isNotEmpty(testPaperId)) {
                    TTrainPaper trainPaper = tTrainPaperService.getById(testPaperId);
                    if ("JUDGE".equals(testQuestionsType)) {
                        score = "(判断题、" + trainPaper.getJudgeScore() + "分)";
                    }
                }
                testQuestionsContent.setScore(score);
                testQuestionsContent.setDictKey(testQuestionsType);
                testQuestionsContents.add(testQuestionsContent);
            }
        }
        UserInfo loginUser = ContextUtils.getLoginUser();
//        //得到已经做过的题目
//        List<TTrainTestQuestionsExercise> list = this.list(new QueryWrapper<TTrainTestQuestionsExercise>()
//                .eq(TTrainTestQuestionsExercise.MY_ID, myid)
//                .eq(TTrainTestQuestionsExercise.PERSON_ID, loginUser.getUserId())
//        );
//        for (TestQuestionsContent test : testQuestionsContents) {
//            for (TTrainTestQuestionsExercise tTrain : list) {
//                if (test.getId().equals(tTrain.getTestQuestionsId())) {
//                    test.setIsSelect("1");
//                    test.setIsCorrect(tTrain.getIsCorrect());
//                    if (StringHelper.isNotEmpty(tTrain.getOptionsId())) {
//                        String[] split = tTrain.getOptionsId().split(",");
//                        for (Options option : test.getOptions()) {
//                            for (String s : split) {
//                                if (option.getId().equals(s)) {
//                                    option.setIsSelect("1");
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }
        List<TestQuestionsContent> collect = testQuestionsContents.stream().
                sorted(Comparator.comparing(TestQuestionsContent::getDictKey).reversed()).collect(Collectors.toList());
        AtomicInteger num = new AtomicInteger(1);
        collect.stream().forEach(item -> {
            item.setTestQuestionsContent(num.getAndIncrement() + "." + item.getTestQuestionsContent());
        });
        return collect;
    }


    /**
     * @description 查询项目所有课程是否完成
     */
    @Override
    public BaseResponse<Boolean> findAllProjectCourseCompleteState(TTrainMyManagement tTrainMyManagement) {
        BaseResponse<Boolean> baseResponse = new BaseResponse<>();
        baseResponse.setData(Boolean.TRUE);

        UserInfo loginUser = ContextUtils.getLoginUser();
        String taskId = null;

        if (ObjectHelper.isEmpty(tTrainMyManagement) ) {
            baseResponse.setData(Boolean.FALSE);
            return baseResponse;
        }
        String id = tTrainMyManagement.getId();
        TTrainMyManagement management = this.getById(id);
        if (ObjectHelper.isEmpty(management)) {
            baseResponse.setData(Boolean.FALSE);
            return baseResponse;
        }
        // 获取任务id 判读是否是自主学习课程
        taskId = management.getTaskId();
        // 存储课程信息
        List<TTrainCourse> course = null;
        //自主学习
        if ("2".equals(management.getLearnWay())) {
            // 此时任务taskId为课程id , 获取课程信息
            course = tTrainCourseService.getCourse(taskId);
        }
        //线下
        if ("1".equals(management.getLearnWay()) || "0".equals(management.getLearnWay())) {
            // 此时任务id taskId为培训计划id  获取培训计划
            TTrainProject project = tTrainProjectService.getById(taskId);
            // 获取计划关联的课程id , 多个课程用逗号隔开
            String courseId = project.getCourseId();
            course = tTrainCourseService.getCourse(courseId);
        }
        if (CollectionUtils.isEmpty(course)) {
            baseResponse.setData(Boolean.FALSE);
            return baseResponse;
        }
        // 交换集合
        List<TTrainCourseParam> collect = course.stream().map(bean -> bean.beanToBean(TTrainCourseParam.class)).collect(Collectors.toList());
        for (TTrainCourseParam tTrainCourseParam : collect) {
            //获取所有章节id
            List<Object> sectionIds = tTrainSectionService.listObjs(new QueryWrapper<TTrainSection>().select("id").in("course_id", tTrainCourseParam.getId()).eq("status", "0"));
            List<Object> nodeIds = tTrainSmallNodeDao.selectObjs(new QueryWrapper<TTrainSmallNode>().select("id").in("section_id", sectionIds));

            //设置进度百分比
            String coursePercentage = tTrainSmallNodeDao.getPercentageByNodeIds(sectionIds, nodeIds, loginUser.getUserId(), id);
            if (StringUtils.isBlank(coursePercentage) || !"100%".equals(coursePercentage)) {
                baseResponse.setData(Boolean.FALSE);
                return baseResponse;
            }
        }

        baseResponse.setData(Boolean.TRUE);
        return baseResponse;
    }


}
