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

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qmth.distributed.print.business.bean.dto.ExamTaskDetailDto;
import com.qmth.distributed.print.business.entity.*;
import com.qmth.distributed.print.business.enums.MakeMethodEnum;
import com.qmth.distributed.print.business.mapper.ExamCardMapper;
import com.qmth.distributed.print.business.mapper.ExamTaskDetailMapper;
import com.qmth.distributed.print.business.bean.dto.ExamTaskPaperDto;
import com.qmth.distributed.print.business.bean.dto.ExamTaskPaperExportDto;
import com.qmth.distributed.print.business.bean.dto.ExamTaskPaperFileDto;
import com.qmth.distributed.print.business.entity.ExamPrintPlan;
import com.qmth.distributed.print.business.mapper.ExamTaskMapper;
import com.qmth.distributed.print.business.service.BasicCardRuleService;
import com.qmth.distributed.print.business.service.DownloadService;
import com.qmth.distributed.print.business.service.ExamPrintPlanService;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicAttachment;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.service.BasicAttachmentService;
import com.qmth.distributed.print.business.service.ExamCardDetailService;
import com.qmth.distributed.print.business.util.CreatePdfUtil;
import com.qmth.distributed.print.business.util.HtmlToPdfUtil;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicAttachment;
import com.qmth.teachcloud.common.enums.CardCreateMethodEnum;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.PageSizeEnum;
import com.qmth.teachcloud.common.mapper.BasicAttachmentMapper;
import com.qmth.teachcloud.common.service.AttachmentCommonService;
import com.qmth.teachcloud.common.service.SysOrgService;
import com.qmth.teachcloud.common.service.TeachcloudCommonService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;

import javax.annotation.Resource;
import java.util.*;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

@Service
public class DownloadServiceImpl implements DownloadService {

    @Resource
    TeachcloudCommonService teachcloudCommonService;

    @Resource
    ExamTaskMapper examTaskMapper;

    @Resource
    BasicAttachmentService basicAttachmentService;

    @Resource
    ExamPrintPlanService examPrintPlanService;

    @Resource
    ExamTaskDetailMapper examTaskDetailMapper;

    @Resource
    BasicAttachmentMapper basicAttachmentMapper;

    @Resource
    ExamCardMapper examCardMapper;

    @Resource
    ExamCardDetailService examCardDetailService;

    @Resource
    BasicCardRuleService basicCardRuleService;

    @Resource
    AttachmentCommonService attachmentCommonService;

    @Resource
    CreatePdfUtil createPdfUtil;

    @Resource
    SysOrgService sysOrgService;

    @Override
    public IPage<ExamTaskDetailDto> page(Long semesterId, Long examId, Long orgId, String courseName, Integer pageNumber, Integer pageSize) {
        Page<ExamTaskDetailDto> page = new Page<>(pageNumber, pageSize);
        Set<Long> orgIds = null;
        if (orgId != null) {
            orgIds = teachcloudCommonService.listSubOrgIds(orgId);
        }
        return examTaskMapper.listExamTaskDetailDownload(page, semesterId, examId, courseName, orgIds);
    }

    @Override
    public void paperDownload(HttpServletResponse response, Long id) throws Exception {
        ExamTask examTask = examTaskMapper.selectById(id);
        QueryWrapper<ExamTaskDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, id);
        ExamTaskDetail examTaskDetail = examTaskDetailMapper.selectOne(queryWrapper);
        if (examTaskDetail == null) {
            throw ExceptionResultEnum.ERROR.exception("数据异常");
        }
        // 只下载未曝光试卷
        String unexposedPaperType = examTaskDetail.getUnexposedPaperType();
        if (StringUtils.isBlank(unexposedPaperType)) {
            throw ExceptionResultEnum.ERROR.exception("没有未曝光试卷，无法下载");
        }
        String paperAttachmentIds = examTaskDetail.getPaperAttachmentIds();
        List<JSONObject> jsonObjectList = JSONObject.parseArray(paperAttachmentIds, JSONObject.class);
        // 本地存储目录
        String rootPath = SystemConstant.TEMP_FILES_DIR + File.separator + System.currentTimeMillis();
        List<File> fileList = new ArrayList<>();
        // 试卷
        List<String> unexposedPaperTypes = Arrays.asList(unexposedPaperType.split(","));
        for (JSONObject jsonObject : jsonObjectList) {
            String attachmentId = jsonObject.get("attachmentId").toString();
            String name = jsonObject.get("name").toString();
            if (!unexposedPaperTypes.contains(name)) {
                continue;
            }
            BasicAttachment attachment = basicAttachmentMapper.selectById(attachmentId);
            if (attachment == null) {
                throw ExceptionResultEnum.ERROR.exception("附件数据异常");
            }
            String paperPath = rootPath + File.separator + examTask.getCourseName() + "-" + examTask.getCourseCode() + File.separator + examTask.getPaperNumber();
            String fileName = "试卷" + "_" + attachment.getName() + "_" + name + attachment.getType();
            fileList.add(attachmentCommonService.downloadFile(paperPath, fileName, attachment));
        }

