package com.qmth.teachcloud.common.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.teachcloud.common.base.BaseEntity;
import com.qmth.teachcloud.common.bean.dto.BasicCourseExportDto;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
import com.qmth.teachcloud.common.bean.dto.excel.BasicCourseImportDto;
import com.qmth.teachcloud.common.bean.dto.excel.DescribeImportDto;
import com.qmth.teachcloud.common.bean.params.BasicCourseParams;
import com.qmth.teachcloud.common.bean.result.BasicCourseResult;
import com.qmth.teachcloud.common.bean.result.ClazzDatasourceResult;
import com.qmth.teachcloud.common.bean.result.SysUserResult;
import com.qmth.teachcloud.common.bean.result.TeachCourseSelectResult;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.*;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.mapper.BasicCourseMapper;
import com.qmth.teachcloud.common.service.*;
import com.qmth.teachcloud.common.util.ExcelUtil;
import com.qmth.teachcloud.common.util.JdbcErrorUtil;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 课程表 服务实现类
 * </p>
 *
 * @author xf
 * @since 2021-03-23
 */
@Service
public class BasicCourseServiceImpl extends ServiceImpl<BasicCourseMapper, BasicCourse> implements BasicCourseService {

    @Resource
    private BasicCourseMapper basicCourseMapper;

    @Resource
    private SysOrgService sysOrgService;

    @Resource
    private BasicUserCourseService basicUserCourseService;

    @Resource
    private BasicClazzService basicClazzService;

    @Resource
    private BasicRoleDataPermissionService basicRoleDataPermissionService;

    @Resource
    private BasicTeachCourseService basicTeachCourseService;

    @Resource
    private SysUserService sysUserService;

    @Override
    public List<BasicCourse> listCoursesByUserId(Long userId) {
        return this.baseMapper.listCoursesByUserId(userId);
    }

