package com.ann.demo.service;

import com.ann.demo.entity.filing.ArchiveDetail;
import com.ann.demo.entity.filing.dto.MessageDto;
import com.ann.demo.entity.interfaceEntity.ArchiveMaster;
import com.ann.demo.entity.interfaceEntity.CommonTable;
import com.ann.demo.entity.interfaceEntity.CommonTable1;
import com.ann.demo.entity.normalEntity.OutPara;
import com.ann.demo.primaryRepository.ScanningFileRepository;
import com.ann.demo.primaryEntity.ScanningFile;
import com.ann.demo.repository.ArchiveDetailRepository;
import com.ann.demo.repository.CommonTable1Repository;
import com.ann.demo.repository.CommonTableRepository;
import com.ann.demo.utils.*;
import com.itextpdf.text.DocumentException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;


/**
 * 解析逻辑
 *
 * @Author: LeiJiaXin
 * @Date: 2019/8/20 16:29
 */
@Component
public class AnalysisService {

    final Logger logger = LoggerFactory.getLogger(AnalysisService.class);

    public static volatile LinkedBlockingQueue<ScanningFile> queue = new LinkedBlockingQueue<>();// 消息队列
    @Autowired
    private ScanningFileRepository scanningFileRepository;

    @Autowired
    private ArchiveDetailService archiveDetailService;

    @Autowired
    private CommonTableRepository commonTableRepository;

    @Autowired
    private CommonTable1Repository commonTable1Repository;

    @Autowired
    private ArchiveMasterService archiveMasterService;

