package com.qmth.distributed.print.business.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
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.qmth.distributed.print.business.bean.dto.*;
import com.qmth.distributed.print.business.bean.params.DeleteParams;
import com.qmth.distributed.print.business.bean.params.PrintPlanParams;
import com.qmth.distributed.print.business.bean.params.SyncDataParam;
import com.qmth.distributed.print.business.bean.result.PrintPlanBrief;
import com.qmth.distributed.print.business.bean.result.PrintPlanResult;
import com.qmth.distributed.print.business.bean.result.TemplatePrintInfoResult;
import com.qmth.distributed.print.business.entity.*;
import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
import com.qmth.distributed.print.business.enums.ExamTaskSyncStatusEnum;
import com.qmth.teachcloud.common.entity.*;
import com.qmth.teachcloud.common.enums.MessageEnum;
import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
import com.qmth.distributed.print.business.enums.SyncCardTypeEnum;
import com.qmth.distributed.print.business.mapper.ExamPrintPlanMapper;
import com.qmth.distributed.print.business.service.*;
import com.qmth.distributed.print.business.templete.execute.AsyncCloudMarkingTaskService;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.enums.ClassifyEnum;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.SyncModeEnum;
import com.qmth.teachcloud.common.service.*;
import com.qmth.teachcloud.common.sync.CloudMarkingTaskUtils;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * <p>
 * 印刷计划管理 服务实现类
 * </p>
 *
 * @author xf
 * @since 2021-03-23
 */