    @Override
    public BasicCourse findByCourseCode(String courseCode, Long schoolId) {
        BasicCourse basicCourse = this.getOne(
                new QueryWrapper<BasicCourse>().lambda().eq(BasicCourse::getCode, courseCode).eq(BasicCourse::getSchoolId, schoolId));
        if (Objects.isNull(basicCourse)) {
            throw ExceptionResultEnum.ERROR.exception("未找到课程编号为[" + courseCode + "]的基础课程");
        }
        return basicCourse;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createCourse(Long schoolId, String courseCode, String courseName) {
        // 向'basic_course'表新增数据 - 教研分析用
        List<BasicCourse> basicCourseList = this.list(
                new QueryWrapper<BasicCourse>().lambda().eq(BasicCourse::getSchoolId, schoolId).eq(BasicCourse::getCode, courseCode));
        if (basicCourseList.size() == 0) {
            BasicCourse basicCourse = new BasicCourse();
            basicCourse.setId(SystemConstant.getDbUuid());
            basicCourse.setCode(courseCode);
            basicCourse.setName(courseName);
            basicCourse.setSchoolId(schoolId);
            this.save(basicCourse);
        }
    }

    @Override
    public IPage<BasicCourseResult> basicCoursePage(Long belongOrgId, String courseName, Long startCreateTime, Long endCreateTime, int pageNumber, int pageSize) {
        Long schoolId = SystemConstant.convertIdToLong(ServletUtil.getRequestHeaderSchoolId().toString());

        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(),
                ServletUtil.getRequest().getServletPath());

        courseName = SystemConstant.translateSpecificSign(courseName);
        IPage<BasicCourseResult> iPage = basicCourseMapper.findBasicCoursePage(new Page<>(pageNumber, pageSize),
                belongOrgId, courseName, startCreateTime, endCreateTime, schoolId, dpr);
        List<BasicCourseResult> list = iPage.getRecords();
        for (BasicCourseResult basicCourseResult : list) {
            Long courseId = basicCourseResult.getId();
            List<BasicUserCourse> basicUserCourseList = basicUserCourseService.list(
                    new QueryWrapper<BasicUserCourse>().lambda().eq(BasicUserCourse::getCourseId, courseId));
            Set<Long> clazzIdSet = basicUserCourseList.stream().map(BasicUserCourse::getClazzId).collect(Collectors.toSet());
            List<ClazzDatasourceResult> clazzDatasourceResultList = new ArrayList<>();
            if (clazzIdSet.size() > 0) {
                List<BasicClazz> clazzList = basicClazzService.list(
                        new QueryWrapper<BasicClazz>().lambda().in(BasicClazz::getId, clazzIdSet).orderByAsc(BasicClazz::getCreateTime));
                for (BasicClazz clazz : clazzList) {
                    ClazzDatasourceResult clazzDatasourceResult = new ClazzDatasourceResult();
                    clazzDatasourceResult.setId(clazz.getId());
                    clazzDatasourceResult.setCode(clazz.getClazzCode());
                    clazzDatasourceResult.setName(clazz.getClazzName());
                    clazzDatasourceResultList.add(clazzDatasourceResult);
                }
                basicCourseResult.setClazzList(clazzDatasourceResultList);
            }

            List<BasicTeachCourse> basicTeachCourseList = basicTeachCourseService.list(
                    new QueryWrapper<BasicTeachCourse>().lambda().eq(BasicTeachCourse::getCourseId, courseId));
            if (!CollectionUtils.isEmpty(basicTeachCourseList)) {
                Set<Long> teachIdSet = basicTeachCourseList.stream().map(BasicTeachCourse::getUserId).collect(Collectors.toSet());
                List<SysUserResult> sysUserResultList = sysUserService.findCourseSysUserResultByTeachIdSet(teachIdSet);
                basicCourseResult.setTeachList(sysUserResultList);
            }
        }
        return iPage;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long saveBasicCourse(BasicCourseParams basicCourseParams, SysUser sysUser) {
        List<BasicCourseParams> basicCourseParamsList = new ArrayList<>();
        basicCourseParamsList.add(basicCourseParams);
        BasicCourse editBasicCourse = this.editEntityHelp(basicCourseParamsList, sysUser).get(0);
        try {
            this.saveOrUpdate(editBasicCourse);
            // 同步更新命题任务中的课程名称
            this.baseMapper.updateCourseNameFormExamTask(sysUser.getSchoolId(), editBasicCourse.getCode(),
                    editBasicCourse.getName());
            // 以下表中course_name要也同步更新
//            client_status,exam_card,exam_detail_course,exam_paper_structure,exam_task,exam_task_print
//            mark_document,mark_group,mark_paper,mark_paper_package,mark_student,mark_task,
//            t_b_sync_task,t_b_task,t_c_final_score,t_c_paper_struct,t_c_statistics,t_c_usual_score,t_r_basic_info
        } catch (Exception e) {
            if (e instanceof DataIntegrityViolationException || e instanceof BadSqlGrammarException) {
                String content = JdbcErrorUtil.parseErrorMsg(e.getMessage());
                throw ExceptionResultEnum.SQL_ERROR.exception(content);
            } else if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return editBasicCourse.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean removeBasicCourseBatch(List<Long> idList) {
        Long schoolId = SystemConstant.convertIdToLong(ServletUtil.getRequestHeaderSchoolId().toString());
        if (idList.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("请选择要目标");
        }
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        // 批量禁用判断
        // 业务判断
        Set<String> courseCodeSet = idList.stream().map(e -> {
            BasicCourse basicCourse = this.getById(e);
            if (Objects.isNull(basicCourse)) {
                throw ExceptionResultEnum.ERROR.exception("未找到课程");
            }
            return basicCourse.getCode();
        }).collect(Collectors.toSet());

        Map<String, String> courseMap = this.list(
                        new QueryWrapper<BasicCourse>().lambda().in(BasicCourse::getId, idList)).stream()
                .collect(Collectors.toMap(BasicCourse::getCode, BasicCourse::getName));
        // 考生字典数据不包含该课程校验
        List<String> basicExamStudentCourseNameList = basicCourseMapper.findBasicExamStudentCourseName(schoolId,
                courseCodeSet).stream().map(courseMap::get).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(basicExamStudentCourseNameList)) {
            throw ExceptionResultEnum.ERROR.exception(
                    String.format("考生字典中包含[%s]课程,不能删除", String.join(",", basicExamStudentCourseNameList)));
        }
        // 教学课程不包含该课程校验
        List<String> teachCourseCourseNameList = basicCourseMapper.findTeachCourseCourseName(schoolId, courseCodeSet).stream().map(courseMap::get).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(teachCourseCourseNameList)) {
            throw ExceptionResultEnum.ERROR.exception(
                    String.format("教学课程中包含[%s]课程,不能删除", String.join(",", teachCourseCourseNameList)));
        }

        // 命题任务不包含该课程校验
        Set<Map<String, Object>> mapList = basicCourseMapper.findExamTaskByCourseCode(schoolId, courseCodeSet);
        if (mapList.size() > 0) {
            StringBuilder courseNames = new StringBuilder();
            for (Map<String, Object> map : mapList) {
                courseNames.append(map.get("courseName")).append(",");
            }
            throw ExceptionResultEnum.ERROR.exception("课程[" + courseNames.substring(0, courseNames.length() - 1) + "]已经生成了命题任务，不允许删除");
        }
        // 课程批量删除
        basicUserCourseService.remove(
                new QueryWrapper<BasicUserCourse>().lambda().in(BasicUserCourse::getCourseId, idList).eq(BasicUserCourse::getSchoolId, sysUser.getSchoolId()));

        // 老师批量删除
        basicTeachCourseService.remove(
                new QueryWrapper<BasicTeachCourse>().lambda().in(BasicTeachCourse::getCourseId, idList).eq(BasicTeachCourse::getSchoolId, sysUser.getSchoolId()));
        return this.removeByIds(idList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean removeBasicCourseBatchByQuery(Long belongOrgId, String courseName, Long startCreateTime, Long endCreateTime) {
        QueryWrapper<BasicCourse> basicCourseQueryWrapper = new QueryWrapper<>();
        if (SystemConstant.longNotNull(belongOrgId)) {
            basicCourseQueryWrapper.lambda().eq(BasicCourse::getTeachingRoomId, belongOrgId);
        }
        if (SystemConstant.strNotNull(courseName)) {
            basicCourseQueryWrapper.lambda().like(BasicCourse::getName, SystemConstant.translateSpecificSign(courseName));
        }
        if (SystemConstant.longNotNull(startCreateTime)) {
            basicCourseQueryWrapper.lambda().ge(BasicCourse::getCreateTime, startCreateTime);
        }
        if (SystemConstant.longNotNull(endCreateTime)) {
            basicCourseQueryWrapper.lambda().le(BasicCourse::getCreateTime, endCreateTime);
        }
        List<BasicCourse> basicCourseList = this.list(basicCourseQueryWrapper);
        List<Long> idList = basicCourseList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());

        return idList.size() > 0 ? this.removeBasicCourseBatch(idList) : true;
    }

    @Override
    public List<BasicCourseParams> executeImportBasicCourseLogic(MultipartFile file) throws IOException, NoSuchFieldException {
        Map<Integer, List<String>> errorMap = new HashMap<>();
        InputStream inputStream = file.getInputStream();
        List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(inputStream, Lists.newArrayList(BasicCourseImportDto.class, DescribeImportDto.class),
                (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
                    Map<String, BasicCourseImportDto> courseDtoMap = new HashMap<>();
                    for (int i = 0; i < finalExcelList.size(); i++) {
                        LinkedMultiValueMap<Integer, Object> excelMap = finalExcelList.get(i);
                        List<Object> basicCourseImportDtoList = excelMap.get(i);
                        List<BasicCourseImportDto> duplicateData = new ArrayList<>();
                        for (int y = 0; y < Objects.requireNonNull(basicCourseImportDtoList).size(); y++) {
                            BasicCourseImportDto basicCourseImportDto = (BasicCourseImportDto) basicCourseImportDtoList.get(
                                    y);
                            basicCourseImportDto.setRowIndex(y + 1);
                            String courseName = basicCourseImportDto.getCourseName();
                            String courseCode = basicCourseImportDto.getCourseCode();
                            String teachingRoomName = basicCourseImportDto.getTeachingRoomName();

                            String emptyCheckError = ExcelUtil.checkExcelField(basicCourseImportDto);
                            if (SystemConstant.strNotNull(emptyCheckError)) {
                                if (errorMap.containsKey(y + 1)) {
                                    errorMap.get(y + 1).add(emptyCheckError);
                                } else {
                                    List<String> errorInfo = new ArrayList<>();
                                    errorInfo.add(emptyCheckError);
                                    errorMap.put(y + 1, errorInfo);
                                }
                            } else {
                                if (courseDtoMap.containsKey(courseCode)) {
                                    BasicCourseImportDto primaryCell = courseDtoMap.get(courseCode);
                                    String primaryName = primaryCell.getCourseName();
                                    String primaryTeachingRoomName = primaryCell.getTeachingRoomName();
                                    if (!Objects.equals(primaryName, courseName)) {
                                        String cellException = "课程编码[" + courseCode + "],存在不同的课程名称";
                                        this.updateErrorInfoMap(errorMap, y + 1, cellException);
                                    }
                                    if (!Objects.equals(primaryTeachingRoomName, teachingRoomName)) {
                                        String cellException = "课程编码[" + courseCode + "],存在不同的开课学院";
                                        this.updateErrorInfoMap(errorMap, y + 1, cellException);
                                    }
                                    duplicateData.add(basicCourseImportDto);
                                } else {
                                    courseDtoMap.put(courseCode, basicCourseImportDto);
                                }
                            }
                            if (Objects.nonNull(courseCode) && (!courseCode.matches(SystemConstant.REGULAR_EXPRESSION_OF_CODE)
                                    || courseCode.length() < 3 || courseCode.length() > 30)) {
                                this.updateErrorInfoMap(errorMap, y + 1, "课程编码[" + courseCode + "]不符合输入规范");
                            }
                        }
                        // 删除重复的（需要累加的）excel数据
                        basicCourseImportDtoList.removeAll(duplicateData);
                    }
                    return finalExcelList;
                }, 2);
        return this.executeBasicCourseImportLogic(finalList, errorMap);
    }

    private void updateErrorInfoMap(Map<Integer, List<String>> errorMap, Integer key, String exception) {
        if (errorMap.containsKey(key)) {
            errorMap.get(key).add(exception);
        } else {
            List<String> errorInfo = new ArrayList<>();
            errorInfo.add(exception);
            errorMap.put(key, errorInfo);
        }
    }

    /**
     * 解析异常信息
     *
     * @param exceptionMap 异常信息
     */
    private void analyzeException(Map<Integer, List<String>> exceptionMap) {
        System.out.println(JSON.toJSONString(exceptionMap));
        StringBuilder exception = new StringBuilder();
        for (Integer rowIndex : exceptionMap.keySet()) {
            String rowInfo;
            if (rowIndex > 0) {
                rowInfo = "excel中第[" + rowIndex + "]行 : ";
            } else {
                rowInfo = "excel中存在异常：";
            }
            List<String> exceptionList = exceptionMap.get(rowIndex);
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(exceptionList)) {
                for (String e : exceptionList) {
                    String cell = rowInfo + e + "\n";
                    exception.append(cell);
                }
            }
        }
        System.out.println(exception);
        if (exception.length() > 0) {
            throw ExceptionResultEnum.ERROR.exception(exception.toString());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<BasicCourseParams> executeBasicCourseImportLogic(List<LinkedMultiValueMap<Integer, Object>> finalList,
                                                                 Map<Integer, List<String>> errorMap) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        Long schoolId = sysUser.getSchoolId();
        List<BasicCourseParams> addBasicCourseParamsList = new ArrayList<>();
        for (int i = 0; i < finalList.size(); i++) {
            LinkedMultiValueMap<Integer, Object> excelMap = finalList.get(i);
            List<Object> basicCourseImportDtoList = excelMap.get(i);
            for (int y = 0; y < Objects.requireNonNull(basicCourseImportDtoList).size(); y++) {
                BasicCourseImportDto basicCourseImportDto = (BasicCourseImportDto) basicCourseImportDtoList.get(y);
                String courseName = basicCourseImportDto.getCourseName();
                String courseCode = basicCourseImportDto.getCourseCode();
                String teachingRoomName = basicCourseImportDto.getTeachingRoomName();

                // 原始excel中的行索引
                Integer rowIndex = basicCourseImportDto.getRowIndex();

                SysOrg sysOrg = sysOrgService.getOne(
                        new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getSchoolId, schoolId).eq(SysOrg::getEnable, true).eq(SysOrg::getName, teachingRoomName));
                if (Objects.isNull(sysOrg)) {
                    this.updateErrorInfoMap(errorMap, rowIndex, "输入的开课学院[" + teachingRoomName + "]不存在");
                    continue;
                }
                Long teachingRoomId = sysOrg.getId();

                BasicCourseParams basicCourseParams = new BasicCourseParams();
                basicCourseParams.setCourseCode(courseCode);
                basicCourseParams.setCourseName(courseName);
                basicCourseParams.setTeachingRoomId(teachingRoomId);
                BasicCourse old = this.getOne(
                        new QueryWrapper<BasicCourse>().lambda().eq(BasicCourse::getSchoolId, schoolId).eq(BasicCourse::getEnable, true).eq(BasicCourse::getCode, courseCode));
                if (Objects.nonNull(old)) {
                    basicCourseParams.setId(old.getId());
                }
                addBasicCourseParamsList.add(basicCourseParams);
            }
            // 解析异常
            this.analyzeException(errorMap);

            List<BasicCourse> editBasicCourse = this.editEntityHelp(addBasicCourseParamsList, sysUser);
            try {
                this.saveOrUpdateBatch(editBasicCourse);

                // 同步更新命题任务中的课程名称
                for (BasicCourse basicCourse : editBasicCourse) {
                    this.baseMapper.updateCourseNameFormExamTask(sysUser.getSchoolId(), basicCourse.getCode(),
                            basicCourse.getName());
                }
            } catch (Exception e) {
                if (e instanceof DataIntegrityViolationException || e instanceof BadSqlGrammarException) {
                    String content = JdbcErrorUtil.parseErrorMsg(e.getMessage());
                    throw ExceptionResultEnum.SQL_ERROR.exception(content);
                } else if (e instanceof ApiException) {
                    ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
                } else {
                    ResultUtil.error(e.getMessage());
                }
            }
        }
        return addBasicCourseParamsList;
    }

    @Override
    public Long getOrgIdBySchoolIdAndCourseCode(Long schoolId, String courseCode) {
        if (Objects.isNull(schoolId)) {
            schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        }
        QueryWrapper<BasicCourse> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId).eq(BasicCourse::getCode, courseCode);
        BasicCourse basicCourse = this.getOne(queryWrapper);
        if (Objects.isNull(basicCourse)) {
            throw ExceptionResultEnum.ERROR.exception("课程不存在");
        }

        return basicCourse.getTeachingRoomId();
    }

