package com.emr.service.ipml;

import com.emr.dao.BatchExportMapper;
import com.emr.dao.ExportTaskDetailsMapper;
import com.emr.dao.ExportZdAssortMapper;
import com.emr.dto.DownloadPdfBloodDto;
import com.emr.service.BatchExportService;
import com.emr.util.Logger;
import com.emr.vo.ExportPdfVo;
import com.emr.vo.ExportTaskDetailsVo;
import com.emr.vo.ExportTaskVo;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @ClassName BatchExportServiceImpl
 * @Description 国家病历批量导出实现类
 * @Author linjj
 * @Date 2024/4/12 11:41
 * @Version 1.0
 */
@Service
public class BatchExportServiceImpl implements BatchExportService {
    private static Logger logger = new Logger();
    @Autowired
    BatchExportMapper batchExportMapper;
    @Autowired
    ExportTaskDetailsMapper exportTaskDetailsMapper;
    @Autowired
    private ExportZdAssortMapper exportZdAssortMapper;
    @Value("${export_pdf_hospital_info}")
    private String flieName;


    @Override
    public List<ExportTaskVo> selectAll(int taskState) {
        return batchExportMapper.selectAll(taskState);
    }

    @Override
    public String batchExportPdf(int taskid) throws Exception {
        //导出文件名
        String fileName=null;
        //根据taskid查询所有需要导出病历的住院号出院日期
        List<ExportTaskDetailsVo> taskList = exportTaskDetailsMapper.selectAllByTaskId(taskid);
        if (CollectionUtils.isEmpty(taskList)) {
            return "没有任务";
        }
        for (ExportTaskDetailsVo list : taskList) {
            try {
                //根据住院号出院日期查询需要导出病历路径
                List<String> masterIds = exportTaskDetailsMapper.getMasterId(list.getInpNo(), list.getDischargeDateTime());
                if (CollectionUtils.isEmpty(masterIds)) {
                    logger.log("病案号为：" + list.getInpNo() + "出院时间为:" + list.getDischargeDateTime() + "的病历找不到。");
                    continue;
                }
                for (String masterId : masterIds) {
                    List<ExportPdfVo> pdfPathList = exportZdAssortMapper.getPdfPath(masterId);
                    if (CollectionUtils.isEmpty(pdfPathList)){
                        logger.log("病案号为：" + list.getInpNo() + "出院时间为:" + list.getDischargeDateTime() + "的病历查询不到影像");
                        continue;
                    }
                    try {
                        //组织导出文件名
                        fileName = exportFlieName(list);
                    } catch (ParseException e) {
                        logger.log("保存失败！异常处理" + e.getMessage());
                        exportTaskDetailsMapper.upStatc(2,list.getId());
                    }
    //                downPdfResponse(fileName,response);
                    Boolean aBoolean = exportPdf(pdfPathList,fileName);
                    //为true时修改任务状态1完成2失败
                    if (aBoolean){
                        logger.log(list.getId()+"这个id导出失败");
                        exportTaskDetailsMapper.upStatc(1,list.getId());
                    }else {
                        exportTaskDetailsMapper.upStatc(2,list.getId());
                    }
                }
            } catch (Exception e) {
                logger.log(list.getId()+"这个id导出失败");
                logger.log("保存失败！异常处理" + e.getMessage());
                exportTaskDetailsMapper.upStatc(2,list.getId());
            }
        }
        return "下载完成";
    }


    private void downPdfResponse(String pdfName, HttpServletResponse response) {
        try {
            pdfName = java.net.URLEncoder.encode(pdfName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        response.reset();
        response.setContentType("application/pdf");
        response.setHeader("content-disposition", "attachment; filename=" + pdfName + ".pdf");
    }



    private static Boolean exportPdf(List<ExportPdfVo> pdfPathList,String fileName) {
        //上一个目录名称
        String lastOutline = null;
        //是否增加标签
        boolean outFlag = true;
        //标签顺序
        Integer outNum = 1;
        Integer pageNum=1;
        Document document = new Document();
        PdfCopy writer = null;
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("D://export//"+fileName+".pdf");
            writer = new PdfCopy(document,fileOutputStream);
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            cb.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 12);
            cb.beginText();
            cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "目录", 300, 780, 0);
            cb.endText();
            // 创建目录
            PdfOutline root = cb.getRootOutline();
            for (int i = 0; i < pdfPathList.size(); i++) {
                try {
                    String assortName = pdfPathList.get(i).getAssortName();
                    if (StringUtils.isNotBlank(lastOutline) && lastOutline.equals(assortName)) {
                        outFlag = false;
                    }
                    if (StringUtils.isBlank(lastOutline)) {
                        lastOutline = assortName;
                        outFlag=true;
                    }
                    if (!lastOutline.equals(assortName)){
                        lastOutline = assortName;
                        outFlag=true;
                    }
                    com.itextpdf.text.pdf.PdfReader reader = new PdfReader(pdfPathList.get(i).getPdfPath());
                    int n = reader.getNumberOfPages();
                    for (int s = 1; s <= n; s++) {
                        PdfImportedPage page = writer.getImportedPage(reader, s);
                        writer.addPage(page);
                    }
                    if (outFlag) {
                        //目录跳转页面内容设置。
                        PdfAction action = PdfAction.gotoLocalPage(pageNum, new PdfDestination(PdfDestination.FIT), writer);
                        //标题目录
                        String title = outNum+"."+pdfPathList.get(i).getAssortName();
                        new PdfOutline(root, action, title, false);
                        outNum++;
                    }
                    pageNum =pageNum+getPageNum(pdfPathList.get(i));
                } catch (Exception e) {
                    //报错删除错误文件
                    File file = new File("D://export//"+fileName+".pdf");
                    try {
                        file.delete(); // 删除照片
                    } catch (Exception c) {
                        c.printStackTrace();
                    }
                    return false;
                }
            }
        } catch (Exception e) {
        logger.log(e.getMessage());
        } finally {
            if (document != null) {
                document.close();
            }
        }
        document.close();
        return true;
    }


    //获取pdf页码
    private static int getPageNum(ExportPdfVo obj) {
        FileInputStream is;
        com.itextpdf.kernel.pdf.PdfReader pdfReader = null;
        int pages = 0;
        //创建File类
        File file = new File(obj.getPdfPath());
        //判断文件是否存在
        if (file.exists()) {
            try {
                is = new FileInputStream(file);
                pdfReader = new com.itextpdf.kernel.pdf.PdfReader(is);
                com.itextpdf.kernel.pdf.PdfDocument redDocument = new com.itextpdf.kernel.pdf.PdfDocument(pdfReader);
                pages = redDocument.getNumberOfPages();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return pages;
    }
    //生成文件名
    private  String exportFlieName(ExportTaskDetailsVo dto) throws ParseException {
        SimpleDateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat targetFormat = new SimpleDateFormat("yyyyMMdd");
        Date date = originalFormat.parse(dto.getDischargeDateTime());
        String formattedDate = targetFormat.format(date);
        return flieName + "_" + dto.getInpNo() + "_" + formattedDate;
    }
}