    @Autowired
    private ArchiveDetailRepository archiveDetailRepository;
    public void handleScanningFile(List<ScanningFile> scanningFileList) {
        if(!CollectionUtils.isEmpty(scanningFileList)) {
            //处理ScanningFile\
            for (int i = 0;i < scanningFileList.size();i++) {
                queue.add(scanningFileList.get(i));
            }
        }
    }
/*
    public void handleScanningFile(List<ScanningFile> scanningFileList) {
        LocalDateTime beginTime = LocalDateTime.now();
        logger.error("开始时间:"+beginTime);
        //处理ScanningFile\
        for (ScanningFile scanningFile: scanningFileList) {
            String remark = null;
            String status = "1";
            try{
                remark = handlePdfFile(scanningFile);
            }catch (Exception e){
                remark = e.getMessage();
                logger.error("处理扫描文件出错：{}" ,e.getMessage());
            }

            if(remark != null){
                status = "2";
            }else{
                remark = LocalDateTime.now().toString();
            }
            scanningFile.setRemark(remark);
            scanningFile.setStatus(status);
            scanningFileRepository.save(scanningFile);

            LocalDateTime handleTime = LocalDateTime.now();
            logger.error("每一条处理时间:"+handleTime);
        }
        LocalDateTime endTime = LocalDateTime.now();
        logger.error("结束时间:"+endTime);

    }
*/
    public void startThread(int i){
        try {
            ScanningFile scanningFile = queue.take();
            handlePdfFile(scanningFile,i);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private String savaHomePageData(ScanningFile scanningFile){
        String masterId = null;
        // 判断病案首页数据是否存在
        try {
            masterId = scanningFile.getApplyId() != null ? scanningFile.getApplyId() : UUID.randomUUID().toString();;
            CommonTable commonTable = commonTableRepository.findByInpNoAndVisitId(scanningFile.getInpNo(), scanningFile.getVisitId());
            if(null != commonTable) {
                logger.error("commomtable.patientId=" + commonTable.getPatientId());
            }
            if(commonTable == null){
                commonTable = new CommonTable(masterId,scanningFile.getPatientId(),scanningFile.getAge(),scanningFile.getSex(),scanningFile.getVisitId(),scanningFile.getName(),
                        scanningFile.getAdmissDate(),scanningFile.getDisDate(),scanningFile.getDisDept(),scanningFile.getAttending(),scanningFile.getInpNo(),"扫描系统");
    //            //保存公共表
                commonTableRepository.save(commonTable);
                //保存公共表1
                commonTable1Repository.save( new CommonTable1(commonTable.getMasterId(),scanningFile.getBirthday(),scanningFile.getIdCard(),scanningFile.getAdmissDept(),scanningFile.getAdmissDoctor()));
            }else{
                masterId = commonTable.getMasterId();
            }
        } catch (Exception e) {
            logger.error("保存首页数据出错了,FBIHID="+scanningFile.getInpNo() + "&FBINCU="+scanningFile.getVisitId());
            e.printStackTrace();
            throw new RuntimeException("保存首页数据出错了,FBIHID="+scanningFile.getInpNo() + "&FBINCU="+scanningFile.getVisitId());
        }
        logger.error("masterId="+masterId);
        return masterId;
    }


    private void handlePdfFile(ScanningFile scanningFile,int i){
        //保存首页数据
        long start = System.currentTimeMillis();
        long start1 = System.currentTimeMillis();
        String masterId = savaHomePageData(scanningFile);
        long end = System.currentTimeMillis();
        logger.error("保存首页数据:FBIHID=" + scanningFile.getInpNo() + "&FBINCU="+scanningFile.getVisitId()+"所用时间:"+(end-start)/1000.00+"s");
        //根据住院号和住院次数查询文件集合
        //保存图片并更新scanningFile表数据
        savePdfDetail(scanningFile,masterId);
        long end1 = System.currentTimeMillis();
        logger.error("完成同步:FBIHID=" + scanningFile.getInpNo() + "&FBINCU="+scanningFile.getVisitId()+"所用时间:"+(end1-start1)/1000.00+"s");
        logger.error("剩余待处理记录数:" + i);
    }

    public static void main(String[] args) throws Exception{
        for(int i = 0;i<100000;i++) {
            long start = System.currentTimeMillis();
            Object[] objects = WebServiceUtils.connect("123");
            long end = System.currentTimeMillis();
            System.out.println("("+(100000-i)+")调用webService接口所用时间:" + (end - start) / 1000.00 + "s");
        }
    }

    private void savePdfDetail(ScanningFile scanningFile,String masterId) {
        if(StringUtils.isNotBlank(masterId)) {
            //根据住院号、住院次数查询文件明细
            List<ScanningFile> scanningFiles = scanningFileRepository.findScanningFileDetailList(scanningFile.getInpNo(), scanningFile.getVisitId());
            //处理ScanningFile
            String remark = "";
            //定义分组的文件明细map
            Map<String, ScanningFile> fileMap = new HashMap<>();
            //定义文件明细id集合
            List<Long> ids = new ArrayList<>();
            for (ScanningFile obj : scanningFiles) {
                ids.add(obj.getId());
                if (StringUtils.isBlank(remark)) {
                    //获取文件名称
                    String realFileName = obj.getRealFileName();
                    List<byte[]> byteList = new ArrayList<>();
                    try {
                        long start = System.currentTimeMillis();
                        Object[] objects = WebServiceUtils.connect(obj.getPath() + "\\" + obj.getFileName());
                        logger.error("objects:" + objects[0] + "&obj:" + obj.getId());
                        long end = System.currentTimeMillis();
                        logger.error("调用webService接口返回图片流:FBIHID=" + scanningFile.getInpNo() + "&FBINCU=" + scanningFile.getVisitId() + "所用时间:" + (end - start) / 1000.00 + "s");
                        if (fileMap.containsKey(realFileName)) {
                            //获取缓存scanningFile对象
                            obj = fileMap.get(realFileName);
                            //获取缓存字节流
                            byteList = obj.getByteList();
                        }
                        byteList.add((byte[]) objects[0]);
                        obj.setByteList(byteList);
                        fileMap.put(realFileName, obj);
                    } catch (Exception e) {
                        remark = e.getMessage();
                        e.printStackTrace();
                        logger.error("调用webService出错了:FBIHID=" + scanningFile.getInpNo() + "&FBINCU=" + scanningFile.getVisitId());
                        throw new RuntimeException("调用webService出错了:FBIHID=" + scanningFile.getInpNo() + "&FBINCU=" + scanningFile.getVisitId());
                    }
                }
            }
            logger.error("fileMap:" + fileMap.toString());
            //定义批量添加detail集合
            List<ArchiveDetail> insertBatchList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(fileMap)) {
                try {
                    long start = System.currentTimeMillis();
                    try {
                        for (Map.Entry<String, ScanningFile> map : fileMap.entrySet()) {
                            //获取真实文件名
                            String fileName = map.getKey();
                            //获取缓存对象
                            ScanningFile obj = map.getValue();
                            String number = getNumber(obj.getNumber());
                            String applyId = masterId + "~" + (number != null ? number : "");
                            File pdfFile = FileUtils.createFile("pdfs", obj.getInpNo(), obj.getVisitId(), applyId);
                            FileUtils.generatePdfFile(obj.getByteList(), pdfFile.getAbsolutePath());
                            //合成pdf
                            String pdfPath = pdfFile.getAbsolutePath();
                            //获取assortId
                            String assortId = getAssortId(obj.getAssortId());
                            ArchiveDetail archiveDetail = new ArchiveDetail(masterId, new Date(), assortId, "扫描系统", applyId, pdfPath, Integer.valueOf(number), fileName);
                            insertBatchList.add(archiveDetail);
                        }
                        long end = System.currentTimeMillis();
                        logger.error("图片合成pdf:FBIHID=" + scanningFile.getInpNo() + "&FBINCU=" + scanningFile.getVisitId() + "所用时间:" + (end - start) / 1000.00 + "s");
                        if (!CollectionUtils.isEmpty(insertBatchList)) {
                            //批量添加进detail表
                            archiveDetailRepository.saveAll(insertBatchList);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        e.printStackTrace(new PrintStream(baos));
                        String exception = baos.toString();
                        logger.error("合成pdf出错了：" + exception);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("合成pdf或插入detail表出错了:FBIHID=" + scanningFile.getInpNo() + "&FBINCU=" + scanningFile.getVisitId());
                    throw new RuntimeException("合成pdf或插入detail表出错了:FBIHID=" + scanningFile.getInpNo() + "&FBINCU=" + scanningFile.getVisitId());
                }
            }
            if (!CollectionUtils.isEmpty(ids)) {
                //批量更新scanningFile表
                String status = "1";
                if (StringUtils.isNotBlank(remark)) {
                    status = "2";
                } else {
                    remark = LocalDateTime.now().toString();
                }
                //更新scanningFile表
                scanningFileRepository.updateBatch(remark, status, ids);
            }
        }
    }

    /**
     * 获取applyId
     * @param number
     * @return
     */
    private String getNumber(String number){
        // Integer number = 1;
        //37006704-10-47-1.CDP 截成  10-47-1.CDP
        number = number.substring(number.indexOf("-")+1,number.length());
        //10-47-1.CDP 截成  47-1.CDP
        number = number.substring(number.indexOf("-")+1,number.length());
        //47-1.CDP 截成47
        number = number.substring(0,number.indexOf("-"));
        return number;
    }

    /**
     * 获取assortId
     * @param thirdAssortId 第三方分段标识
     * @return
     */
    private String getAssortId(String thirdAssortId) {
        String assortId = "1";
        switch (thirdAssortId){
            case "1": // 病案首页
                assortId = "3";
                break;
            case "2":  //出院（或死亡）记录（小结）
                assortId = "113";
                break;
            case "3": //入院记录
                assortId = "9";
                break;
            case "4": //病程记录
                assortId = "11";
                break;
            case "5": //死亡病例讨论
                assortId = "14";
                break;
            case "6": //特殊病情及治疗记录
                assortId = "20";
                break;
            case "7": //会诊记录单
                assortId = "15";
                break;
            case "8": //病重(病危)护理记录
                assortId = "121";
                break;
            case "9": //知情同意书
                assortId = "20";
                break;
            case "10": //辅助检查报告单
                assortId = "110";
                break;
            case "11": //医嘱单
                assortId = "25";
                break;
            case "12": //体温单
                assortId = "5";
                break;
            case "13": //护理记录
                assortId = "2";
                break;
            case "14": //死亡患者门诊病历
                assortId = "18";
                break;
            case "15": //其他资料
                assortId = "18";
                break;
        }
        return assortId;
    }
/*
    public String handlePdfFile(ScanningFile scanningFile) throws Exception{
        //处理ScanningFile
        // 判断病案首页数据是否存在

        LocalDateTime now1 = LocalDateTime.now();//删掉
        CommonTable commonTable = commonTableRepository.findByInpNoAndVisitId(scanningFile.getInpNo(), scanningFile.getVisitId());
        LocalDateTime end1 = LocalDateTime.now();//删掉
        logger.error("判断病案首页数据是否存在耗时:"+Duration.between(now1,end1).toMillis());//删掉

        if(commonTable == null){
            String masterId = scanningFile.getApplyId() != null ? scanningFile.getApplyId() : UUID.randomUUID().toString();
            commonTable = new CommonTable(masterId,scanningFile.getPatientId(),scanningFile.getAge(),scanningFile.getSex(),scanningFile.getVisitId(),scanningFile.getName(),
                    scanningFile.getAdmissDate(),scanningFile.getDisDate(),scanningFile.getDisDept(),scanningFile.getAttending(),scanningFile.getInpNo(),"扫描系统");
//            //保存公共表
            LocalDateTime now2 = LocalDateTime.now();//删掉
            commonTableRepository.save(commonTable);
            LocalDateTime end2 = LocalDateTime.now();//删掉
            logger.error("保存公共表耗时:"+Duration.between(now2,end2).toMillis());//删掉
            //保存公共表1
            LocalDateTime now3 = LocalDateTime.now();//删掉
            commonTable1Repository.save( new CommonTable1(commonTable.getMasterId(),scanningFile.getBirthday(),scanningFile.getIdCard(),scanningFile.getAdmissDept(),scanningFile.getAdmissDoctor()));
            LocalDateTime end3 = LocalDateTime.now();//删掉
            logger.error("保存公共表1耗时:"+Duration.between(now3,end3).toMillis());//删掉
        }

        LocalDateTime now4 = LocalDateTime.now();//删掉
        Object[] objects = WebServiceUtils.connect(scanningFile.getPath() + "\\" + scanningFile.getFileName());
        LocalDateTime end4 = LocalDateTime.now();//删掉
        logger.error("WebServiceUtils.connect耗时:"+Duration.between(now4,end4).toMillis());//删掉
        //Object[] objects = WebServiceUtil.urlConnectionUtil("http://10.6.0.224/cdms/cdmsservice.asmx?wsdl",scanningFile.getPath() + "\\" + scanningFile.getFileName());
        //使用HttpURLConnection方式连接
//        String s = WebServiceUtil.urlConnectionUtil("http://10.6.0.224/cdms/cdmsservice.asmx?wsdl", scanningFile.getPath() + "\\" + scanningFile.getFileName());


        */
/*if(!"".equals(s)){
            int w=9;
        }
        //s转Object[]
        String[] strArr = s.split(",");//注意分隔符是需要转译
        Object[] objects = new Object[strArr.length];
        for(int i=0;i<strArr.length;i++) {
            objects[i] = strArr[i];
        }*//*

        if (objects == null) {
            return "下载图片出错了。。。";
        }

        String number = scanningFile.getNumber();
        // Integer number = 1;
        //37006704-10-47-1.CDP 截成  10-47-1.CDP
        number = number.substring(number.indexOf("-")+1,number.length());
        //10-47-1.CDP 截成  47-1.CDP
        number = number.substring(number.indexOf("-")+1,number.length());
        //47-1.CDP 截成47
        number = number.substring(0,number.indexOf("-"));

//        byte[] bytes = (byte[]) objects[0];
        String applyId = commonTable.getMasterId() + "~" + (number != null ? number : "");
        // 给临时图片填充内容
        LocalDateTime now5 = LocalDateTime.now();//删掉
        File imageTempFile = FileUtils.createFile("images", scanningFile.getInpNo(), scanningFile.getVisitId(), applyId);
        LocalDateTime end5 = LocalDateTime.now();//删掉
        logger.error("FileUtils.createFile生成images耗时:"+Duration.between(now5,end5).toMillis());//删掉

        LocalDateTime now6 = LocalDateTime.now();//删掉
        File imageFile = FileUtils.getImageFileByByteArray(objects, imageTempFile);
        LocalDateTime end6 = LocalDateTime.now();//删掉
        logger.error("FileUtils.getImageFileByByteArray耗时:"+Duration.between(now6,end6).toMillis());//删掉
        if (imageFile == null) {
            return "填充临时图片出错了。。。";
        }

        LocalDateTime now7 = LocalDateTime.now();//删掉
        File pdfFile = FileUtils.createFile("pdfs", scanningFile.getInpNo(), scanningFile.getVisitId(), applyId);
        LocalDateTime end7 = LocalDateTime.now();//删掉
        logger.error("FileUtils.createFile生成pdfs耗时:"+Duration.between(now7,end7).toMillis());//删掉

        LocalDateTime now8 = LocalDateTime.now();//删掉
        String pdfPath = PdfUtils.imagesToPdf(imageFile, pdfFile);
        LocalDateTime end8 = LocalDateTime.now();//删掉
        logger.error("图片转pdf耗时:"+Duration.between(now8,end8).toMillis());//删掉
        //存入pdf地址
        if (pdfPath == null) {
            return "image转成pdf出错了。。。";
        }


//        // 如果存在 那就更新
//        ArchiveDetail archiveDetail = archiveDetailService.isExit(commonTable.getMasterId(), "1", "扫描系统", applyId);
//        if (archiveDetail == null) {
//            archiveDetail = new ArchiveDetail(commonTable.getMasterId(), new Date(), "1", "扫描系统", applyId, pdfPath,Integer.valueOf(number));
//            archiveDetailService.save(archiveDetail);
//        }
        String assortId = "1";
        switch (scanningFile.getAssortId()){
            case "1": // 病案首页
                assortId = "3";
                break;
            case "2":  //出院（或死亡）记录（小结）
                assortId = "113";
                break;
            case "3": //入院记录
                assortId = "9";
                break;
            case "4": //病程记录
                assortId = "11";
                break;
            case "5": //死亡病例讨论
                assortId = "14";
                break;
            case "6": //特殊病情及治疗记录
                assortId = "20";
                break;
            case "7": //会诊记录单
                assortId = "15";
                break;
            case "8": //病重(病危)护理记录
                assortId = "121";
                break;
            case "9": //知情同意书
                assortId = "20";
                break;
            case "10": //辅助检查报告单
                assortId = "110";
                break;
            case "11": //医嘱单
                assortId = "25";
                break;
            case "12": //体温单
                assortId = "5";
                break;
            case "13": //护理记录
                assortId = "2";
                break;
            case "14": //死亡患者门诊病历
                assortId = "18";
                break;
            case "15": //其他资料
                assortId = "18";
                break;
        }
        LocalDateTime now9 = LocalDateTime.now();//删掉
        archiveDetailService.save(new ArchiveDetail(commonTable.getMasterId(), new Date(), assortId, "扫描系统", applyId, pdfPath,Integer.valueOf(number)));
        LocalDateTime end9 = LocalDateTime.now();//删掉
        logger.error("保存耗时:"+Duration.between(now9,end9).toMillis());//删掉
        return null;
    }
*/

    public String handlePdfFile1(MessageDto messageDto) throws Exception{
        String pdfPath = "";
        ArchiveMaster archiveMaster = archiveMasterService.findByInpNoAndVisitIdAndIsValid(messageDto.getInpNo(),messageDto.getVisitId());
        if(archiveMaster == null){
            return "没有患者信息";
        }
        File imageFile = FileUtils.createFile("images", messageDto.getInpNo(), messageDto.getVisitId(),"");
        if(DownloadUtils.downloadImageFile("","", imageFile) == null){
            return "下载图像出错";
        }
        File pdfFile = FileUtils.createFile("pdfs", messageDto.getInpNo(), messageDto.getVisitId(), messageDto.getApplyId());
        //存入pdf地址
        pdfPath = PdfUtils.imagesToPdf(imageFile, pdfFile);
        if (pdfPath == null) {
            return "image转成pdf出错了。。。";
        }
        ArchiveDetail archiveDetail = new ArchiveDetail(archiveMaster.getId(), new Date(), messageDto.getType(), "扫描系统", messageDto.getApplyId(), pdfPath,Integer.valueOf(messageDto.getPageNum()));
        archiveDetail.setTitle(messageDto.getApplyId());
        archiveDetailService.save(archiveDetail);
        if(archiveDetail.getId() != null){
            return null;
        }
        return "出错了";
    }

    public static String getReturnResult(boolean resultCode,String remark) throws Exception{
        OutPara outPara = new OutPara();
        if (resultCode) {
            outPara.setRESULT_CODE(true);
            outPara.setRESULT_CONTENT("成功");
        } else {
            outPara.setRESULT_CODE(false);
            outPara.setRESULT_CONTENT(remark);
        }
        return XMLUtils.generateXmlStr(outPara);
    }


}