    @Override
    public void exportData(HttpServletResponse response, Long belongOrgId, String courseName, Long startCreateTime, Long endCreateTime) throws Exception {
        Long schoolId = SystemConstant.convertIdToLong(ServletUtil.getRequestHeaderSchoolId().toString());

        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(),
                ServletUtil.getRequest().getServletPath());

        courseName = SystemConstant.translateSpecificSign(courseName);
        List<BasicCourseExportDto> courseExportDtos = basicCourseMapper.listExportData(belongOrgId, courseName,
                startCreateTime, endCreateTime, schoolId, dpr);
        if (courseExportDtos.isEmpty()) {
            throw ExceptionResultEnum.ERROR.exception("没有可导出数据");
        }
        ExcelUtil.excelExport("课程数据", BasicCourseExportDto.class, courseExportDtos, response);
    }

    @Override
    public List<TeachCourseSelectResult> listByOrgId(Long orgId, Long examId, String courseName, SysUser requestUser) {
        List<Long> temp = new ArrayList<>();
        temp.add(orgId);

        Set<Long> orgIdSet = sysOrgService.findDeepOrgIdListByOrgIdList(temp);
        List<TeachCourseSelectResult> result = new ArrayList<>();
        if (orgIdSet.size() > 0) {
            // 全校学院级机构map
            Map<Long, String> collegeMap = new HashMap<>();
            for (Long teachRoomId : orgIdSet) {
                if (!collegeMap.containsKey(teachRoomId)) {
                    SysOrg sysOrg = sysOrgService.findCollegeLevelOrgByOrgId(teachRoomId);
                    if (Objects.nonNull(sysOrg)) {
                        collegeMap.put(teachRoomId, sysOrg.getName());
                    }
                }
            }
            // 查询本次考试已选择的课程编号
            List<String> occupiedCourseCodeList = this.baseMapper.findOccupiedCourseCode(examId, requestUser.getId());
            LambdaQueryWrapper<BasicCourse> lambda = new QueryWrapper<BasicCourse>().lambda();
            lambda.in(BasicCourse::getTeachingRoomId, orgIdSet).orderByAsc(BasicCourse::getOrgId);
            if(StringUtils.isNotBlank(courseName)){
                lambda.like(BasicCourse::getName, courseName);
            }
            result = this.list(lambda).stream().filter(e -> !occupiedCourseCodeList.contains(e.getCode())).flatMap(e -> {
                TeachCourseSelectResult teachCourseSelectResult = new TeachCourseSelectResult();
                teachCourseSelectResult.setBasicCourseId(e.getId());
                teachCourseSelectResult.setCourseName(e.getName());
                teachCourseSelectResult.setCourseCode(e.getCode());
                teachCourseSelectResult.setTeachCollegeName(collegeMap.get(e.getTeachingRoomId()));
                return Stream.of(teachCourseSelectResult);
            }).collect(Collectors.toList());
        }
        return result;
    }

    @Override
    public BasicCourse getByCode(String courseCode) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        QueryWrapper<BasicCourse> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId)
                .eq(BasicCourse::getCode, courseCode);
        return this.getOne(queryWrapper);
    }

    private List<BasicCourse> editEntityHelp(List<BasicCourseParams> basicCourseParamsList, SysUser sysUser) {
        Long schoolId = sysUser.getSchoolId();
        List<BasicCourse> basicCourseList = new ArrayList<>();
        for (BasicCourseParams basicCourseParams : basicCourseParamsList) {
            Long id = basicCourseParams.getId();
            String courseName = basicCourseParams.getCourseName();
            // 校验课程编号
            String courseCode = basicCourseParams.getCourseCode();
            BasicCourse checkCode = this.getOne(
                    new QueryWrapper<BasicCourse>().lambda().eq(BasicCourse::getCode, courseCode).eq(BasicCourse::getSchoolId, schoolId).eq(BasicCourse::getEnable, true));
            if (Objects.nonNull(checkCode)) {
                if (!checkCode.getId().equals(id)) {
                    throw ExceptionResultEnum.ERROR.exception("课程编码[" + courseCode + "]重复");
                }
            }
            // 校验教研室id
            Long teachingRoomId = basicCourseParams.getTeachingRoomId();
            //            if (Objects.isNull(sysOrgService.getOne(new QueryWrapper<SysOrg>().lambda()
            //                    .eq(SysOrg::getId, teachingRoomId)
            //                    .eq(SysOrg::getEnable, true)
            //                    .eq(SysOrg::getType, OrgTypeEnum.TEACHING_ROOM)))) {
            //                throw ExceptionResultEnum.ERROR.exception("所选教研室不存在");
            //            }
            // 校验班级

            //基础数据组装
            Long orgId;
            BasicCourse basicCourse = new BasicCourse();
            basicCourse.setName(courseName);
            basicCourse.setCode(courseCode);
            basicCourse.setTeachingRoomId(teachingRoomId);
            basicCourse.setSchoolId(schoolId);

            if (!SystemConstant.longNotNull(id)) {
                // 没有id -》新增
                id = SystemConstant.getDbUuid();
                basicCourse.setId(id);
                basicCourse.setCreateId(sysUser.getId());
                basicCourse.setEnable(true);
                // 生成简码
                String shortCode = createShortCode(schoolId);
                basicCourse.setShortCode(shortCode);
                orgId = sysUser.getOrgId();
            } else {
                // 有id -》 更新
                BasicCourse old = this.getById(id);
                if (Objects.isNull(old) || old.getEnable().equals(false)) {
                    throw ExceptionResultEnum.ERROR.exception("课程主键不存在或被禁用");
                }
                orgId = old.getOrgId();
                basicCourse.setId(id);
                basicCourse.setUpdateId(sysUser.getId());
            }
            basicCourseParams.setId(basicCourse.getId());
            basicCourse.setOrgId(orgId);

            basicCourseList.add(basicCourse);
        }
        return basicCourseList;
    }

    /**
     * 生成考试简码
     *
     * @param schoolId 学校ID
     */
    private String createShortCode(Long schoolId) {
        QueryWrapper<BasicCourse> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId);
        List<BasicCourse> basicCourses = this.baseMapper.selectList(queryWrapper);
        if (basicCourses.isEmpty()) {
            return "001";
        } else {
            Optional<BasicCourse> max = basicCourses.stream().filter(m -> StringUtils.isNotBlank(m.getShortCode())).max(Comparator.comparing(BasicCourse::getShortCode));
            if (!max.isPresent()) {
                return "001";
            }
            String maxShortCode = max.get().getShortCode();
            int shortCode = StringUtils.isBlank(maxShortCode) ? 0 : Integer.parseInt(maxShortCode);
            return String.format("%03d", shortCode + 1);
        }
    }
}