@Service
public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, ExamPrintPlan> implements ExamPrintPlanService {

    @Resource
    private ExamPrintPlanMapper examPrintPlanMapper;

    @Resource
    private ExamDetailService examDetailService;

    @Resource
    private SysOrgService sysOrgService;

    @Resource
    private BasicSchoolService basicSchoolService;

    @Resource
    private ExamTaskService examTaskService;

    @Resource
    private BasicAttachmentService basicAttachmentService;

    @Resource
    private BasicExamRuleService basicExamRuleService;

    @Resource
    private BasicMessageService basicMessageService;

    @Resource
    private TBTaskService tbTaskService;

    @Resource
    private ClientPrintDataService clientPrintDataService;

    @Resource
    TeachcloudCommonService teachcloudCommonService;

    @Resource
    BasicCourseService basicCourseService;

    @Resource
    ExamDetailCourseService examDetailCourseService;

    @Resource
    AsyncCloudMarkingTaskService asyncCloudMarkingTaskService;

    @Resource
    CloudMarkingTaskUtils cloudMarkingTaskUtils;

    @Resource
    BasicTemplateService basicTemplateService;

    @Resource
    private BasicRoleDataPermissionService basicRoleDataPermissionService;

    @Resource
    TSyncStmmsExamService tSyncStmmsExamService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public IPage<PrintPlanResult> printPlanPage(Long schoolId, Long semesterId, Long examId, List<Long> printPlanIdList, PrintPlanStatusEnum status, Long startTime, Long endTime, int pageNumber, int pageSize) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(), ServletUtil.getRequest().getServletPath());
        IPage<PrintPlanResult> page = examPrintPlanMapper.findPrintPlanPage(new Page<>(pageNumber, pageSize), schoolId, semesterId, examId, printPlanIdList, status, startTime, endTime, dpr);
        List<PrintPlanResult> list = page.getRecords();
        for (PrintPlanResult printPlanResult : list) {
            List<Map> variableContent = JSONObject.parseArray(printPlanResult.getVariableContentTemp(), Map.class);
            List<Map> ordinaryContent = JSONObject.parseArray(printPlanResult.getOrdinaryContentTemp(), Map.class);
            printPlanResult.setVariableContent(variableContent);
            printPlanResult.setOrdinaryContent(ordinaryContent);

            double totalSubjects = examDetailService.calculateTotalSubjects(printPlanResult.getId());
            double totalPackages = examDetailService.calculateTotalPackages(printPlanResult.getId());
            printPlanResult.setTotalSubjects((int) totalSubjects);
            printPlanResult.setTotalPackages((int) totalPackages);
        }
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<PrintPlanBrief> printPlanBriefQuery(String source, String module) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        List<PrintPlanBrief> list;
        if ("client".equals(source)) {
            SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
            String[] status = {PrintPlanStatusEnum.READY.name(), PrintPlanStatusEnum.PRINTING.name(), PrintPlanStatusEnum.PRINT_FINISH.name()};
            list = this.baseMapper.listToClient(schoolId, source, module, status, sysUser.getOrgId());
        } else {
            Long privilegeId = ServletUtil.getCurrentPrivilegeId();
            DataPermissionRule dpr = new DataPermissionRule();
            // 未找到权限菜单，默认为本人权限
            SysUser sysUser = (SysUser) ServletUtil.getRequestUser();

            // 如果byAssignUser为true时，不能通过层级关系查询
            if (privilegeId == null) {
                dpr.setRequestUserId(sysUser.getId());
                dpr.setOrgIdSet(null);
            } else if ("44".equals(privilegeId.toString())){
                dpr = basicRoleDataPermissionService.findDataPermission(privilegeId);
            }else {
                dpr = basicRoleDataPermissionService.findDataPermission();
            }
            String[] status = {PrintPlanStatusEnum.NEW.name(), PrintPlanStatusEnum.READY.name()};
            list = this.baseMapper.list(schoolId, source, module, status, dpr);
        }
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> printPlanTemplateDatasource(Long requestSchoolId, Long userId) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        //1.根据userId，schoolId查出orgId(应该从requestUser 获取)
        Long schoolId = sysUser.getSchoolId();

        //2.根据orgId查询他的所有叶子id 并把这些id放入List<Long> ids
        List<Long> orgIds = sysOrgService.list(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getSchoolId, schoolId)).stream().map(SysOrg::getId).collect(Collectors.toList());

        //3.关联template和template_org表 查询出来orgIds所包含的所有模板并组装
        if (CollectionUtils.isEmpty(orgIds)) {
            return null;
        }
        List<TemplatePrintInfoResult> templateInfoList = basicTemplateService.findTemplateInfoByOrgIds(orgIds);
        Map<String, Object> result = new HashMap<>();

        // 变量印品
        List<Map<String, Object>> variable = new ArrayList<>();
        List<TemplatePrintInfoResult> variableList = templateInfoList.stream()
                .filter(e -> ClassifyEnum.SIGN == e.getTemplateClassify() || ClassifyEnum.PACKAGE == e.getTemplateClassify())
                .collect(Collectors.toList());
        for (ClassifyEnum value : ClassifyEnum.values()) {
            Map<String, Object> variableMap = new HashMap<>();
            List<TemplatePrintInfoResult> sourceList = variableList.stream().filter(e -> value.equals(e.getTemplateClassify())).collect(Collectors.toList());
            List<Map<String, Object>> templateList = new ArrayList<>();
            for (TemplatePrintInfoResult templatePrintInfoResult : sourceList) {
                Map<String, Object> printMap = new HashMap<>();
                printMap.put("id", String.valueOf(templatePrintInfoResult.getTemplateId()));
                printMap.put("name", templatePrintInfoResult.getTemplateName());
//                printMap.put("attachmentId", templatePrintInfoResult.getAttachmentId().toString());
                templateList.add(printMap);
            }
            if (templateList.size() > 0) {
                variableMap.put("type", value);
                variableMap.put("template", templateList);
                variable.add(variableMap);
            }
        }

        // 普通印品
        List<Map<String, Object>> ordinary = new ArrayList<>();
        List<TemplatePrintInfoResult> ordinaryList = templateInfoList.stream()
                .filter(e -> ClassifyEnum.CHECK_IN == e.getTemplateClassify())
                .collect(Collectors.toList());
        Map<String, Object> ordinaryMap = new HashMap<>();
        for (ClassifyEnum value : ClassifyEnum.values()) {
            List<TemplatePrintInfoResult> sourceList = ordinaryList.stream().filter(e -> value.equals(e.getTemplateClassify())).collect(Collectors.toList());
            List<Map<String, Object>> templateList = new ArrayList<>();
            for (TemplatePrintInfoResult templatePrintInfoResult : sourceList) {
                Map<String, Object> printMap = new HashMap<>();
                printMap.put("id", String.valueOf(templatePrintInfoResult.getTemplateId()));
                printMap.put("name", templatePrintInfoResult.getTemplateName());
                printMap.put("attachmentId", templatePrintInfoResult.getAttachmentId().toString());
                templateList.add(printMap);
            }
            if (templateList.size() > 0) {
                ordinaryMap.put("type", value);
                ordinaryMap.put("template", templateList);
                ordinary.add(ordinaryMap);
            }
        }

        result.put("variable", variable);
        result.put("ordinary", ordinary);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean savePrintPlan(PrintPlanParams printPlanParams) {
        boolean result;
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        Long id = printPlanParams.getId();
        Long schoolId = printPlanParams.getSchoolId();
        if (basicSchoolService.list(new QueryWrapper<BasicSchool>().lambda().eq(BasicSchool::getId, schoolId).eq(BasicSchool::getEnable, true)).size() != 1) {
            throw ExceptionResultEnum.ERROR.exception("学校被禁用或不存在");
        }

        // 校验是否印试卷和题卡
        List<String> printContentList = printPlanParams.getPrintContent();
        BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId(schoolId);
        if (Objects.isNull(basicExamRule)) {
            throw ExceptionResultEnum.ERROR.exception("未找到学校的通用规则");
        }

        ExamPrintPlan examPrintPlan = new ExamPrintPlan();
        BeanUtils.copyProperties(printPlanParams, examPrintPlan);
        String printContent = StringUtils.join(printContentList, ",");
        examPrintPlan.setPrintContent(printContent);
        examPrintPlan.setCreateId(sysUser.getId());
        examPrintPlan.setUpdateId(sysUser.getId());
        examPrintPlan.setOrgId(sysUser.getOrgId());

        //印刷计划名称唯一性
        QueryWrapper<ExamPrintPlan> printPlanQueryWrapper = new QueryWrapper<>();
        printPlanQueryWrapper.lambda().eq(ExamPrintPlan::getSchoolId, schoolId).eq(ExamPrintPlan::getName, examPrintPlan.getName());
        ExamPrintPlan printPlan = this.getOne(printPlanQueryWrapper);
        if (id == null || id == 0) {
            // 没有印刷计划id -> 新增印刷计划
            if (printPlan != null) {
                throw ExceptionResultEnum.ERROR.exception("印刷计划名称已存在");
            }
            examPrintPlan.setId(SystemConstant.getDbUuid());
            examPrintPlan.setStatus(PrintPlanStatusEnum.NEW);
            result = this.save(examPrintPlan);
        } else {
            // 包含印刷计划id -> 编辑印刷计划
            ExamPrintPlan tmp = this.getById(id);
            if (tmp == null) {
                throw ExceptionResultEnum.ERROR.exception("印刷计划id不存在");
            }
            if (printPlan != null && id.longValue() != printPlan.getId().longValue()) {
                throw ExceptionResultEnum.ERROR.exception("印刷计划名称已存在");
            }

            PrintPlanStatusEnum status = tmp.getStatus();
            if (!PrintPlanStatusEnum.NEW.equals(status) && !PrintPlanStatusEnum.READY.equals(status)) {
                throw ExceptionResultEnum.ERROR.exception("已经开始打印的印刷计划不能编辑");
            }
            // 学校id不能更改
            examPrintPlan.setSchoolId(tmp.getSchoolId());
            result = this.updateById(examPrintPlan);
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean removePrintPlan(DeleteParams deleteParams) {
        Long id = deleteParams.getId();
        ExamPrintPlan examPrintPlan = this.getById(id);
        if (examPrintPlan == null) {
            throw ExceptionResultEnum.ERROR.exception("要删除的项目计划不存在");
        }
        if (!PrintPlanStatusEnum.NEW.equals(examPrintPlan.getStatus())) {
            throw ExceptionResultEnum.ERROR.exception("只有'新建'状态的项目计划可以被删除");
        }
        if (!tbTaskService.countByPrintPlanIdAndEntityId(examPrintPlan.getSchoolId(), id, null)) {
            throw ExceptionResultEnum.ERROR.exception("要删除的印刷计划正在生成pdf中，无法删除");
        }
        examDetailService.deleteExaminationData(id, null);
        return this.removeById(id);
    }

    @Override
    public List<Map<String, String>> tempalteView(Long printPlanId) {
        ExamPrintPlan examPrintPlan = this.getById(printPlanId);
        String variableContent = examPrintPlan.getVariableContent();
        List<Map<String, String>> finalList = new ArrayList<>();
        List<Map> variableList = JSONObject.parseArray(variableContent, Map.class);
        for (Map variable : variableList) {
            finalList.add(getAttachment(variable));
        }

        String ordinaryContent = examPrintPlan.getOrdinaryContent();
        List<Map> ordinaryList = JSONObject.parseArray(ordinaryContent, Map.class);
        for (Map ordinary : ordinaryList) {
            finalList.add(getAttachment(ordinary));
        }
        return finalList;
    }

    @Override
    public IPage<ClientPrintTaskDto> listClientPrintTask(Page<ClientPrintTaskDto> page, Long schoolId, Long semesterId, Long examId, String machineCode, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Long orgId) {
        // 以下状态考场状态不可查询
        String[] examDetailStatus = new String[]{ExamDetailStatusEnum.NEW.name(), PrintPlanStatusEnum.READY.name()};
        IPage<ClientPrintTaskDto> clientPrintTaskDtoIPage = this.baseMapper.listClientPrintTask(page, schoolId, semesterId, examId, machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, orgId, examDetailStatus);
        for (ClientPrintTaskDto record : clientPrintTaskDtoIPage.getRecords()) {
            // 试卷、题卡
            String printContent = record.getPrintContent();
            record.setIncluedPaper(!StringUtils.isBlank(printContent) && printContent.contains("PAPER"));
            record.setIncluedCard(!StringUtils.isBlank(printContent) && printContent.contains("CARD"));

            //印品
            String variableContent = record.getVariableContent();
            List<Map> variableList = JSONObject.parseArray(variableContent, Map.class);
            record.setIncluedSign(false);
            record.setIncluedPackage(false);
            for (Map map : variableList) {
                String type = map.get("type").toString();
                String templateId = map.get("templateId").toString();
                if (ClassifyEnum.SIGN.name().equals(type) && StringUtils.isNotBlank(templateId)) {
                    record.setIncluedSign(true);
                }
                if (ClassifyEnum.PACKAGE.name().equals(type) && StringUtils.isNotBlank(templateId)) {
                    record.setIncluedPackage(true);
                }
            }
            String ordinaryContent = record.getOrdinaryContent();
            List<Map> ordinaryList = JSONObject.parseArray(ordinaryContent, Map.class);
            record.setIncluedCheckin(false);
            for (Map map : ordinaryList) {
                String type = map.get("type").toString();
                String templateId = map.get("templateId").toString();
                if (ClassifyEnum.CHECK_IN.name().equals(type) && StringUtils.isNotBlank(templateId)) {
                    record.setIncluedCheckin(true);
                }
            }

            // 班级
            String className = examDetailService.findClazzNamesByClazzIds(record.getClassId(), ",");
            record.setClassName(className);
        }
        return clientPrintTaskDtoIPage;
    }


    @Override
    public List<ClientPrintTaskDto> listClientPrintTask(Long schoolId, Long semesterId, Long examId, String machineCode, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Long orgId) {
        // 以下状态考场状态不可查询
        String[] examDetailStatus = new String[]{ExamDetailStatusEnum.NEW.name(), PrintPlanStatusEnum.READY.name()};
        return this.baseMapper.listClientPrintTask(schoolId, semesterId, examId, machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, orgId, examDetailStatus);
    }

    @Override
    public ClientPrintTaskTotalDto clientTaskTotalData(Long semesterId, Long examId, String printPlanId, Long orgId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, String machineCode) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
//        Set<Long> orgIds = teachcloudCommonService.listSubOrgIds(null);
        // 以下状态考场状态不可查询
        String[] examDetailStatus = new String[]{ExamDetailStatusEnum.NEW.name(), PrintPlanStatusEnum.READY.name()};
        ClientPrintTaskTotalDto clientPrintTaskTotalDto = this.baseMapper.clientTaskTotalData(schoolId, semesterId, examId, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, machineCode, orgId, examDetailStatus);

        if (clientPrintTaskTotalDto != null) {
            // 累计a3,a4
            List<ClientPrintData> list = clientPrintDataService.listBySchoolIdAndMachineCode(schoolId, machineCode);
            if (!list.isEmpty()) {
                int paperPages = list.stream().mapToInt(ClientPrintData::getPaperPages).sum();
                clientPrintTaskTotalDto.setHostPaperPages(paperPages / 2);
                int cardPages = list.stream().mapToInt(ClientPrintData::getCardPages).sum();
                clientPrintTaskTotalDto.setHostCardPages(cardPages / 2);
                int pagesA4 = list.stream().mapToInt(ClientPrintData::getPagesA4).sum();
                clientPrintTaskTotalDto.setHostPagesA4(pagesA4 / 2);
            }

            // 试卷总计
            String paperNumberStrs = clientPrintTaskTotalDto.getPaperNumberAndType();
            if (StringUtils.isNotBlank(paperNumberStrs)) {
                String[] paperNumbers = paperNumberStrs.split(",");
                Set<String> paperNumberSet = new HashSet<>(Arrays.asList(paperNumbers));
                clientPrintTaskTotalDto.setPaperCount(paperNumberSet.size());
            }
        }

        return clientPrintTaskTotalDto;
    }

    @Override
    public IPage<ClientPrintStatisticsDto> listClientPrintStatistics(Page<ClientPrintStatisticsDto> page, Long schoolId, Long semesterId, Long examId, String printPlanId, String examPlace, Long examStartTime, Long examEndTime, String courseCode, String paperNumber, Long orgId) {
        // 以下状态考场状态不可查询
        String[] examDetailStatus = new String[]{ExamDetailStatusEnum.NEW.name(), PrintPlanStatusEnum.READY.name()};
        return this.baseMapper.listClientPrintStatistics(page, schoolId, semesterId, examId, printPlanId, examPlace, examStartTime, examEndTime, courseCode, paperNumber, orgId, examDetailStatus);
    }

    @Override
    public ClientPrintStatisticsTotalDto clientStatisticsTotalData(Long orgId, Long semesterId, Long examId, Long printPlanId, String examPlace, Long examStartTime, Long examEndTime, String courseCode, String paperNumber) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
//        Set<Long> orgIds = teachcloudCommonService.listSubOrgIds(null);
        // 以下考场状态不可查询
        String[] examDetailStatus = new String[]{ExamDetailStatusEnum.NEW.name(), PrintPlanStatusEnum.READY.name()};
        ClientPrintStatisticsTotalDto clientPrintStatisticsTotalDto = this.baseMapper.clientStatisticsTotalData(schoolId, semesterId, examId, printPlanId, examPlace, examStartTime, examEndTime, courseCode, paperNumber, orgId, examDetailStatus);

        if (clientPrintStatisticsTotalDto != null) {
            String paperNumberStrs = clientPrintStatisticsTotalDto.getPaperNumberAndType();
            if (StringUtils.isNotBlank(paperNumberStrs)) {
                String[] paperNumbers = paperNumberStrs.split(",");
                Set<String> paperNumberSet = new HashSet<>(Arrays.asList(paperNumbers));
                clientPrintStatisticsTotalDto.setPaperCount(paperNumberSet.size());
            }
        }

        return clientPrintStatisticsTotalDto;
    }

    @Override
    public void syncDataCloud(SyncDataParam syncDataParam) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());

        List<SyncExamTaskDto> params = syncDataParam.getList();
        if (CollectionUtils.isEmpty(params)) {
            throw ExceptionResultEnum.ERROR.exception("请选择需要推送的数据");
        }

        if (Objects.isNull(syncDataParam.getThirdRelateId())
                && StringUtils.isBlank(syncDataParam.getThirdRelateName())) {
            throw ExceptionResultEnum.ERROR.exception("考试ID、考试名称至少选择一个");
        } else if (StringUtils.isNotBlank(syncDataParam.getThirdRelateName())
                && Objects.isNull(syncDataParam.getExamTime())) {
            throw ExceptionResultEnum.ERROR.exception("考试时间必填");
        }

        // 校验同步数据的所属学院（机构）是否为空
        checkSyncMode(syncDataParam);

        Long objectId = SystemConstant.getDbUuid();
        String examTime = Objects.isNull(syncDataParam.getExamTime()) ? null : DateUtil.format(new Date(syncDataParam.getExamTime()), CloudMarkingTaskUtils.DATE_FORMAT);
        asyncCloudMarkingTaskService.syncExamAndStudentAndCard(schoolId, objectId, syncDataParam.getThirdRelateId(), syncDataParam.getThirdRelateName(), examTime, params);
    }

    @Override
    public ExamPrintPlan findByExamDetailId(Long examDetailId) {
        ExamDetail examDetail = examDetailService.getById(examDetailId);
        if (Objects.isNull(examDetail)) {
            throw ExceptionResultEnum.ERROR.exception("未找到印刷考场数据");
        }
        ExamPrintPlan examPrintPlan = this.getById(examDetail.getPrintPlanId());
        if (Objects.isNull(examPrintPlan)) {
            throw ExceptionResultEnum.ERROR.exception("未找到印刷计划");
        }
        return examPrintPlan;
    }

