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

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.util.pdf.CreatePdfNewUtil;
import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
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.ExamPrintPlanService;
import com.qmth.distributed.print.business.util.CreatePdfUtil;
import com.qmth.teachcloud.common.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.ExamTaskUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
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
    ExamTaskMapper examTaskMapper;
    @Resource
    ExamTaskDetailMapper examTaskDetailMapper;

    @Resource
    BasicAttachmentMapper basicAttachmentMapper;

    @Resource
    ExamCardMapper examCardMapper;

    @Resource
    BasicCardRuleService basicCardRuleService;

    @Resource
    AttachmentCommonService attachmentCommonService;

    @Resource
    CreatePdfUtil createPdfUtil;
    @Resource
    CreatePdfNewUtil createPdfNewUtil;
    @Resource
    private BasicRoleDataPermissionService basicRoleDataPermissionService;

    @Override
    public IPage<ExamTaskDetailDto> page(Long examId, String courseCode, String paperNumber, Long orgId, String userParam, Integer pageNumber, Integer pageSize) {
        Page<ExamTaskDetailDto> page = new Page<>(pageNumber, pageSize);
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(requestUser.getSchoolId(), requestUser.getId(), ServletUtil.getRequest().getServletPath());
        return examTaskMapper.listExamTaskDetailDownload(page, examId, courseCode, paperNumber, orgId, userParam, 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("没有未曝光试卷，无法下载");
        }


        // 收集处理试卷和题卡
        // 本地存储目录
        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<PaperInfoVo> paperInfoDtoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds());
            if (CollectionUtils.isEmpty(paperInfoDtoList)) {
                throw ExceptionResultEnum.ERROR.exception("试卷信息不存在");
            }

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

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

                // 题卡id
                String cardId = paperInfo.getCardId();
                // 题卡
                if (StringUtils.isNotBlank(cardId)) {
                    ExamCard examCard = examCardMapper.selectById(cardId);

                    String cardPath = rootPath + File.separator + examTask.getCourseName().replaceAll(" ", "") + 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;

                    // html
                    File htmlFile = new File(cardHtmlPath);
                    if (!htmlFile.exists()) {
                        htmlFile.getParentFile().mkdirs();
                        htmlFile.createNewFile();
                    }
                    String htmlContent = createPdfNewUtil.replaceBlankHtmlContent(examCard.getHtmlContent());
                    // 生成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 List<ExamTaskDetailDto> listExamQuery(Long semesterId, Long examId, Long orgId, String courseName, Set<Long> idSet, DataPermissionRule dpr) {
        return examTaskMapper.listExamTaskDetailDownloadByQuery(semesterId, examId, courseName, orgId, idSet, dpr);
    }

}
