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

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.qmth.distributed.print.business.bean.dto.*;
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.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.ExamCardDetailService;
import com.qmth.distributed.print.business.service.ExamPrintPlanService;
import com.qmth.distributed.print.business.util.CreatePdfUtil;
import com.qmth.distributed.print.business.util.HtmlToPdfUtil;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
import com.qmth.teachcloud.common.config.DictionaryConfig;
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.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.*;
import com.qmth.teachcloud.common.util.ConvertUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.FileCopyUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Service
public class DownloadServiceImpl implements DownloadService {
    private final static Logger log = LoggerFactory.getLogger(DownloadServiceImpl.class);

    @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;

    @Resource
    DictionaryConfig dictionaryConfig;

    @Resource
    private BasicRoleDataPermissionService basicRoleDataPermissionService;

    @Override
    public IPage<ExamTaskDetailDto> page(Long semesterId, Long examId, Long orgId, String courseName, Integer pageNumber, Integer pageSize) {
        Page<ExamTaskDetailDto> page = new Page<>(pageNumber, pageSize);
        Long schoolId = SystemConstant.convertIdToLong(String.valueOf(ServletUtil.getRequestHeaderSchoolId()));
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(), ServletUtil.getRequest().getServletPath());
        return examTaskMapper.listExamTaskDetailDownload(page, schoolId, semesterId, examId, courseName, orgId, dpr);
    }

    @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();

        // 收集处理试卷和题卡
        // 本地存储目录
        File fileTemp = null;
        String rootPath = null;
        try {
            fileTemp = SystemConstant.getFileTempVar(SystemConstant.ZIP_PREFIX);
            rootPath = fileTemp.getParent() + File.separator + System.currentTimeMillis();
            List<File> fileList = new ArrayList<>();
            List<String> unexposedPaperTypes = Arrays.asList(unexposedPaperType.split(","));
            List<ExamPaperInfoDto> paperInfoDtoList = JSONObject.parseArray(paperAttachmentIds, ExamPaperInfoDto.class);
            if (CollectionUtils.isEmpty(paperInfoDtoList)) {
                throw ExceptionResultEnum.ERROR.exception("试卷信息不存在");
            }

            for (ExamPaperInfoDto paperInfo : paperInfoDtoList) {
                String paperType = paperInfo.getName();
                if (!unexposedPaperTypes.contains(paperType)) {
                    continue;
                }

                // 试卷附件id
                Long attachmentId = paperInfo.getAttachmentId();
                if (attachmentId != null) {
                    // 试卷
                    BasicAttachment attachment = basicAttachmentMapper.selectById(attachmentId);
                    if (attachment == null) {
                        throw ExceptionResultEnum.ERROR.exception("附件数据异常");
                    }
                    String paperPath = rootPath + File.separator + examTask.getCourseName() + SystemConstant.HYPHEN + examTask.getCourseCode() + File.separator + examTask.getPaperNumber();
                    String fileName = "试卷" + "_" + attachment.getName() + "_" + paperType + attachment.getType();
                    fileList.add(attachmentCommonService.downloadFile(paperPath, fileName, attachment));
                }

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

                    String cardPath = rootPath + File.separator + examTask.getCourseName() + SystemConstant.HYPHEN + examTask.getCourseCode() + File.separator + examTask.getPaperNumber();
                    String cardHtmlPath = cardPath + File.separator + "题卡" + "_" + examTask.getCourseName() + "_" + paperType + SystemConstant.HTML_PREFIX;
                    String cardPdfPath = cardPath + File.separator + "题卡" + "_" + examTask.getCourseName() + "_" + paperType + 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.exists()) {
                        htmlFile.getParentFile().mkdirs();
                        htmlFile.createNewFile();
                    }
                    // 生成html文件
                    FileCopyUtils.copy(htmlContent.getBytes(StandardCharsets.UTF_8), htmlFile);
                    fileList.add(htmlFile);
                    // 转pdf文件
                    File pdfFile = new File(cardPdfPath);
                    if (!pdfFile.exists()) {
                        pdfFile.getParentFile().mkdirs();
                        pdfFile.createNewFile();
                    }
                    HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A3);
                    fileList.add(pdfFile);
                }
            }

            if (fileList.size() == 0) {
                throw ExceptionResultEnum.ERROR.exception("没有可导出文件");
            }
            String zipName = examTask.getCourseName() + "未曝光试卷" + SystemConstant.ZIP_PREFIX;
            attachmentCommonService.zipFiles(response, rootPath, zipName, fileList);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
        } finally {
            if (Objects.nonNull(fileTemp)) {
                fileTemp.delete();
            }
            ConvertUtil.delFolder(rootPath);
        }
    }

    @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 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<ExamPaperInfoDto> paperInfo = JSONObject.parseArray(examTaskDetailDto.getPaperAttachmentIds(), ExamPaperInfoDto.class);
                if (Objects.isNull(paperInfo)) {
                    throw ExceptionResultEnum.ERROR.exception("试卷信息不存在");
                }
                // 试卷信息
                for (ExamPaperInfoDto paper : paperInfo) {
                    Long cardId = paper.getCardId();
                    Long attachmentId = paper.getAttachmentId();
                    BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
                    String paperName = null;
                    String paperSuffix = null;
                    String paperPath = null;
                    if (Objects.nonNull(basicAttachment)) {
                        paperName = basicAttachment.getName();
                        paperSuffix = basicAttachment.getType();
                        JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
                        paperPath = (String) jsonObject.get(SystemConstant.PATH);
                    }
                    String paperType = paper.getName();

                    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(cardId);
                    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;
    }

}