        // 题卡
        Long cardId = examTaskDetail.getCardId();
        if (cardId != null) {
            ExamCard examCard = examCardMapper.selectById(cardId);

            String cardPath = rootPath + File.separator + examTask.getCourseName() + "-" + examTask.getCourseCode() + File.separator + examTask.getPaperNumber();
            String cardHtmlPath = cardPath + File.separator + "题卡" + "_" + examTask.getCourseName() + SystemConstant.HTML_PREFIX;
            String cardPdfPath = cardPath + File.separator + "题卡" + "_" + examTask.getCourseName() + SystemConstant.PDF_PREFIX;

            ExamCardDetail examCardDetail = examCardDetailService.getByCardId(examCard.getId());
            String htmlContent;
            // 通用模板
            if (MakeMethodEnum.SELECT.equals(examCard.getMakeMethod()) && CardCreateMethodEnum.UPLOAD.equals(examCard.getCreateMethod())) {
                htmlContent = createPdfUtil.resetHtmlTemplateBar(examCardDetail.getHtmlContent());
            } else {
                BasicCardRule basicCardRule = basicCardRuleService.getById(examTask.getCardRuleId());
                htmlContent = createPdfUtil.replaceHtmlCard(examCardDetail, basicCardRule);
            }

            // html
            File htmlFile = new File(cardHtmlPath);
            if (!htmlFile.getParentFile().exists()) {
                htmlFile.getParentFile().mkdirs();
            }
            // 生成html文件
            FileCopyUtils.copy(htmlContent.getBytes(), htmlFile);
            fileList.add(htmlFile);
            // 转pdf文件
            File pdfFile = new File(cardPdfPath);
            if (!pdfFile.exists()) {
                pdfFile.createNewFile();
            }
            HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A3);
            fileList.add(pdfFile);
        }
        if (fileList.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("没有可导出文件");
        }
        String zipName = examTask.getCourseName() + "未曝光试卷.zip";
        attachmentCommonService.zipFiles(response, rootPath, zipName, fileList);
    }

    @Override
    public ExamTaskPaperDto findDownloadContent(Long schoolId, Long semesterId, Long examId, Long orgId, String pCourseName, Set<Long> idSet) {
        // 没有选择id集合才根据查询条件查询
        List<ExamTaskDetailDto> examTaskDetailDtoList;
        if (idSet != null && idSet.size() > 0) {
            examTaskDetailDtoList = examTaskMapper.listExamTaskDetailDownloadByQuery(null, null, null, null, idSet);
        } else {
            Set<Long> orgIds = null;
            if (orgId != null) {
                List<Long> orgList = new ArrayList<>();
                orgList.add(orgId);
                orgIds = sysOrgService.findDeepOrgIdListByOrgIdList(orgList);
            }
            examTaskDetailDtoList = examTaskMapper.listExamTaskDetailDownloadByQuery(semesterId, examId, pCourseName, orgIds, null);
        }

        List<ExamTaskPaperFileDto> examTaskPaperFileDtoList = new ArrayList<>();
        // 创建导出接收集合
        List<ExamTaskPaperExportDto> examTaskPaperExportDtoList = new ArrayList<>();

        if (examTaskDetailDtoList.size() > 0){
            for (ExamTaskDetailDto examTaskDetailDto : examTaskDetailDtoList) {
                Long examTaskId = SystemConstant.convertIdToLong(examTaskDetailDto.getId());
                String semesterName = examTaskDetailDto.getSemesterName();
                String examName = examTaskDetailDto.getExamName();
                String orgName = examTaskDetailDto.getOrgName();
                String courseCode = examTaskDetailDto.getCourseCode();
                String courseName = examTaskDetailDto.getCourseName();
                String paperNumber = examTaskDetailDto.getPaperNumber();
                Long examCardId= examTaskDetailDto.getExamCardId();
                Long cardRuleId = SystemConstant.convertIdToLong(examTaskDetailDto.getCardRuleId());

                // 生成导出对象
                ExamTaskPaperExportDto examTaskPaperExportDto = new ExamTaskPaperExportDto();
                examTaskPaperExportDto.setCourseCode(courseCode);
                examTaskPaperExportDto.setCourseName(courseName);
                examTaskPaperExportDto.setPaperNumber(paperNumber);
                examTaskPaperExportDto.setPaperType(examTaskDetailDto.getPaperType());
                examTaskPaperExportDto.setUnexposedPaperType(examTaskDetailDto.getUnexposedPaperType());
                examTaskPaperExportDtoList.add(examTaskPaperExportDto);


                // 所属印刷计划信息
                List<ExamPrintPlan> examPrintPlanList = examPrintPlanService.findByPaperNumber(schoolId,paperNumber);


                // 处理试卷
                List<String> exposedPaperTypeList = Arrays.asList(examTaskDetailDto.getExposedPaperType().split(","));
                List<String> unexposedPaperTypeList = Arrays.asList(examTaskDetailDto.getUnexposedPaperType().split(","));

                List<Map> paperInfo = JSONObject.parseArray(examTaskDetailDto.getPaperAttachmentIds(), Map.class);
                if (Objects.isNull(paperInfo)) {
                    throw ExceptionResultEnum.ERROR.exception("试卷信息不存在");
                }
                 // 试卷信息
                for (Map paper : paperInfo) {
                    Long attachmentId = SystemConstant.convertIdToLong(String.valueOf(paper.get("attachmentId")));
                    BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
                    String paperType = String.valueOf(paper.get("name"));
                    String paperName = basicAttachment.getName();
                    String paperSuffix = basicAttachment.getType();
                    JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
                    String paperPath = (String) jsonObject.get(SystemConstant.PATH);

                    boolean exposureStatus;
                    if (exposedPaperTypeList.contains(paperType)){
                        exposureStatus = true;
                    }else if (unexposedPaperTypeList.contains(paperType)){
                        exposureStatus = false;
                    }else {
                        throw ExceptionResultEnum.ERROR.exception("命题任务曝光卷型异常【" + examTaskId + "(" + paperType + ")】");
                    }



                    ExamTaskPaperFileDto cell = new ExamTaskPaperFileDto();
                    // 基本信息
                    cell.setExamTaskId(examTaskId);
                    cell.setSemesterName(semesterName);
                    cell.setExamName(examName);
                    cell.setOrgName(orgName);
                    // 基础信息
                    cell.setExamPrintPlanList(examPrintPlanList);
                    cell.setCourseCode(courseCode);
                    cell.setCourseName(courseName);
                    cell.setPaperNumber(paperNumber);
                    // 题卡
                    cell.setExamCardId(examCardId);
                    cell.setCardRuleId(cardRuleId);
                    // 试卷
                    cell.setPaperType(paperType);
                    cell.setExposureStatus(exposureStatus);
                    cell.setPaperName(paperName);
                    cell.setPaperSuffix(paperSuffix);
                    cell.setPaperPath(paperPath);
                    examTaskPaperFileDtoList.add(cell);
                }
            }
        }
        ExamTaskPaperDto result = new ExamTaskPaperDto();
        result.setExamTaskPaperFileDtoList(examTaskPaperFileDtoList);
        result.setExamTaskPaperExportDtoList(examTaskPaperExportDtoList);
        return result;
    }

}