//    @Override
//    public void sendNoticeUploadStructure(Long id, SysUser sysUser) {
//        List<ExamDetailCourse> examDetailCourses = examDetailService.listSyncPaperNumberByPrintPlanId(id);
//        for (ExamDetailCourse examDetailCours : examDetailCourses) {
//            ExamTask examTask = examTaskService.getByCourseCodeAndPaperNumber(examDetailCours.getSchoolId(), examDetailCours.getCourseCode(), examDetailCours.getPaperNumber());
//            basicMessageService.sendNoticeUploadStructure(examTask.getPaperNumber(), examTask.getCourseCode(), examTask.getCourseName(), examTask.getUserId(), MessageEnum.NOTICE_OF_UPLOAD_STRUCTURE, sysUser);
//        }
//    }

    @Override
    public List<ExamPrintPlan> findByPaperNumber(Long schoolId, String paperNumber) {
        Set<Long> examDetailIdSet = examDetailCourseService.list(new QueryWrapper<ExamDetailCourse>()
                        .lambda()
                        .eq(ExamDetailCourse::getSchoolId, schoolId)
                        .eq(ExamDetailCourse::getPaperNumber, paperNumber))
                .stream()
                .map(ExamDetailCourse::getExamDetailId)
                .collect(Collectors.toSet());

        Set<Long> examPrintPlanIdSet = new HashSet<>();
        if (examDetailIdSet.size() > 0) {
            examPrintPlanIdSet = examDetailService.list(new QueryWrapper<ExamDetail>()
                            .lambda()
                            .in(ExamDetail::getId, examDetailIdSet))
                    .stream()
                    .map(ExamDetail::getPrintPlanId)
                    .collect(Collectors.toSet());
        }

        List<ExamPrintPlan> examPrintPlanList = new ArrayList<>();
        if (examPrintPlanIdSet.size() > 0) {
            examPrintPlanList = this.list(new QueryWrapper<ExamPrintPlan>().lambda().in(ExamPrintPlan::getId, examPrintPlanIdSet));
        }
        return examPrintPlanList;
    }

    @Override
    public List<ExamPrintPlan> listBySchoolId(Long schoolId) {
        QueryWrapper<ExamPrintPlan> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ExamPrintPlan::getSchoolId, schoolId);
        return this.list(queryWrapper);
    }

    @Override
    public IPage<SyncExamTaskDto> listSyncExamTask(Long semesterId, Long examId, Long orgId, SyncCardTypeEnum cardType, ExamTaskSyncStatusEnum syncStatus, String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
        return examDetailCourseService.listSyncCourseByPrintPlanId(semesterId, examId, orgId, cardType, syncStatus, courseCode, paperNumber, startTime, endTime, pageNumber, pageSize);
    }

    @Override
    public void checkSyncMode(SyncDataParam syncDataParam) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        if (cloudMarkingTaskUtils.isCollegeMode(schoolId)) {
            // 查询科目所属学院是否一致
            for (SyncExamTaskDto param : syncDataParam.getList()) {
                if (param.getCollegeCode() == null) {
                    throw ExceptionResultEnum.ERROR.exception(String.format("未找到课程[%s（%s）]所属学院", param.getCourseName(), param.getCourseCode()));
                }
            }
        }
    }


    /**
     * 查找子机构
     *
     * @param ids        上级机构id集合
     * @param schoolId   学校id
     * @param resultList 已查询所有子机构id集合
     * @return 所有子机构id集合
     */
    private List<Long> dp(List<Long> ids, Long schoolId, List<Long> resultList) {
        resultList.addAll(ids);
        for (Long id : ids) {
            List<SysOrg> childList = sysOrgService.list(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getParentId, id).eq(SysOrg::getSchoolId, schoolId));
            if (childList.size() > 0) {
                List<Long> childIds = childList.stream().map(SysOrg::getId).collect(Collectors.toList());
                this.dp(childIds, schoolId, resultList);
            }
        }
        return resultList;
    }

    public Map<String, String> getAttachment(Map map) {
        Map<String, String> fMap = new HashMap<>();
        fMap.put("type", map.get("type").toString());
        String attachmentId = map.get("attachmentId").toString();
        BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
        if (attachment.getType().equals(SystemConstant.FTL_PREFIX) || attachment.getType().equals(SystemConstant.HTML_PREFIX)) {
            String content = teachcloudCommonService.readFileContent(attachment.getPath());
            fMap.put("content", content);
            fMap.put("utl", null);
        } else if (attachment.getType().equals(SystemConstant.PDF_PREFIX)) {
            fMap.put("content", null);
            Map<String, String> stringMap = teachcloudCommonService.filePreviewByAttachmentId(Long.valueOf(attachmentId), false);
            fMap.putAll(stringMap);
        } else {
            throw ExceptionResultEnum.ERROR.exception("不支持的类型");
        }
        return fMap;
    }
}
